From 70f5bc5df9b2bd0be0d0a9f8d860b025b4270d02 Mon Sep 17 00:00:00 2001 From: istarkov Date: Sun, 19 May 2024 23:24:28 +0300 Subject: [PATCH] fix: Make select and combobox description height stable --- .../settings-panel/variable-popover.tsx | 2 +- .../controls/select/select-control.tsx | 2 +- .../style-panel/sections/advanced/add.tsx | 2 +- .../css-value-input/css-value-input.tsx | 22 +++++++++- .../src/components/combobox.stories.tsx | 6 ++- .../design-system/src/components/combobox.tsx | 40 ++++++++++++++--- .../src/components/select.stories.tsx | 35 +++++++++------ .../design-system/src/components/select.tsx | 43 ++++++++++++++++--- 8 files changed, 118 insertions(+), 34 deletions(-) diff --git a/apps/builder/app/builder/features/settings-panel/variable-popover.tsx b/apps/builder/app/builder/features/settings-panel/variable-popover.tsx index 1b2e94a77ae0..a1e7b94833ee 100644 --- a/apps/builder/app/builder/features/settings-panel/variable-popover.tsx +++ b/apps/builder/app/builder/features/settings-panel/variable-popover.tsx @@ -232,7 +232,7 @@ const TypeField = ({ disabled: options.get(option)?.disabled, })} getDescription={(option) => ( - + {options.get(option)?.description} )} diff --git a/apps/builder/app/builder/features/style-panel/controls/select/select-control.tsx b/apps/builder/app/builder/features/style-panel/controls/select/select-control.tsx index 7468c92969b8..e06d8d470ac6 100644 --- a/apps/builder/app/builder/features/style-panel/controls/select/select-control.tsx +++ b/apps/builder/app/builder/features/style-panel/controls/select/select-control.tsx @@ -66,7 +66,7 @@ export const SelectControl = ({ if (description === undefined) { return; } - return {description}; + return {description}; }} getItemProps={() => ({ text: "sentence" })} /> diff --git a/apps/builder/app/builder/features/style-panel/sections/advanced/add.tsx b/apps/builder/app/builder/features/style-panel/sections/advanced/add.tsx index 94c26c2df4b4..887059266939 100644 --- a/apps/builder/app/builder/features/style-panel/sections/advanced/add.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/advanced/add.tsx @@ -63,7 +63,7 @@ export const Add = ({ item.value as keyof typeof propertyDescriptions ]; } - return {description}; + return {description}; }} defaultHighlightedIndex={0} /> 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 57190ab5d724..fb5a1e79c1c4 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 @@ -15,6 +15,7 @@ import { handleNumericInputArrowKeys, theme, Flex, + styled, } from "@webstudio-is/design-system"; import type { KeywordValue, @@ -325,6 +326,9 @@ const itemToString = (item: CssValueInputValue | null) => { ? String(item.value) : toValue(item); }; + +const Description = styled(Box, { width: theme.spacing[27] }); + /** * Common: * - Free text editing @@ -651,6 +655,7 @@ export const CssValueInput = ({ : items[0]?.type === "keyword" ? items[0] : undefined; + if (valueForDescription) { const key = `${property}:${toValue( valueForDescription @@ -658,6 +663,19 @@ export const CssValueInput = ({ description = declarationDescriptions[key]; } + const descriptions = items + .map((item) => + item.type === "keyword" + ? declarationDescriptions[ + `${property}:${toValue( + item + )}` as keyof typeof declarationDescriptions + ] + : undefined + ) + .filter(Boolean) + .map((descr) => {descr}); + return ( @@ -701,8 +719,8 @@ export const CssValueInput = ({ ))} {description && ( - - {description} + + {description} )} diff --git a/packages/design-system/src/components/combobox.stories.tsx b/packages/design-system/src/components/combobox.stories.tsx index 097eaa8c699a..36840a7075b9 100644 --- a/packages/design-system/src/components/combobox.stories.tsx +++ b/packages/design-system/src/components/combobox.stories.tsx @@ -117,7 +117,11 @@ export const Complex = () => { ); })} - Description + + Description + diff --git a/packages/design-system/src/components/combobox.tsx b/packages/design-system/src/components/combobox.tsx index ba01d5d819d2..b043a4f515af 100644 --- a/packages/design-system/src/components/combobox.tsx +++ b/packages/design-system/src/components/combobox.tsx @@ -36,6 +36,7 @@ import { } from "./menu"; import { ScrollArea } from "./scroll-area"; import { Flex, InputField, NestedInputButton } from ".."; +import { Box } from "./box"; export const ComboboxListbox = styled( "ul", @@ -119,9 +120,11 @@ export const ComboboxListboxItem = forwardRef(ListboxItemBase); export const ComboboxItemDescription = ({ children, - style, - ...props -}: ComponentProps) => { + descriptions, +}: { + children: ReactNode; + descriptions: ReactNode[]; +}) => { return ( <> - {children} + {descriptions.map((descr, index) => ( + + {descr} + + ))} + + {children} + ({ : combobox.items[combobox.highlightedIndex]; const description = getDescription?.(descriptionItem); + const descriptions = combobox.items.map((item) => getDescription?.(item)); return ( @@ -463,7 +487,9 @@ export const Combobox = ({ })} {description && ( - {description} + + {description} + )} diff --git a/packages/design-system/src/components/select.stories.tsx b/packages/design-system/src/components/select.stories.tsx index 159ac1d9a99e..9c6aa0f39045 100644 --- a/packages/design-system/src/components/select.stories.tsx +++ b/packages/design-system/src/components/select.stories.tsx @@ -86,26 +86,33 @@ export const WithDescriptions: StoryFn = () => { const options = [ { label: "Apple", description: "An apple fruit" }, { label: "Banana", description: "A banana fruit" }, - { label: "Orange", description: "An orange fruit" }, + { + label: "Orange", + description: + "An orange fruit An orange fruit An orange fruit An orange fruit", + }, { label: "Pear", description: "A pear fruit" }, { label: "Grape", description: "A grape fruit" }, ]; const [value, setValue] = useState<(typeof options)[number]>(options[0]); return ( - value.label} + onChange={setValue} + getLabel={(option) => { + return option.label; + }} + getDescription={(option) => { + return
{option.description}
; + }} + /> + ); }; diff --git a/packages/design-system/src/components/select.tsx b/packages/design-system/src/components/select.tsx index e94ecd8bfc07..7031b930e892 100644 --- a/packages/design-system/src/components/select.tsx +++ b/packages/design-system/src/components/select.tsx @@ -18,6 +18,7 @@ import { MenuCheckedIcon, } from "./menu"; import { SelectButton } from "./select-button"; +import { Box } from "./box"; export const SelectContent = styled(Primitive.Content, menuCss, { "&[data-side=top]": { @@ -86,9 +87,11 @@ const Description = styled("div", menuItemCss); // Note this only works in combination with position: popper on Content component, because only popper exposes data-side attribute export const SelectItemDescription = ({ children, - style, - ...props -}: ComponentProps) => { + descriptions, +}: { + children: ReactNode; + descriptions: ReactNode[]; +}) => { return ( <> + - {children} + {descriptions.map((descr, index) => ( + + {descr} + + ))} + + {children} + + ( ? getDescription?.(itemForDescription) : undefined; + const descriptions = options.map((option) => getDescription?.(option)); + return ( ( {description && ( - {description} + + {description} + )}