Skip to content

Commit 4fb2338

Browse files
authored
refactor: remove legacy style engine from style panel (#4338)
Migrated style panel to new style engine for sections rendering and switched position section as well. Test following cases - flex child section when parent has flex - list style section for list or list item - inset control when position value is relative, absolute, fixed or sticky - inset control when position is inherited form relative etc - zindex control when parent is flex or grid
1 parent 57fc3b9 commit 4fb2338

File tree

9 files changed

+67
-129
lines changed

9 files changed

+67
-129
lines changed

apps/builder/app/builder/features/style-panel/parent-style.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from "./sections";
2-
export type { SectionProps } from "./shared/section";

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

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import type { StyleProperty } from "@webstudio-is/css-engine";
2-
import type { SectionProps } from "../shared/section";
3-
import { StyleSection } from "../../shared/style-section";
1+
import { toValue, type StyleProperty } from "@webstudio-is/css-engine";
42
import { Grid, theme } from "@webstudio-is/design-system";
3+
import { propertyDescriptions } from "@webstudio-is/css-data";
4+
import { StyleSection } from "../../shared/style-section";
55
import { SelectControl, TextControl } from "../../controls";
66
import { styleConfigByName } from "../../shared/configs";
7-
import { InsetControl } from "./inset-control";
8-
import { useParentStyle } from "../../parent-style";
97
import { PropertyLabel } from "../../property-label";
10-
import { propertyDescriptions } from "@webstudio-is/css-data";
8+
import {
9+
useComputedStyleDecl,
10+
useParentComputedStyleDecl,
11+
} from "../../shared/model";
12+
import { InsetControl } from "./inset-control";
1113

1214
export const properties = [
1315
"position",
@@ -18,52 +20,37 @@ export const properties = [
1820
"left",
1921
] satisfies Array<StyleProperty>;
2022

21-
const positionControlVisibleProperties = [
22-
"relative",
23-
"absolute",
24-
"fixed",
25-
"sticky",
26-
] as const;
27-
28-
const zIndexParents = ["flex", "grid", "inline-flex", "inline-grid"] as const;
29-
30-
export const Section = ({ currentStyle }: SectionProps) => {
31-
const parentStyle = useParentStyle();
32-
33-
const positionValue = currentStyle.position?.value;
34-
23+
export const Section = () => {
24+
const position = useComputedStyleDecl("position");
25+
const positionValue = toValue(position.computedValue);
3526
const showInsetControl =
36-
positionValue?.type === "keyword" &&
37-
positionControlVisibleProperties.includes(positionValue.value as never);
27+
positionValue === "relative" ||
28+
positionValue === "absolute" ||
29+
positionValue === "fixed" ||
30+
positionValue === "sticky";
3831

32+
const parentDisplay = useParentComputedStyleDecl("display");
33+
const parentDisplayValue = toValue(parentDisplay.computedValue);
3934
const showZindexControl =
4035
showInsetControl ||
41-
(parentStyle?.display?.value.type === "keyword" &&
42-
zIndexParents.includes(parentStyle?.display?.value.value as never));
43-
44-
const { items: unfilteredPositionItems } = styleConfigByName("position");
45-
46-
// Filter out "inherit" as we have no a good way to handle it
47-
// @todo remove after https://github.com/webstudio-is/webstudio/issues/1536
48-
const positionItems = unfilteredPositionItems.filter(
49-
(item) => item.name !== "inherit"
50-
);
36+
parentDisplayValue === "flex" ||
37+
parentDisplayValue === "grid" ||
38+
parentDisplayValue === "inline-flex" ||
39+
parentDisplayValue === "inline-grid";
5140

5241
return (
5342
<StyleSection label="Position" properties={properties}>
5443
<Grid gap={2}>
55-
<Grid
56-
gap={2}
57-
css={{
58-
gridTemplateColumns: `1fr ${theme.spacing[23]}`,
59-
}}
60-
>
44+
<Grid gap={2} css={{ gridTemplateColumns: `1fr ${theme.spacing[23]}` }}>
6145
<PropertyLabel
6246
label="Position"
6347
description={propertyDescriptions.position}
6448
properties={["position"]}
6549
/>
66-
<SelectControl property="position" items={positionItems} />
50+
<SelectControl
51+
property="position"
52+
items={styleConfigByName("position").items}
53+
/>
6754
{showZindexControl && showInsetControl === false && (
6855
<>
6956
<PropertyLabel
@@ -75,7 +62,6 @@ export const Section = ({ currentStyle }: SectionProps) => {
7562
</>
7663
)}
7764
</Grid>
78-
7965
{showInsetControl && (
8066
<Grid gap={3} columns={2}>
8167
<InsetControl />

apps/builder/app/builder/features/style-panel/sections/sections.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ import * as textShadows from "./text-shadows/text-shadows";
1717
import * as backdropFilter from "./backdrop-filter/backdrop-filter";
1818
import * as transforms from "./transforms/transforms";
1919
import type { StyleProperty } from "@webstudio-is/css-engine";
20-
import type { SectionProps } from "./shared/section";
2120

2221
export const sections = new Map<
2322
string,
2423
{
2524
properties: StyleProperty[];
26-
Section: (props: SectionProps) => ReactNode;
25+
Section: () => ReactNode;
2726
}
2827
>([
2928
["layout", layout],

apps/builder/app/builder/features/style-panel/sections/shared/input-popover.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {
1111
CssValueInput,
1212
type IntermediateStyleValue,
1313
} from "../../shared/css-value-input";
14-
import type { StyleSource } from "../../shared/style-info";
1514
import { createBatchUpdate } from "../../shared/use-style-data";
1615
import { theme } from "@webstudio-is/design-system";
16+
import type { StyleValueSourceColor } from "~/shared/style-object-model";
1717
import { $availableUnitVariables } from "../../shared/model";
1818

1919
const slideUpAndFade = keyframes({
@@ -28,7 +28,7 @@ const Input = ({
2828
activeProperties,
2929
onClosePopover,
3030
}: {
31-
styleSource: StyleSource;
31+
styleSource: StyleValueSourceColor;
3232
property: StyleProperty;
3333
activeProperties: StyleProperty[];
3434
value: StyleValue;
@@ -119,7 +119,7 @@ export const InputPopover = ({
119119
isOpen,
120120
onClose,
121121
}: {
122-
styleSource: StyleSource;
122+
styleSource: StyleValueSourceColor;
123123
property: StyleProperty;
124124
activeProperties: StyleProperty[];
125125
value: StyleValue;

apps/builder/app/builder/features/style-panel/sections/shared/section.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import { useUnitSelect } from "./unit-select";
3939
import { parseIntermediateOrInvalidValue } from "./parse-intermediate-or-invalid-value";
4040
import { toValue } from "@webstudio-is/css-engine";
4141
import { useDebouncedCallback } from "use-debounce";
42-
import type { StyleSource } from "../style-info";
4342
import {
4443
declarationDescriptions,
4544
isValidDeclaration,
@@ -52,6 +51,7 @@ import {
5251
import { convertUnits } from "./convert-units";
5352
import { mergeRefs } from "@react-aria/utils";
5453
import { composeEventHandlers } from "~/shared/event-utils";
54+
import type { StyleValueSourceColor } from "~/shared/style-object-model";
5555
import { ColorThumb } from "../color-thumb";
5656

5757
// We need to enable scrub on properties that can have numeric value.
@@ -255,7 +255,7 @@ type CssValueInputProps = Pick<
255255
| "prefix"
256256
| "inputRef"
257257
> & {
258-
styleSource: StyleSource;
258+
styleSource: StyleValueSourceColor;
259259
property: StyleProperty;
260260
value: StyleValue | undefined;
261261
intermediateValue: CssValueInputValue | undefined;

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,24 @@ export const useComputedStyleDecl = (property: StyleProperty) => {
280280
return useStore($store);
281281
};
282282

283+
export const useParentComputedStyleDecl = (property: StyleProperty) => {
284+
const $store = useMemo(
285+
() =>
286+
computed(
287+
[$model, $instanceAndRootSelector],
288+
(model, instanceSelector) => {
289+
return getComputedStyleDecl({
290+
model,
291+
instanceSelector: instanceSelector?.slice(1),
292+
property,
293+
});
294+
}
295+
),
296+
[property]
297+
);
298+
return useStore($store);
299+
};
300+
283301
export const useComputedStyles = (properties: StyleProperty[]) => {
284302
// cache each computed style store
285303
const cachedStores = useRef(

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

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,15 @@ import {
88
} from "@webstudio-is/design-system";
99
import { useStore } from "@nanostores/react";
1010
import { computed } from "nanostores";
11-
import type { HtmlTags } from "html-tags";
12-
import {
13-
setProperty,
14-
deleteProperty,
15-
createBatchUpdate,
16-
} from "./shared/use-style-data";
1711
import { StyleSourcesSection } from "./style-source-section";
1812
import { $selectedInstanceRenderState } from "~/shared/nano-states";
1913
import {
2014
$selectedInstanceIntanceToTag,
2115
$selectedInstanceSelector,
2216
} from "~/shared/nano-states";
2317
import { sections } from "./sections";
24-
import { useParentStyle } from "./parent-style";
25-
import { useStyleInfo, type StyleInfo } from "./shared/style-info";
2618
import { toValue } from "@webstudio-is/css-engine";
19+
import { useParentComputedStyleDecl } from "./shared/model";
2720

2821
const $selectedInstanceTag = computed(
2922
[$selectedInstanceSelector, $selectedInstanceIntanceToTag],
@@ -35,26 +28,11 @@ const $selectedInstanceTag = computed(
3528
}
3629
);
3730

38-
const shouldRenderCategory = (
39-
category: string,
40-
parentStyle: StyleInfo,
41-
tag: undefined | HtmlTags
42-
) => {
43-
switch (category) {
44-
case "flexChild":
45-
return toValue(parentStyle.display?.value).includes("flex");
46-
case "listItem":
47-
return tag === "ul" || tag === "ol" || tag === "li";
48-
}
49-
return true;
50-
};
51-
5231
export const StylePanel = () => {
53-
const currentStyle = useStyleInfo();
54-
5532
const selectedInstanceRenderState = useStore($selectedInstanceRenderState);
56-
const selectedInstanceTag = useStore($selectedInstanceTag);
57-
const parentStyle = useParentStyle();
33+
const tag = useStore($selectedInstanceTag);
34+
const display = useParentComputedStyleDecl("display");
35+
const displayValue = toValue(display.computedValue);
5836

5937
// If selected instance is not rendered on the canvas,
6038
// style panel will not work, because it needs the element in DOM in order to work.
@@ -72,17 +50,20 @@ export const StylePanel = () => {
7250
const all = [];
7351

7452
for (const [category, { Section }] of sections.entries()) {
75-
if (shouldRenderCategory(category, parentStyle, selectedInstanceTag)) {
76-
all.push(
77-
<Section
78-
key={category}
79-
setProperty={setProperty}
80-
deleteProperty={deleteProperty}
81-
createBatchUpdate={createBatchUpdate}
82-
currentStyle={currentStyle}
83-
/>
84-
);
53+
// show flex child UI only when parent is flex or inline-flex
54+
if (category === "flexChild" && displayValue.includes("flex") === false) {
55+
continue;
56+
}
57+
// allow customizing list item type only for list and list item
58+
if (
59+
category === "listItem" &&
60+
tag !== "ul" &&
61+
tag !== "ol" &&
62+
tag !== "li"
63+
) {
64+
continue;
8565
}
66+
all.push(<Section key={category} />);
8667
}
8768

8869
return (

0 commit comments

Comments
 (0)