diff --git a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-keyframes.tsx b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-keyframes.tsx index d5f1f87fc7..a75d5ec6c8 100644 --- a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-keyframes.tsx +++ b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-keyframes.tsx @@ -65,7 +65,7 @@ const OffsetInput = ({ intermediateValue={intermediateValue} styleSource="default" /* same as offset has 0 - 100% */ - property={"fontStretch"} + property={"font-stretch"} value={ value !== undefined ? { diff --git a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx index 079ed05568..b1f99c719a 100644 --- a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx +++ b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx @@ -109,7 +109,7 @@ const RangeValueInput = ({ styleSource="default" value={value} /* marginLeft to allow negative values */ - property={"marginLeft"} + property={"margin-left"} unitOptions={unitOptions} intermediateValue={intermediateValue} onChange={(styleValue) => { @@ -156,8 +156,6 @@ const EasingInput = ({ StyleValue | IntermediateStyleValue >(); - const property = "animationTimingFunction"; - return ( { setIntermediateValue(styleValue); diff --git a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-section.tsx b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-section.tsx index 93164ccc2a..bdb64b52c1 100644 --- a/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-section.tsx +++ b/apps/builder/app/builder/features/settings-panel/props-section/animation/animation-section.tsx @@ -115,7 +115,7 @@ const InsetValueInput = ({ styleSource="default" value={value} /* marginLeft to allow negative values */ - property={"marginLeft"} + property="margin-left" unitOptions={unitOptions} intermediateValue={intermediateValue} onChange={(styleValue) => { diff --git a/apps/builder/app/builder/features/style-panel/controls/color/color-control.tsx b/apps/builder/app/builder/features/style-panel/controls/color/color-control.tsx index 0bce16bf11..1554817b69 100644 --- a/apps/builder/app/builder/features/style-panel/controls/color/color-control.tsx +++ b/apps/builder/app/builder/features/style-panel/controls/color/color-control.tsx @@ -1,8 +1,4 @@ -import { - hyphenateProperty, - type CssProperty, - type StyleProperty, -} from "@webstudio-is/css-engine"; +import type { CssProperty } from "@webstudio-is/css-engine"; import { keywordValues } from "@webstudio-is/css-data"; import { ColorPicker } from "../../shared/color-picker"; import { @@ -11,11 +7,7 @@ import { } from "../../shared/model"; import { deleteProperty, setProperty } from "../../shared/use-style-data"; -export const ColorControl = ({ - property, -}: { - property: StyleProperty | CssProperty; -}) => { +export const ColorControl = ({ property }: { property: CssProperty }) => { const computedStyleDecl = useComputedStyleDecl(property); const value = computedStyleDecl.cascadedValue; const currentColor = computedStyleDecl.usedValue; @@ -26,7 +18,7 @@ export const ColorControl = ({ value={value} currentColor={currentColor} getOptions={() => [ - ...(keywordValues[hyphenateProperty(property)] ?? []).map((item) => ({ + ...(keywordValues[property] ?? []).map((item) => ({ type: "keyword" as const, value: item, })), @@ -35,9 +27,7 @@ export const ColorControl = ({ onChange={(styleValue) => setValue(styleValue, { isEphemeral: true })} onChangeComplete={setValue} onAbort={() => deleteProperty(property, { isEphemeral: true })} - onReset={() => { - deleteProperty(property); - }} + onReset={() => deleteProperty(property)} /> ); }; diff --git a/apps/builder/app/builder/features/style-panel/controls/position/position-control.tsx b/apps/builder/app/builder/features/style-panel/controls/position/position-control.tsx index 7a07e4bdf3..efa48cd756 100644 --- a/apps/builder/app/builder/features/style-panel/controls/position/position-control.tsx +++ b/apps/builder/app/builder/features/style-panel/controls/position/position-control.tsx @@ -7,9 +7,7 @@ import { TupleValue, TupleValueItem, type StyleValue, - type StyleProperty, type CssProperty, - hyphenateProperty, } from "@webstudio-is/css-engine"; import { Flex, Grid, PositionGrid } from "@webstudio-is/design-system"; import type { ComputedStyleDecl } from "~/shared/style-object-model"; @@ -58,16 +56,14 @@ export const PositionControl = ({ property, styleDecl, }: { - property: StyleProperty | CssProperty; + property: CssProperty; styleDecl: ComputedStyleDecl; }) => { const value = toTuple(styleDecl.cascadedValue); - const keywords = (keywordValues[hyphenateProperty(property)] ?? []).map( - (value) => ({ - type: "keyword" as const, - value, - }) - ); + const keywords = (keywordValues[property] ?? []).map((value) => ({ + type: "keyword" as const, + value, + })); const setValue = setProperty(property); diff --git a/apps/builder/app/builder/features/style-panel/controls/text/text-control.tsx b/apps/builder/app/builder/features/style-panel/controls/text/text-control.tsx index 84a14add9a..a709452f21 100644 --- a/apps/builder/app/builder/features/style-panel/controls/text/text-control.tsx +++ b/apps/builder/app/builder/features/style-panel/controls/text/text-control.tsx @@ -1,10 +1,5 @@ import { useState } from "react"; -import { - hyphenateProperty, - type CssProperty, - type StyleProperty, - type StyleValue, -} from "@webstudio-is/css-engine"; +import type { CssProperty, StyleValue } from "@webstudio-is/css-engine"; import { keywordValues } from "@webstudio-is/css-data"; import { CssValueInput, @@ -16,11 +11,7 @@ import { useComputedStyleDecl, } from "../../shared/model"; -export const TextControl = ({ - property, -}: { - property: StyleProperty | CssProperty; -}) => { +export const TextControl = ({ property }: { property: CssProperty }) => { const computedStyleDecl = useComputedStyleDecl(property); const value = computedStyleDecl.cascadedValue; const setValue = setProperty(property); @@ -34,7 +25,7 @@ export const TextControl = ({ value={value} intermediateValue={intermediateValue} getOptions={() => [ - ...(keywordValues[hyphenateProperty(property)] ?? []).map((value) => ({ + ...(keywordValues[property] ?? []).map((value) => ({ type: "keyword" as const, value, })), diff --git a/apps/builder/app/builder/features/style-panel/sections/shared/scrub.tsx b/apps/builder/app/builder/features/style-panel/sections/shared/scrub.tsx index 0ffb7797b0..e863a11bdf 100644 --- a/apps/builder/app/builder/features/style-panel/sections/shared/scrub.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/shared/scrub.tsx @@ -6,7 +6,7 @@ import type { } from "@webstudio-is/css-engine"; import { toValue } from "@webstudio-is/css-engine"; import { numericScrubControl } from "@webstudio-is/design-system"; -import { camelCaseProperty, isValidDeclaration } from "@webstudio-is/css-data"; +import { isValidDeclaration } from "@webstudio-is/css-data"; import { useModifierKeys } from "../../shared/modifier-keys"; import type { StyleUpdateOptions } from "../../shared/use-style-data"; import { parseIntermediateOrInvalidValue } from "../../shared/css-value-input/parse-intermediate-or-invalid-value"; @@ -85,7 +85,7 @@ export const useScrub =

(props: { } as const; if (isValidDeclaration(property, toValue(value)) === false) { - value = parseIntermediateOrInvalidValue(camelCaseProperty(property), { + value = parseIntermediateOrInvalidValue(property, { type: "intermediate", value: `${value.value}`, unit: value.unit, diff --git a/apps/builder/app/builder/features/style-panel/sections/transitions/transition-content.tsx b/apps/builder/app/builder/features/style-panel/sections/transitions/transition-content.tsx index 4e5e6eed06..667c9fba14 100644 --- a/apps/builder/app/builder/features/style-panel/sections/transitions/transition-content.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/transitions/transition-content.tsx @@ -125,7 +125,7 @@ export const TransitionContent = ({ index }: { index: number }) => { { $availableUnitVariables.get()} value={duration ?? propertiesData["transition-duration"].initial} @@ -163,10 +163,10 @@ export const TransitionContent = ({ index }: { index: number }) => { $availableUnitVariables.get()} value={delay ?? propertiesData["transition-delay"].initial} @@ -188,10 +188,10 @@ export const TransitionContent = ({ index }: { index: number }) => { [ { type: "keyword", value: "linear" }, diff --git a/apps/builder/app/builder/features/style-panel/shared/color-picker.tsx b/apps/builder/app/builder/features/style-panel/shared/color-picker.tsx index 41c628a1a0..c6e54878d1 100644 --- a/apps/builder/app/builder/features/style-panel/shared/color-picker.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/color-picker.tsx @@ -5,7 +5,6 @@ import { useDebouncedCallback } from "use-debounce"; import { RgbaColorPicker } from "react-colorful"; import { EyedropperIcon } from "@webstudio-is/icons"; import type { - StyleProperty, StyleValue, KeywordValue, RgbValue, @@ -175,7 +174,7 @@ type ColorPickerProps = { value: StyleValue; currentColor: StyleValue; getOptions?: () => Array; - property: StyleProperty | CssProperty; + property: CssProperty; disabled?: boolean; }; diff --git a/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.stories.tsx b/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.stories.tsx index 0c464fa06c..153bef8555 100644 --- a/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.stories.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.stories.tsx @@ -67,7 +67,7 @@ export const WithIcons = () => { return ( [ @@ -116,7 +116,7 @@ export const WithUnits = () => { [ @@ -172,7 +172,7 @@ export const Oversized = () => { { diff --git a/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx b/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx index 7c750f6661..682c53a32e 100644 --- a/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx @@ -21,7 +21,6 @@ import { import type { CssProperty, KeywordValue, - StyleProperty, StyleValue, Unit, VarValue, @@ -40,7 +39,7 @@ import { } from "react"; import { useUnitSelect, type UnitOption } from "./unit-select"; import { parseIntermediateOrInvalidValue } from "./parse-intermediate-or-invalid-value"; -import { hyphenateProperty, toValue } from "@webstudio-is/css-engine"; +import { toValue } from "@webstudio-is/css-engine"; import { camelCaseProperty, declarationDescriptions, @@ -61,9 +60,8 @@ import { import { useEffectEvent } from "~/shared/hook-utils/effect-event"; // We need to enable scrub on properties that can have numeric value. -const canBeNumber = (property: StyleProperty, value: CssValueInputValue) => { - const unitGroups = - propertiesData[hyphenateProperty(property)]?.unitGroups ?? []; +const canBeNumber = (property: CssProperty, value: CssValueInputValue) => { + const unitGroups = propertiesData[property]?.unitGroups ?? []; // allow scrubbing css variables with unit value return unitGroups.length !== 0 || value.type === "unit"; }; @@ -93,7 +91,7 @@ const useScrub = ({ defaultUnit: Unit | undefined; value: CssValueInputValue; intermediateValue: CssValueInputValue | undefined; - property: StyleProperty; + property: CssProperty; onChange: (value: CssValueInputValue | undefined) => void; onChangeComplete: (value: StyleValue) => void; onAbort: () => void; @@ -302,7 +300,7 @@ type CssValueInputProps = Pick< | "inputRef" > & { styleSource: StyleValueSourceColor; - property: StyleProperty | CssProperty; + property: CssProperty; value: StyleValue | undefined; intermediateValue: CssValueInputValue | undefined; /** @@ -475,7 +473,7 @@ export const CssValueInput = ({ prefix, showSuffix = true, styleSource, - property: multiCaseProperty, + property, getOptions = () => [], onHighlight, onAbort, @@ -489,7 +487,6 @@ export const CssValueInput = ({ placeholder, ...props }: CssValueInputProps) => { - const property = camelCaseProperty(multiCaseProperty); const value = props.intermediateValue ?? props.value ?? initialValue; const valueRef = useRef(value); valueRef.current = value; @@ -607,7 +604,7 @@ export const CssValueInput = ({ const [isUnitsOpen, unitSelectElement] = useUnitSelect({ options: unitOptions, - property: hyphenateProperty(multiCaseProperty), + property, value, onChange: (unitOrKeyword) => { if (unitOrKeyword.type === "keyword") { @@ -650,7 +647,7 @@ export const CssValueInput = ({ // value is a keyword or non numeric, try get browser style value and convert it if (value.type === "keyword" || value.type === "intermediate") { - const styleValue = propertySizes[hyphenateProperty(property)]; + const styleValue = propertySizes[property]; const convertedValue = convertUnits(unitSizes)( styleValue?.value ?? 0, styleValue?.unit ?? "number", @@ -790,7 +787,7 @@ export const CssValueInput = ({ ) { description = option.description; } else { - const key = `${property}:${toValue( + const key = `${camelCaseProperty(property)}:${toValue( valueForDescription )}` as keyof typeof declarationDescriptions; description = declarationDescriptions[key]; @@ -808,7 +805,7 @@ export const CssValueInput = ({ .map((item) => item.type === "keyword" ? declarationDescriptions[ - `${property}:${toValue( + `${camelCaseProperty(property)}:${toValue( item )}` as keyof typeof declarationDescriptions ] diff --git a/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts b/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts index 88e0239166..2130977825 100644 --- a/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts +++ b/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts @@ -1,9 +1,8 @@ -import { - type StyleProperty, - type StyleValue, - type InvalidValue, - type Unit, - hyphenateProperty, +import type { + StyleValue, + InvalidValue, + Unit, + CssProperty, } from "@webstudio-is/css-engine"; import { units, @@ -17,9 +16,8 @@ import { toKebabCase } from "../keyword-utils"; const unitsList = Object.values(units).flat(); -const getDefaultUnit = (property: StyleProperty): Unit => { - const unitGroups = - propertiesData[hyphenateProperty(property)]?.unitGroups ?? []; +const getDefaultUnit = (property: CssProperty): Unit => { + const unitGroups = propertiesData[property]?.unitGroups ?? []; for (const unitGroup of unitGroups) { if (unitGroup === "number") { @@ -41,7 +39,7 @@ const getDefaultUnit = (property: StyleProperty): Unit => { }; export const parseIntermediateOrInvalidValue = ( - property: StyleProperty, + property: CssProperty, styleValue: IntermediateStyleValue | InvalidValue, defaultUnit: Unit = getDefaultUnit(property), originalValue?: string diff --git a/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts.test.ts b/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts.test.ts index 122c79e4d3..6b53a98d58 100644 --- a/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts.test.ts +++ b/apps/builder/app/builder/features/style-panel/shared/css-value-input/parse-intermediate-or-invalid-value.ts.test.ts @@ -2,11 +2,11 @@ import { describe, test, expect } from "vitest"; import { parseIntermediateOrInvalidValue } from "./parse-intermediate-or-invalid-value"; import { toKebabCase, toPascalCase } from "../keyword-utils"; -const properties = ["width", "lineHeight"] as const; +const properties = ["width", "line-height"] as const; const propertiesAndKeywords = [ ["width", "auto" as string], - ["lineHeight", "normal" as string], + ["line-height", "normal" as string], ] as const; test("forgive trailing semicolon", () => { @@ -55,7 +55,7 @@ describe("Parse intermediate or invalid value without math evaluation", () => { }); test("fallback to % if px is not supported", () => { - const result = parseIntermediateOrInvalidValue("fontStretch", { + const result = parseIntermediateOrInvalidValue("font-stretch", { type: "intermediate", value: "10", }); @@ -133,7 +133,7 @@ describe("Parse intermediate or invalid value without math evaluation", () => { }); test("keyword with pascal case name", () => { - const result = parseIntermediateOrInvalidValue("boxSizing", { + const result = parseIntermediateOrInvalidValue("box-sizing", { type: "intermediate", value: "Border Box", unit: "em", @@ -173,7 +173,7 @@ describe("Parse intermediate or invalid value without math evaluation", () => { }); test("tolerate comma instead of dot typo while correctly parsing legit comma inside value", () => { - const result = parseIntermediateOrInvalidValue("transitionDuration", { + const result = parseIntermediateOrInvalidValue("transition-duration", { type: "intermediate", value: "1s, 2s", }); @@ -327,7 +327,7 @@ describe("Returns invalid if can't parse", () => { }); test("do not accept wrong keywords", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "auto", }); @@ -341,7 +341,7 @@ describe("Returns invalid if can't parse", () => { describe("Value ending with `-` should be considered unitless", () => { test("Unitless intermediate transformed to unitless", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10-", }); @@ -354,7 +354,7 @@ describe("Value ending with `-` should be considered unitless", () => { }); test("Unit intermediate transformed to unitless", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10-", unit: "em", @@ -368,7 +368,7 @@ describe("Value ending with `-` should be considered unitless", () => { }); test("Unit intermediate with space transformed to unitless", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10 -", unit: "em", @@ -382,7 +382,7 @@ describe("Value ending with `-` should be considered unitless", () => { }); test("Unit number intermediate transformed to unitless", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10", unit: "number", @@ -396,7 +396,7 @@ describe("Value ending with `-` should be considered unitless", () => { }); test("Unitless expression transformed to unitless", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10 + 20 -", unit: "px", @@ -410,7 +410,7 @@ describe("Value ending with `-` should be considered unitless", () => { }); test("Expression containing unit and unitless must be a unit", () => { - const result = parseIntermediateOrInvalidValue("lineHeight", { + const result = parseIntermediateOrInvalidValue("line-height", { type: "intermediate", value: "10px + 20 -", unit: "px", @@ -638,7 +638,7 @@ test("parse css variables as unparsed", () => { test("parse z-index", () => { expect( - parseIntermediateOrInvalidValue("zIndex", { + parseIntermediateOrInvalidValue("z-index", { type: "intermediate", value: "6.5", unit: "number", diff --git a/apps/builder/app/builder/features/style-panel/shared/css-value-input/value-editor-dialog.tsx b/apps/builder/app/builder/features/style-panel/shared/css-value-input/value-editor-dialog.tsx index f4d940b93e..6e6073e347 100644 --- a/apps/builder/app/builder/features/style-panel/shared/css-value-input/value-editor-dialog.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/css-value-input/value-editor-dialog.tsx @@ -1,21 +1,21 @@ +import { useEffect, useState } from "react"; import { NestedInputButton, rawTheme, theme, } from "@webstudio-is/design-system"; import { MaximizeIcon } from "@webstudio-is/icons"; -import { useEffect, useState } from "react"; +import type { + CssProperty, + InvalidValue, + StyleValue, +} from "@webstudio-is/css-engine"; import { EditorDialog } from "~/builder/shared/code-editor-base"; import { CssFragmentEditorContent } from "../css-fragment"; import type { CssValueInputValue, IntermediateStyleValue, } from "./css-value-input"; -import { - type InvalidValue, - type StyleProperty, - type StyleValue, -} from "@webstudio-is/css-engine"; import { parseIntermediateOrInvalidValue } from "./parse-intermediate-or-invalid-value"; export const cssButtonDisplay = "--ws-css-value-input-maximize-button-display"; @@ -44,7 +44,7 @@ export const ValueEditorDialog = ({ value, onChangeComplete, }: { - property: StyleProperty; + property: CssProperty; value: string; onChangeComplete: (value: StyleValue) => void; }) => { diff --git a/apps/builder/app/builder/features/style-panel/shared/filter-content.tsx b/apps/builder/app/builder/features/style-panel/shared/filter-content.tsx index 5cdde1c8a1..2191d0d9a1 100644 --- a/apps/builder/app/builder/features/style-panel/shared/filter-content.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/filter-content.tsx @@ -40,7 +40,7 @@ import { parseCssFragment } from "./css-fragment"; const filterFunctions = { // https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur#syntax // length - blur: { default: "0px", fakeProperty: "outlineOffset" }, + blur: { default: "0px", fakeProperty: "outline-offset" }, // https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/brightness#formal_syntax // number | percentage brightness: { default: "0%", fakeProperty: "opacity" }, @@ -199,7 +199,7 @@ export const FilterSectionContent = ({ property={ filterFunction ? filterFunctions[filterFunction].fakeProperty - : "outlineOffset" + : "outline-offset" } styleSource="local" value={ diff --git a/apps/builder/app/builder/features/style-panel/shared/shadow-content.tsx b/apps/builder/app/builder/features/style-panel/shared/shadow-content.tsx index ae0c32b77e..87a9b77a56 100644 --- a/apps/builder/app/builder/features/style-panel/shared/shadow-content.tsx +++ b/apps/builder/app/builder/features/style-panel/shared/shadow-content.tsx @@ -219,7 +219,7 @@ export const ShadowContent = ({