diff --git a/apps/designer/app/designer/features/style-panel/shared/css-value-input/css-value-input.tsx b/apps/designer/app/designer/features/style-panel/shared/css-value-input/css-value-input.tsx index 504bfcd149..2ea10e83a3 100644 --- a/apps/designer/app/designer/features/style-panel/shared/css-value-input/css-value-input.tsx +++ b/apps/designer/app/designer/features/style-panel/shared/css-value-input/css-value-input.tsx @@ -49,7 +49,7 @@ const useHandleOnChange = ( const valueRef = useRef(value); useEffect(() => { - if (input === String(valueRef.current.value)) { + if (input === "" || input === String(valueRef.current.value)) { return; } @@ -110,6 +110,8 @@ const useScrub = ({ unit, value: event.value, }); + inputRef.current?.blur(); + inputRef.current?.parentElement?.setAttribute("data-state", "focus"); }, onValueChange(event) { onChangeCompleteRef.current({ @@ -117,6 +119,9 @@ const useScrub = ({ unit, value: event.value, }); + inputRef.current?.focus(); + inputRef.current?.select(); + inputRef.current?.parentElement?.removeAttribute("data-state"); }, }); @@ -148,7 +153,8 @@ const useHandleKeyDown = } if ( value.type === "unit" && - (event.key === "ArrowUp" || event.key === "ArrowDown") + (event.key === "ArrowUp" || event.key === "ArrowDown") && + event.currentTarget.value ) { onChange({ ...value, @@ -230,6 +236,7 @@ export const CssValueInput = ({ useHandleOnChange(value, inputProps.value, onChange); const [isUnitsOpen, unitSelectElement] = useUnitSelect({ + property, value: value.type === "unit" ? value : undefined, onChange: onChangeComplete, onCloseAutoFocus(event) { @@ -263,7 +270,7 @@ export const CssValueInput = ({ const suffix = value.type === "keyword" ? ( - + ) : value.type === "unit" ? ( @@ -289,7 +296,11 @@ export const CssValueInput = ({ css={{ cursor: "default" }} /> - + {isOpen && items.map((item, index) => ( diff --git a/apps/designer/app/designer/features/style-panel/shared/css-value-input/unit-select.tsx b/apps/designer/app/designer/features/style-panel/shared/css-value-input/unit-select.tsx index dc2f8aad55..e6f9cc7b6e 100644 --- a/apps/designer/app/designer/features/style-panel/shared/css-value-input/unit-select.tsx +++ b/apps/designer/app/designer/features/style-panel/shared/css-value-input/unit-select.tsx @@ -10,6 +10,7 @@ import { SelectContent, } from "@webstudio-is/design-system"; import { ChevronDownIcon, ChevronUpIcon } from "@webstudio-is/icons"; +import { isValid } from "../parse-css-value"; const unitRenderMap: Map = new Map([ ["px", "PX"], @@ -19,7 +20,7 @@ const unitRenderMap: Map = new Map([ ["ch", "CH"], ["vw", "VW"], ["vh", "VH"], - ["number", "-"], + ["number", "—"], ]); const renderUnitMap: Map = new Map(); @@ -30,6 +31,7 @@ for (const [key, value] of unitRenderMap.entries()) { const defaultUnits = Array.from(unitRenderMap.keys()); type UseUnitSelectType = { + property: string; value?: UnitValue; onChange: (value: StyleValue) => void; units?: Array; @@ -37,6 +39,7 @@ type UseUnitSelectType = { }; export const useUnitSelect = ({ + property, onChange, value, units = defaultUnits, @@ -44,7 +47,12 @@ export const useUnitSelect = ({ }: UseUnitSelectType) => { const [isOpen, setIsOpen] = useState(false); const renderUnits = useMemo( - () => units.map((unit) => unitRenderMap.get(unit) ?? unit), + () => + units + .filter((unit) => { + return isValid(property, value?.value + String(unit)); + }) + .map((unit) => unitRenderMap.get(unit) ?? unit), [units] ); @@ -78,11 +86,13 @@ export const useUnitSelect = ({ const StyledTrigger = styled(SelectPrimitive.SelectTrigger, { all: "unset", height: "$5", + width: "auto", px: "$1", borderRadius: 2, display: "inline-flex", alignItems: "center", color: "$hiContrast", + justifyContent: "center", "&:hover": { backgroundColor: "$slate6", }, diff --git a/apps/designer/app/designer/features/style-panel/shared/parse-css-value.ts b/apps/designer/app/designer/features/style-panel/shared/parse-css-value.ts index 339565a765..e5056fcc85 100644 --- a/apps/designer/app/designer/features/style-panel/shared/parse-css-value.ts +++ b/apps/designer/app/designer/features/style-panel/shared/parse-css-value.ts @@ -4,7 +4,7 @@ import type { StyleProperty, StyleValue, Unit } from "@webstudio-is/react-sdk"; const unitRegex = new RegExp(`${units.join("|")}`); -const isValid = (property: string, value: string): boolean => { +export const isValid = (property: string, value: string): boolean => { // Only browsers with houdini api will provide validation for now // @todo add a polyfill maybe if ( diff --git a/packages/design-system/src/components/combobox.tsx b/packages/design-system/src/components/combobox.tsx index c81ee172c4..2664688e45 100644 --- a/packages/design-system/src/components/combobox.tsx +++ b/packages/design-system/src/components/combobox.tsx @@ -24,12 +24,12 @@ import { Box } from "./box"; import { Grid } from "./grid"; const Listbox = styled("ul", panelStyles, { - padding: 0, + padding: "$1 0", margin: 0, overflow: "auto", // @todo need some non-hardcoded value maxHeight: 400, - minWidth: 230, + minWidth: 214, variants: { state: { open: {}, @@ -46,7 +46,7 @@ const Listbox = styled("ul", panelStyles, { }); const ListboxItem = styled("li", itemCss, { - padding: 0, + padding: "0 $2", margin: 0, }); diff --git a/packages/design-system/src/components/text-field.tsx b/packages/design-system/src/components/text-field.tsx index b1760fcf84..078cd2edd6 100644 --- a/packages/design-system/src/components/text-field.tsx +++ b/packages/design-system/src/components/text-field.tsx @@ -79,7 +79,7 @@ const TextFieldBase = styled("div", { height: 28, // @todo waiting for the sizing scale lineHeight: 1, - "&:focus-within": { + "&:focus-within, &[data-state=focus]": { boxShadow: "inset 0px 0px 0px 1px $colors$blue10, 0px 0px 0px 1px $colors$blue10", }, diff --git a/packages/react-sdk/src/css/units.ts b/packages/react-sdk/src/css/units.ts index a733273860..1dede3ee72 100644 --- a/packages/react-sdk/src/css/units.ts +++ b/packages/react-sdk/src/css/units.ts @@ -29,4 +29,5 @@ export const units = [ "vw", "x", "%", + "number", ] as const; diff --git a/packages/react-sdk/src/stitches/to-css.ts b/packages/react-sdk/src/stitches/to-css.ts index 199618592c..46556167c4 100644 --- a/packages/react-sdk/src/stitches/to-css.ts +++ b/packages/react-sdk/src/stitches/to-css.ts @@ -2,9 +2,10 @@ import type { CSS } from "./stitches"; import type { StyleProperty, StyleValue, CssRule, Breakpoint } from "../css"; import { DEFAULT_FONT_FALLBACK, SYSTEM_FONTS } from "@webstudio-is/fonts"; -export const toValue = (value: StyleValue): string => { +export const toValue = (value: StyleValue | undefined): string => { + if (value === undefined) return ""; if (value.type === "unit") { - return value.value + (value.unit === "number" ? "" : value.unit); + return value.value + value.unit; } if (value.type === "fontFamily") { const family = value.value[0];