Skip to content

Commit 3c8ac56

Browse files
authored
refactor: migrate properties data to hyphen case (#4970)
properties data are now more type safe and can accept any CssProperty name though in case of custom properties (--string) will return undefined. This also removes a lot of `keyof typeof properties` castings.
1 parent fbe9eed commit 3c8ac56

File tree

21 files changed

+444
-400
lines changed

21 files changed

+444
-400
lines changed

apps/builder/app/builder/features/style-panel/property-label.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
type CssProperty,
99
type StyleProperty,
1010
} from "@webstudio-is/css-engine";
11+
import { propertiesData } from "@webstudio-is/css-data";
1112
import {
1213
Button,
1314
Flex,
@@ -36,7 +37,6 @@ import { useComputedStyles } from "./shared/model";
3637
import { StyleSourceBadge } from "./style-source";
3738
import { createBatchUpdate } from "./shared/use-style-data";
3839
import { $virtualInstances } from "~/shared/awareness";
39-
import { styleConfigByName } from "./shared/configs";
4040

4141
const $isAltPressed = atom(false);
4242
if (typeof window !== "undefined") {
@@ -251,7 +251,6 @@ export const PropertyLabel = ({
251251
}
252252
batch.publish();
253253
};
254-
const styleConfig = styleConfigByName(properties[0]);
255254

256255
return (
257256
<Flex align="center">
@@ -281,7 +280,7 @@ export const PropertyLabel = ({
281280
resetProperty();
282281
setIsOpen(false);
283282
}}
284-
link={styleConfig?.mdnUrl}
283+
link={propertiesData[hyphenateProperty(properties[0])]?.mdnUrl}
285284
/>
286285
}
287286
>
@@ -314,7 +313,6 @@ export const PropertySectionLabel = ({
314313
}
315314
batch.publish();
316315
};
317-
const styleConfig = styleConfigByName(properties[0]);
318316

319317
return (
320318
<Flex align="center">
@@ -342,7 +340,7 @@ export const PropertySectionLabel = ({
342340
resetProperty();
343341
setIsOpen(false);
344342
}}
345-
link={styleConfig?.mdnUrl}
343+
link={propertiesData[hyphenateProperty(properties[0])]?.mdnUrl}
346344
/>
347345
}
348346
>
@@ -444,7 +442,6 @@ export const PropertyValueTooltip = ({
444442
}
445443
batch.publish();
446444
};
447-
const styleConfig = styleConfigByName(properties[0]);
448445

449446
return (
450447
<Tooltip
@@ -480,7 +477,7 @@ export const PropertyValueTooltip = ({
480477
resetProperty();
481478
setIsOpen(false);
482479
}}
483-
link={styleConfig?.mdnUrl}
480+
link={propertiesData[hyphenateProperty(properties[0])]?.mdnUrl}
484481
/>
485482
}
486483
>

apps/builder/app/builder/features/style-panel/sections/transitions/transition-content.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
Grid,
1818
} from "@webstudio-is/design-system";
1919
import { InfoCircleIcon } from "@webstudio-is/icons";
20-
import { properties, propertyDescriptions } from "@webstudio-is/css-data";
20+
import { propertiesData, propertyDescriptions } from "@webstudio-is/css-data";
2121
import { type IntermediateStyleValue } from "../../shared/css-value-input";
2222
import { CssValueInputContainer } from "../../shared/css-value-input";
2323
import { parseCssFragment } from "../../shared/css-fragment";
@@ -128,7 +128,7 @@ export const TransitionContent = ({ index }: { index: number }) => {
128128
properties={["transitionProperty"]}
129129
/>
130130
<TransitionProperty
131-
value={property ?? properties.transitionProperty.initial}
131+
value={property ?? propertiesData["transition-property"].initial}
132132
onChange={(value) => {
133133
updateIntermediateValue({ property: value });
134134
setRepeatedStyleItem(transitionProperty, index, value);
@@ -144,7 +144,7 @@ export const TransitionContent = ({ index }: { index: number }) => {
144144
property="transitionDuration"
145145
styleSource="local"
146146
getOptions={() => $availableUnitVariables.get()}
147-
value={duration ?? properties.transitionDuration.initial}
147+
value={duration ?? propertiesData["transition-duration"].initial}
148148
deleteProperty={() => {}}
149149
setValue={(value, options) => {
150150
if (value === undefined) {
@@ -169,7 +169,7 @@ export const TransitionContent = ({ index }: { index: number }) => {
169169
property="transitionDelay"
170170
styleSource="local"
171171
getOptions={() => $availableUnitVariables.get()}
172-
value={delay ?? properties.transitionDelay.initial}
172+
value={delay ?? propertiesData["transition-delay"].initial}
173173
deleteProperty={() => {}}
174174
setValue={(value, options) => {
175175
if (value === undefined) {
@@ -203,7 +203,10 @@ export const TransitionContent = ({ index }: { index: number }) => {
203203
{ type: "keyword", value: "step-end" },
204204
...$availableVariables.get(),
205205
]}
206-
value={timingFunction ?? properties.transitionTimingFunction.initial}
206+
value={
207+
timingFunction ??
208+
propertiesData["transition-timing-function"].initial
209+
}
207210
deleteProperty={() => {}}
208211
setValue={(value, options) => {
209212
if (value === undefined) {

apps/builder/app/builder/features/style-panel/sections/transitions/transitions.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import {
55
SectionTitleButton,
66
Tooltip,
77
} from "@webstudio-is/design-system";
8-
import { properties } from "@webstudio-is/css-data";
8+
import { propertiesData } from "@webstudio-is/css-data";
99
import {
10+
hyphenateProperty,
1011
toValue,
12+
type CssProperty,
1113
type LayerValueItem,
12-
type StyleProperty,
1314
} from "@webstudio-is/css-engine";
1415
import {
1516
CollapsibleSectionRoot,
@@ -30,12 +31,12 @@ import { TransitionContent } from "./transition-content";
3031
import { parseCssFragment } from "../../shared/css-fragment";
3132

3233
const transitionLongHandProperties = [
33-
"transitionProperty",
34-
"transitionTimingFunction",
35-
"transitionDelay",
36-
"transitionDuration",
37-
"transitionBehavior",
38-
] as const satisfies StyleProperty[];
34+
"transition-property",
35+
"transition-timing-function",
36+
"transition-delay",
37+
"transition-duration",
38+
"transition-behavior",
39+
] as const satisfies CssProperty[];
3940

4041
export { transitionLongHandProperties as properties };
4142

@@ -47,7 +48,7 @@ const getTransitionLayers = (
4748
) => {
4849
const transitionPropertyValue = styles[0].cascadedValue;
4950
const currentPropertyValue = styles.find(
50-
(styleDecl) => styleDecl.property === property
51+
(styleDecl) => hyphenateProperty(styleDecl.property) === property
5152
)?.cascadedValue;
5253
const transitionPropertiesCount =
5354
transitionPropertyValue.type === "layers"
@@ -56,7 +57,7 @@ const getTransitionLayers = (
5657
const definedLayers: LayerValueItem[] =
5758
currentPropertyValue?.type === "layers"
5859
? currentPropertyValue.value
59-
: [properties[property].initial];
60+
: [propertiesData[property].initial as LayerValueItem];
6061
return repeatUntil(definedLayers, transitionPropertiesCount);
6162
};
6263

@@ -68,19 +69,19 @@ const getLayerLabel = ({
6869
index: number;
6970
}) => {
7071
// show label without hidden replacement
71-
const propertyLayer = getTransitionLayers(styles, "transitionProperty")[
72+
const propertyLayer = getTransitionLayers(styles, "transition-property")[
7273
index
7374
];
7475
const property = humanizeString(toValue({ ...propertyLayer, hidden: false }));
7576
const duration = toValue(
76-
getTransitionLayers(styles, "transitionDuration")[index]
77+
getTransitionLayers(styles, "transition-duration")[index]
7778
);
7879
const timingFunctionLayer = getTransitionLayers(
7980
styles,
80-
"transitionTimingFunction"
81+
"transition-timing-function"
8182
)[index];
8283
const timingFunction = toValue({ ...timingFunctionLayer, hidden: false });
83-
const delay = toValue(getTransitionLayers(styles, "transitionDelay")[index]);
84+
const delay = toValue(getTransitionLayers(styles, "transition-delay")[index]);
8485
return `${property}: ${duration} ${timingFunction} ${delay}`;
8586
};
8687

apps/builder/app/builder/features/style-panel/shared/configs.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import type { CssProperty, StyleProperty } from "@webstudio-is/css-engine";
2-
import {
3-
camelCaseProperty,
4-
keywordValues,
5-
properties,
6-
} from "@webstudio-is/css-data";
2+
import { camelCaseProperty, keywordValues } from "@webstudio-is/css-data";
73
import { humanizeString } from "~/shared/string-utils";
84
import type * as Controls from "../controls";
95

106
type BaseStyleConfig = {
117
label: string;
128
property: StyleProperty;
13-
mdnUrl?: string;
149
};
1510

1611
export type Control = keyof typeof Controls;
@@ -59,15 +54,12 @@ export const styleConfigByName = (
5954

6055
const keywords = keywordValues[property] || [];
6156
const label = humanizeString(property);
62-
// property data does not exist for css custom properties
63-
const propertyData = properties[property] ?? {};
6457

6558
const result = {
6659
label,
6760
property,
6861
control: getControl(property),
6962
items: keywords.map((keyword) => ({ label: keyword, name: keyword })),
70-
...("mdnUrl" in propertyData && { mdnUrl: propertyData.mdnUrl }),
7163
};
7264

7365
styleConfigCache.set(property, result);

apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ import {
4040
} from "react";
4141
import { useUnitSelect, type UnitOption } from "./unit-select";
4242
import { parseIntermediateOrInvalidValue } from "./parse-intermediate-or-invalid-value";
43-
import { toValue } from "@webstudio-is/css-engine";
43+
import { hyphenateProperty, toValue } from "@webstudio-is/css-engine";
4444
import {
4545
camelCaseProperty,
4646
declarationDescriptions,
4747
isValidDeclaration,
48-
properties,
48+
propertiesData,
4949
} from "@webstudio-is/css-data";
5050
import {
5151
$selectedInstanceBrowserStyle,
@@ -66,7 +66,7 @@ import { useEffectEvent } from "~/shared/hook-utils/effect-event";
6666
// We need to enable scrub on properties that can have numeric value.
6767
const canBeNumber = (property: StyleProperty, value: CssValueInputValue) => {
6868
const unitGroups =
69-
properties[property as keyof typeof properties]?.unitGroups ?? [];
69+
propertiesData[hyphenateProperty(property)]?.unitGroups ?? [];
7070
// allow scrubbing css variables with unit value
7171
return unitGroups.length !== 0 || value.type === "unit";
7272
};
@@ -610,7 +610,7 @@ export const CssValueInput = ({
610610

611611
const [isUnitsOpen, unitSelectElement] = useUnitSelect({
612612
options: unitOptions,
613-
property,
613+
property: hyphenateProperty(multiCaseProperty),
614614
value,
615615
onChange: (unitOrKeyword) => {
616616
if (unitOrKeyword.type === "keyword") {

apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import type {
2-
StyleProperty,
3-
StyleValue,
4-
InvalidValue,
5-
Unit,
1+
import {
2+
type StyleProperty,
3+
type StyleValue,
4+
type InvalidValue,
5+
type Unit,
6+
hyphenateProperty,
67
} from "@webstudio-is/css-engine";
78
import {
89
units,
910
parseCssValue,
1011
cssTryParseValue,
11-
properties,
12+
propertiesData,
1213
} from "@webstudio-is/css-data";
1314
import type { IntermediateStyleValue } from "./css-value-input";
1415
import { evaluateMath } from "./evaluate-math";
@@ -18,7 +19,7 @@ const unitsList = Object.values(units).flat();
1819

1920
const getDefaultUnit = (property: StyleProperty): Unit => {
2021
const unitGroups =
21-
properties[property as keyof typeof properties]?.unitGroups ?? [];
22+
propertiesData[hyphenateProperty(property)]?.unitGroups ?? [];
2223

2324
for (const unitGroup of unitGroups) {
2425
if (unitGroup === "number") {

apps/builder/app/builder/features/style-panel/shared/css-value-input/unit-select-options.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import type { CssValueInputValue } from "./css-value-input";
2-
import { properties, units, isValidDeclaration } from "@webstudio-is/css-data";
2+
import {
3+
propertiesData,
4+
units,
5+
isValidDeclaration,
6+
} from "@webstudio-is/css-data";
37
import type { UnitOption } from "./unit-select";
8+
import type { CssProperty } from "@webstudio-is/css-engine";
49

510
// To make sorting stable
611
const preferedSorting = [
@@ -37,7 +42,7 @@ const initialLengthUnits = [
3742
] as const;
3843

3944
export const buildOptions = (
40-
property: string,
45+
property: CssProperty,
4146
value: CssValueInputValue,
4247
nestedSelectButtonUnitless: string
4348
) => {
@@ -50,8 +55,7 @@ export const buildOptions = (
5055

5156
// show at least current unit when no property meta is available
5257
// for example in custom properties
53-
const unitGroups =
54-
properties[property as keyof typeof properties]?.unitGroups ?? [];
58+
const unitGroups = propertiesData[property]?.unitGroups ?? [];
5559

5660
for (const unitGroup of unitGroups) {
5761
if (unitGroup === "number") {

apps/builder/app/builder/features/style-panel/shared/css-value-input/unit-select.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState, useMemo, type JSX } from "react";
22
import * as SelectPrimitive from "@radix-ui/react-select";
3-
import type { Unit } from "@webstudio-is/css-engine";
3+
import type { CssProperty, Unit } from "@webstudio-is/css-engine";
44
import {
55
SelectScrollUpButton,
66
SelectScrollDownButton,
@@ -23,7 +23,7 @@ export type UnitOption =
2323
| { id: string; label: string; type: "keyword" };
2424

2525
type UseUnitSelectType = {
26-
property: string;
26+
property: CssProperty;
2727
value: CssValueInputValue;
2828
onChange: (
2929
value: { type: "unit"; value: Unit } | { type: "keyword"; value: string }

apps/builder/app/builder/features/style-panel/shared/model.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { useMemo, useRef } from "react";
22
import type { HtmlTags } from "html-tags";
33
import { computed, type ReadableAtom } from "nanostores";
44
import { useStore } from "@nanostores/react";
5-
import { camelCaseProperty, properties } from "@webstudio-is/css-data";
5+
import { camelCaseProperty, propertiesData } from "@webstudio-is/css-data";
66
import {
77
compareMedia,
8+
hyphenateProperty,
89
toVarFallback,
910
type CssProperty,
1011
type StyleProperty,
@@ -181,7 +182,7 @@ export const getDefinedStyles = ({
181182
instanceStyles.add(styleDecl);
182183
}
183184
const inherited =
184-
properties[styleDecl.property as keyof typeof properties]?.inherited ??
185+
propertiesData[hyphenateProperty(styleDecl.property)]?.inherited ??
185186
// custom properties are always inherited
186187
true;
187188
if (

0 commit comments

Comments
 (0)