Skip to content

Commit b14676b

Browse files
authored
refactor: simplify css value input sizes (#4997)
- removed non-unit values from browser styles - merged browser styles and unit sizes into single store; both objects used in cize conversion - use typed cssom to parse units instead of custom parser (sorry firefox)
1 parent 973d7d6 commit b14676b

File tree

7 files changed

+68
-135
lines changed

7 files changed

+68
-135
lines changed

apps/builder/app/builder/features/style-panel/shared/css-value-input/convert-units.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { Unit } from "@webstudio-is/css-engine";
2-
3-
const convertibleUnits = ["px", "ch", "vw", "vh", "em", "rem"] as const;
4-
5-
type ConvertibleUnit = (typeof convertibleUnits)[number];
6-
7-
export type UnitSizes = Record<ConvertibleUnit, number>;
2+
import {
3+
convertibleUnits,
4+
type ConvertibleUnit,
5+
type UnitSizes,
6+
} from "~/shared/nano-states";
87

98
const isConvertibleUnit = (unit: Unit): unit is ConvertibleUnit =>
109
convertibleUnits.includes(unit as ConvertibleUnit);

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

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ import {
4747
isValidDeclaration,
4848
propertiesData,
4949
} from "@webstudio-is/css-data";
50-
import {
51-
$selectedInstanceBrowserStyle,
52-
$selectedInstanceUnitSizes,
53-
} from "~/shared/nano-states";
50+
import { $selectedInstanceSizes } from "~/shared/nano-states";
5451
import { convertUnits } from "./convert-units";
5552
import { mergeRefs } from "@react-aria/utils";
5653
import { composeEventHandlers } from "~/shared/event-utils";
@@ -630,7 +627,7 @@ export const CssValueInput = ({
630627
return;
631628
}
632629

633-
const unitSizes = $selectedInstanceUnitSizes.get();
630+
const { unitSizes, propertySizes } = $selectedInstanceSizes.get();
634631

635632
// Value not edited by the user, we need to convert it to the new unit
636633
if (value.type === "unit") {
@@ -653,20 +650,10 @@ export const CssValueInput = ({
653650

654651
// value is a keyword or non numeric, try get browser style value and convert it
655652
if (value.type === "keyword" || value.type === "intermediate") {
656-
const browserStyle = $selectedInstanceBrowserStyle.get();
657-
const browserPropertyValue = browserStyle?.[property];
658-
const propertyValue =
659-
browserPropertyValue?.type === "unit"
660-
? browserPropertyValue.value
661-
: 0;
662-
const propertyUnit =
663-
browserPropertyValue?.type === "unit"
664-
? browserPropertyValue.unit
665-
: "number";
666-
653+
const styleValue = propertySizes[hyphenateProperty(property)];
667654
const convertedValue = convertUnits(unitSizes)(
668-
propertyValue,
669-
propertyUnit,
655+
styleValue?.value ?? 0,
656+
styleValue?.unit ?? "number",
670657
unit
671658
);
672659

apps/builder/app/canvas/features/webstudio-component/get-browser-style.ts

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

apps/builder/app/canvas/instance-selected.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import { shallowEqual } from "shallow-equal";
2+
import warnOnce from "warn-once";
13
import type { Instance } from "@webstudio-is/sdk";
4+
import type { CssProperty, UnitValue } from "@webstudio-is/css-engine";
5+
import { propertiesData } from "@webstudio-is/css-data";
26
import { selectorIdAttribute } from "@webstudio-is/react-sdk";
37
import { subscribeWindowResize } from "~/shared/dom-hooks";
48
import {
59
$isResizingCanvas,
6-
$selectedInstanceBrowserStyle,
7-
$selectedInstanceUnitSizes,
10+
$selectedInstanceSizes,
811
$selectedInstanceRenderState,
912
$stylesIndex,
1013
$instances,
@@ -13,6 +16,8 @@ import {
1316
$styles,
1417
$selectedInstanceStates,
1518
$styleSourceSelections,
19+
type UnitSizes,
20+
type PropertySizes,
1621
} from "~/shared/nano-states";
1722
import {
1823
getAllElementsBoundingBox,
@@ -23,15 +28,11 @@ import {
2328
} from "~/shared/dom-utils";
2429
import { subscribeScrollState } from "~/canvas/shared/scroll-state";
2530
import { $selectedInstanceOutline } from "~/shared/nano-states";
26-
import type { UnitSizes } from "~/builder/features/style-panel/shared/css-value-input/convert-units";
2731
import {
2832
hasCollapsedMutationRecord,
2933
setDataCollapsed,
3034
} from "~/canvas/collapsed";
31-
import { getBrowserStyle } from "./features/webstudio-component/get-browser-style";
3235
import type { InstanceSelector } from "~/shared/tree-utils";
33-
import { shallowEqual } from "shallow-equal";
34-
import warnOnce from "warn-once";
3536

3637
const setOutline = (instanceId: Instance["id"], elements: HTMLElement[]) => {
3738
$selectedInstanceOutline.set({
@@ -78,6 +79,30 @@ const calculateUnitSizes = (element: HTMLElement): UnitSizes => {
7879
};
7980
};
8081

82+
const calculatePropertySizes = (element: HTMLElement) => {
83+
const computedStyle = getComputedStyle(element);
84+
const propertySizes: PropertySizes = {};
85+
for (const property in propertiesData) {
86+
try {
87+
const propertyValue = computedStyle.getPropertyValue(property);
88+
const value = CSSStyleValue.parse(property, propertyValue);
89+
if (value instanceof CSSUnitValue) {
90+
propertySizes[property as CssProperty] = {
91+
type: "unit",
92+
// px | number | percent etc
93+
unit:
94+
value.unit === "percent" ? "%" : (value.unit as UnitValue["unit"]),
95+
value: value.value,
96+
};
97+
}
98+
} catch (error) {
99+
// failed with unknown property like -moz-osx-font-smoothing
100+
// also firefox does not support CSSStyleValue
101+
}
102+
}
103+
return propertySizes;
104+
};
105+
81106
const subscribeSelectedInstance = (
82107
selectedInstanceSelector: Readonly<InstanceSelector>,
83108
debounceEffect: (callback: () => void) => void
@@ -151,10 +176,9 @@ const subscribeSelectedInstance = (
151176

152177
const [element] = elements;
153178
// trigger style recomputing every time instance styles are changed
154-
$selectedInstanceBrowserStyle.set(getBrowserStyle(element));
155-
156179
const unitSizes = calculateUnitSizes(element);
157-
$selectedInstanceUnitSizes.set(unitSizes);
180+
const propertySizes = calculatePropertySizes(element);
181+
$selectedInstanceSizes.set({ unitSizes, propertySizes });
158182

159183
const availableStates = new Set<string>();
160184
const instanceStyleSourceIds = new Set(

apps/builder/app/shared/nano-states/misc.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Simplify } from "type-fest";
12
import { atom, computed, onSet } from "nanostores";
23
import { nanoid } from "nanoid";
34
import type { AuthPermit } from "@webstudio-is/trpc-interface/index.server";
@@ -15,16 +16,14 @@ import type {
1516
StyleSources,
1617
StyleSourceSelections,
1718
} from "@webstudio-is/sdk";
18-
import type { Style } from "@webstudio-is/css-engine";
19+
import type { CssProperty, UnitValue } from "@webstudio-is/css-engine";
1920
import type { Project } from "@webstudio-is/project";
2021
import type { MarketplaceProduct } from "@webstudio-is/project-build";
2122
import type { TokenPermissions } from "@webstudio-is/authorization-token";
23+
import type { AssetType } from "@webstudio-is/asset-uploader";
2224
import type { DragStartPayload } from "~/canvas/shared/use-drag-drop";
2325
import { type InstanceSelector } from "../tree-utils";
2426
import { $selectedInstanceSelector } from "./instances";
25-
import type { UnitSizes } from "~/builder/features/style-panel/shared/css-value-input/convert-units";
26-
import type { Simplify } from "type-fest";
27-
import type { AssetType } from "@webstudio-is/asset-uploader";
2827
import type { ChildrenOrientation } from "node_modules/@webstudio-is/design-system/src/components/primitives/dnd/geometry-utils";
2928
import { $selectedInstance } from "../awareness";
3029
import type { UserPlanFeatures } from "../db/user-plan-features.server";
@@ -161,16 +160,28 @@ export type UploadingFileData = Simplify<
161160

162161
export const $uploadingFilesDataStore = atom<UploadingFileData[]>([]);
163162

164-
export const $selectedInstanceBrowserStyle = atom<undefined | Style>();
163+
export const convertibleUnits = ["px", "ch", "vw", "vh", "em", "rem"] as const;
164+
165+
export type ConvertibleUnit = (typeof convertibleUnits)[number];
166+
167+
export type UnitSizes = Record<ConvertibleUnit, number>;
168+
169+
export type PropertySizes = Partial<Record<CssProperty, UnitValue>>;
165170

166171
// Init with some defaults to avoid undefined
167-
export const $selectedInstanceUnitSizes = atom<UnitSizes>({
168-
ch: 8,
169-
vw: 3.2,
170-
vh: 4.8,
171-
em: 16,
172-
rem: 16,
173-
px: 1,
172+
export const $selectedInstanceSizes = atom<{
173+
unitSizes: UnitSizes;
174+
propertySizes: PropertySizes;
175+
}>({
176+
unitSizes: {
177+
ch: 8,
178+
vw: 3.2,
179+
vh: 4.8,
180+
em: 16,
181+
rem: 16,
182+
px: 1,
183+
},
184+
propertySizes: {},
174185
});
175186

176187
/**

apps/builder/app/shared/sync/sync-stores.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import {
1414
$assets,
1515
$selectedPageHash,
1616
$selectedInstanceSelector,
17-
$selectedInstanceBrowserStyle,
18-
$selectedInstanceUnitSizes,
17+
$selectedInstanceSizes,
1918
$selectedInstanceRenderState,
2019
$hoveredInstanceSelector,
2120
$authTokenPermissions,
@@ -98,14 +97,7 @@ export const createObjectPool = () => {
9897
new NanostoresSyncObject("dataSourceVariables", $dataSourceVariables),
9998
new NanostoresSyncObject("resourceValues", $resourceValues),
10099
new NanostoresSyncObject("selectedPageHash", $selectedPageHash),
101-
new NanostoresSyncObject(
102-
"selectedInstanceBrowserStyle",
103-
$selectedInstanceBrowserStyle
104-
),
105-
new NanostoresSyncObject(
106-
"selectedInstanceUnitSizes",
107-
$selectedInstanceUnitSizes
108-
),
100+
new NanostoresSyncObject("selectedInstanceSizes", $selectedInstanceSizes),
109101
new NanostoresSyncObject(
110102
"selectedInstanceRenderState",
111103
$selectedInstanceRenderState

packages/css-engine/src/schema.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,3 @@ export const StyleValue = z.union([
212212
]);
213213

214214
export type StyleValue = z.infer<typeof StyleValue>;
215-
216-
const Style = z.record(z.string(), StyleValue);
217-
218-
export type Style = {
219-
[property in StyleProperty]?: StyleValue;
220-
} & { [property: CustomProperty]: StyleValue };

0 commit comments

Comments
 (0)