mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-07 12:33:36 +09:00
render font weights we have defined
This commit is contained in:
1 parent
031c823695
commit
504fc976b2
6 files changed
+118
-37
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { Select } from "@webstudio-is/design-system";
|
||||
import { useMemo } from "react";
|
||||
import { getFinalValue } from "../../shared/get-final-value";
|
||||
import type { ControlProps } from "../../style-sections";
|
||||
|
||||
@@ -15,17 +16,29 @@ export const SelectControl = ({
|
||||
property: styleConfig.property,
|
||||
});
|
||||
|
||||
const [options, selectedOption] = useMemo(() => {
|
||||
const item = styleConfig.items.find((item) => item.name == value?.value);
|
||||
const options = styleConfig.items.map((item) => item.label);
|
||||
return [options, item?.label];
|
||||
}, [value?.value, styleConfig.items]);
|
||||
|
||||
if (value === undefined) return null;
|
||||
|
||||
const setValue = setProperty(styleConfig.property);
|
||||
|
||||
return (
|
||||
<Select
|
||||
options={styleConfig.items.map(({ label }) => label)}
|
||||
value={String(value.value)}
|
||||
onChange={setValue}
|
||||
options={options}
|
||||
value={selectedOption}
|
||||
onChange={(option) => {
|
||||
const item = styleConfig.items.find((item) => item.label == option);
|
||||
if (item) {
|
||||
setValue(item.name);
|
||||
}
|
||||
}}
|
||||
ghost
|
||||
css={{
|
||||
// @todo this shouldn't be in design system by default
|
||||
gap: "calc($sizes$1 / 2)",
|
||||
paddingLeft: "calc($sizes$4 / 2)",
|
||||
height: "calc($sizes$5 + $sizes$1)",
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
ColumnGapIcon,
|
||||
} from "@webstudio-is/icons";
|
||||
import { isFeatureEnabled } from "~/shared/feature-flags";
|
||||
import { FontWeight, fontWeights } from "@webstudio-is/fonts";
|
||||
|
||||
type BaseStyleConfig = {
|
||||
label: string;
|
||||
@@ -61,6 +62,7 @@ export type StyleConfig = BaseStyleConfig & {
|
||||
};
|
||||
|
||||
type Property = keyof typeof keywordValues;
|
||||
type Keywords = typeof keywordValues[Property];
|
||||
|
||||
const getControl = (property: StyleProperty): Control => {
|
||||
if (property.toLocaleLowerCase().includes("color")) {
|
||||
@@ -74,11 +76,32 @@ const getControl = (property: StyleProperty): Control => {
|
||||
case "backgroundImage": {
|
||||
return isFeatureEnabled("assets") ? "ImageControl" : "TextControl";
|
||||
}
|
||||
case "fontWeight": {
|
||||
return "SelectControl";
|
||||
}
|
||||
}
|
||||
|
||||
return "TextControl";
|
||||
};
|
||||
|
||||
const fontWeightItems = (Object.keys(fontWeights) as Array<FontWeight>).map(
|
||||
(weight) => ({
|
||||
label: `${weight} - ${fontWeights[weight].label}`,
|
||||
name: weight,
|
||||
})
|
||||
);
|
||||
|
||||
const getItems = (property: StyleProperty, keywords: Keywords) => {
|
||||
if (property === "fontWeight") {
|
||||
return fontWeightItems;
|
||||
}
|
||||
|
||||
return keywords.map((keyword) => ({
|
||||
label: keyword,
|
||||
name: keyword,
|
||||
}));
|
||||
};
|
||||
|
||||
const createStyleConfigs = () => {
|
||||
// We have same properties in different categories: alignSelf is in grid children and flex children
|
||||
// but this list has to contain only unique props
|
||||
@@ -99,10 +122,7 @@ const createStyleConfigs = () => {
|
||||
property,
|
||||
appliesTo: properties[property].appliesTo,
|
||||
control: getControl(property),
|
||||
items: keywords.map((keyword: string) => ({
|
||||
label: keyword,
|
||||
name: keyword,
|
||||
})),
|
||||
items: getItems(property, keywords),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,13 @@ const StyledTrigger = styled(SelectPrimitive.SelectTrigger, {
|
||||
},
|
||||
});
|
||||
|
||||
const StyledValue = styled("span", {
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
flexGrow: 0,
|
||||
});
|
||||
|
||||
const StyledIcon = styled(SelectPrimitive.Icon, {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
@@ -143,6 +150,7 @@ export type SelectProps<Option = SelectOption> = Omit<
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
placeholder?: string;
|
||||
getLabel?: (option: Option) => string | undefined;
|
||||
getValue?: (option: Option) => string | undefined;
|
||||
};
|
||||
|
||||
const SelectBase = (
|
||||
@@ -155,6 +163,7 @@ const SelectBase = (
|
||||
onOpenChange,
|
||||
open,
|
||||
getLabel = (option) => option,
|
||||
getValue = (option) => option,
|
||||
name,
|
||||
...props
|
||||
}: SelectProps,
|
||||
@@ -170,8 +179,8 @@ const SelectBase = (
|
||||
onOpenChange={onOpenChange}
|
||||
>
|
||||
<StyledTrigger ref={forwardedRef} {...props}>
|
||||
<SelectPrimitive.Value>
|
||||
{value ? getLabel(value) : placeholder}
|
||||
<SelectPrimitive.Value asChild>
|
||||
<StyledValue>{value ? getLabel(value) : placeholder}</StyledValue>
|
||||
</SelectPrimitive.Value>
|
||||
<StyledIcon>
|
||||
<ChevronDownIcon />
|
||||
@@ -184,7 +193,11 @@ const SelectBase = (
|
||||
</SelectScrollUpButton>
|
||||
<SelectViewport>
|
||||
{options.map((option) => (
|
||||
<SelectItem key={option} value={option} textValue={option}>
|
||||
<SelectItem
|
||||
key={getValue(option)}
|
||||
value={getValue(option) ?? ""}
|
||||
textValue={getLabel(option)}
|
||||
>
|
||||
{getLabel(option)}
|
||||
</SelectItem>
|
||||
))}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { FontFormat } from "./types";
|
||||
import fontkit from "fontkit";
|
||||
import { FontWeight, fontWeights } from "./font-weights";
|
||||
|
||||
// @todo sumbit this to definitely typed, they are not up to date
|
||||
declare module "fontkit" {
|
||||
@@ -12,26 +13,6 @@ declare module "fontkit" {
|
||||
export const styles = ["normal", "italic", "oblique"] as const;
|
||||
type Style = typeof styles[number];
|
||||
|
||||
const weights = {
|
||||
thin: 100,
|
||||
hairline: 100,
|
||||
"extra light": 200,
|
||||
"ultra light": 200,
|
||||
light: 300,
|
||||
normal: 400,
|
||||
medium: 500,
|
||||
"semi bold": 600,
|
||||
"demi bold": 600,
|
||||
bold: 700,
|
||||
"extra bold": 800,
|
||||
"ultra bold": 800,
|
||||
black: 900,
|
||||
heavy: 900,
|
||||
} as const;
|
||||
|
||||
type WeightKey = keyof typeof weights;
|
||||
type WeightValue = typeof weights[WeightKey];
|
||||
|
||||
export const parseSubfamily = (subfamily: string) => {
|
||||
const subfamilyLow = subfamily.toLowerCase();
|
||||
let style: Style = "normal";
|
||||
@@ -41,15 +22,16 @@ export const parseSubfamily = (subfamily: string) => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let weight: WeightValue = weights.normal;
|
||||
let possibleWeight: WeightKey;
|
||||
for (possibleWeight in weights) {
|
||||
if (subfamilyLow.includes(possibleWeight)) {
|
||||
weight = weights[possibleWeight];
|
||||
|
||||
let weight: FontWeight = "400";
|
||||
for (weight in fontWeights) {
|
||||
const { name } = fontWeights[weight];
|
||||
const { alt } = fontWeights[weight];
|
||||
if (subfamilyLow.includes(name) || subfamilyLow.includes(alt)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { style, weight };
|
||||
return { style, weight: Number(weight) };
|
||||
};
|
||||
|
||||
export const normalizeFamily = (family: string, subfamily: string) => {
|
||||
@@ -70,7 +52,7 @@ type FontData = {
|
||||
format: FontFormat;
|
||||
family: string;
|
||||
style: Style;
|
||||
weight: WeightValue;
|
||||
weight: number;
|
||||
};
|
||||
|
||||
export const getFontData = (data: Uint8Array): FontData => {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
export const fontWeights = {
|
||||
"100": {
|
||||
label: "Thin",
|
||||
name: "thin",
|
||||
alt: "hairline",
|
||||
},
|
||||
"200": {
|
||||
label: "Extra Light",
|
||||
name: "extra light",
|
||||
alt: "ultra light",
|
||||
},
|
||||
"300": {
|
||||
label: "Light",
|
||||
name: "light",
|
||||
alt: "light",
|
||||
},
|
||||
"400": {
|
||||
label: "Normal",
|
||||
name: "normal",
|
||||
alt: "normal",
|
||||
},
|
||||
"500": {
|
||||
label: "Medium",
|
||||
name: "medium",
|
||||
alt: "medium",
|
||||
},
|
||||
"600": {
|
||||
label: "Semi Bold",
|
||||
name: "semi bold",
|
||||
alt: "demi bold",
|
||||
},
|
||||
"700": {
|
||||
label: "Bold",
|
||||
name: "bold",
|
||||
alt: "bold",
|
||||
},
|
||||
"800": {
|
||||
label: "Extra Bold",
|
||||
name: "extra bold",
|
||||
alt: "ultra bold",
|
||||
},
|
||||
"900": {
|
||||
label: "Black",
|
||||
name: "black",
|
||||
alt: "heavy",
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type FontWeight = keyof typeof fontWeights;
|
||||
export type FontWeightKeyword =
|
||||
| typeof fontWeights[FontWeight]["name"]
|
||||
| typeof fontWeights[FontWeight]["alt"];
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./constants";
|
||||
export * from "./get-font-faces";
|
||||
export * from "./types";
|
||||
export * from "./font-weights";
|
||||
Reference in new issue
Block a user