From dcd118952692de81c8b9d9f54c7cac329de47bc4 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Fri, 16 May 2025 17:09:01 +0300 Subject: [PATCH 1/2] refactor: merge radix props with component metas Related https://github.com/webstudio-is/webstudio/pull/5211 We moved html attributes away from props metas and have very little actual props left in meta. It is safe to merge with component meta to simplify access in both builder and CLI. CLI size increase is not very significant ```diff - 241.92kB + 256.64kB ``` --- .../props-section/props-section.tsx | 4 + .../app/shared/nano-states/components.ts | 17 +++-- .../sdk-components-react-radix/package.json | 5 -- .../src/accordion.ws.ts | 41 +++------- .../src/checkbox.tsx | 14 +++- .../src/checkbox.ws.ts | 16 +--- .../src/collapsible.ws.ts | 24 +----- .../src/dialog.ws.ts | 61 +++------------ .../src/label.ws.ts | 11 +-- .../src/navigation-menu.ws.ts | 29 ++------ .../src/popover.ws.ts | 29 ++------ .../sdk-components-react-radix/src/props.ts | 74 ------------------- .../src/radio-group.tsx | 13 +++- .../src/radio-group.ws.ts | 23 ++---- .../src/select.ws.ts | 74 +++++-------------- .../sdk-components-react-radix/src/switch.tsx | 14 +++- .../src/switch.ws.ts | 16 +--- .../sdk-components-react-radix/src/tabs.ws.ts | 36 ++------- .../src/tooltip.ws.ts | 23 ++---- packages/sdk/src/schema/component-meta.ts | 3 + 20 files changed, 134 insertions(+), 393 deletions(-) diff --git a/apps/builder/app/builder/features/settings-panel/props-section/props-section.tsx b/apps/builder/app/builder/features/settings-panel/props-section/props-section.tsx index cfe1a9ccfdc6..dba1af50e889 100644 --- a/apps/builder/app/builder/features/settings-panel/props-section/props-section.tsx +++ b/apps/builder/app/builder/features/settings-panel/props-section/props-section.tsx @@ -19,6 +19,7 @@ import { import { isAttributeNameSafe, reactPropsToStandardAttributes, + showAttribute, standardAttributesToReactProps, } from "@webstudio-is/react-sdk"; import { @@ -115,6 +116,9 @@ const $availableProps = computed( (instance, props, propsMetas, initialPropNames) => { const availableProps = new Map(); for (const [name, { label, description }] of propsMetas) { + if (name === showAttribute) { + continue; + } availableProps.set(name, { name, label, description }); } if (instance === undefined) { diff --git a/apps/builder/app/shared/nano-states/components.ts b/apps/builder/app/shared/nano-states/components.ts index 8e41229ad47b..f4ea5136e121 100644 --- a/apps/builder/app/shared/nano-states/components.ts +++ b/apps/builder/app/shared/nano-states/components.ts @@ -206,10 +206,22 @@ export const registerComponentLibrary = ({ } $registeredComponents.set(nextComponents); + const prevPropsMetas = $registeredComponentPropsMetas.get(); + const nextPropsMetas = new Map(prevPropsMetas); + for (const [componentName, propsMeta] of Object.entries(propsMetas)) { + nextPropsMetas.set(`${prefix}${componentName}`, propsMeta); + } + const prevMetas = $registeredComponentMetas.get(); const nextMetas = new Map(prevMetas); for (const [componentName, meta] of Object.entries(metas)) { nextMetas.set(`${prefix}${componentName}`, meta); + if (meta.initialProps || meta.props) { + nextPropsMetas.set(`${prefix}${componentName}`, { + initialProps: meta.initialProps, + props: meta.props ?? {}, + }); + } } $registeredComponentMetas.set(nextMetas); @@ -230,10 +242,5 @@ export const registerComponentLibrary = ({ $registeredComponentHooks.set(nextHooks); } - const prevPropsMetas = $registeredComponentPropsMetas.get(); - const nextPropsMetas = new Map(prevPropsMetas); - for (const [componentName, propsMeta] of Object.entries(propsMetas)) { - nextPropsMetas.set(`${prefix}${componentName}`, propsMeta); - } $registeredComponentPropsMetas.set(nextPropsMetas); }; diff --git a/packages/sdk-components-react-radix/package.json b/packages/sdk-components-react-radix/package.json index 7472a546da86..e4c3045de5cf 100644 --- a/packages/sdk-components-react-radix/package.json +++ b/packages/sdk-components-react-radix/package.json @@ -23,11 +23,6 @@ "types": "./lib/types/metas.d.ts", "import": "./lib/metas.js" }, - "./props": { - "webstudio": "./src/props.ts", - "types": "./lib/types/props.d.ts", - "import": "./lib/props.js" - }, "./hooks": { "webstudio": "./src/hooks.ts", "types": "./lib/types/hooks.d.ts", diff --git a/packages/sdk-components-react-radix/src/accordion.ws.ts b/packages/sdk-components-react-radix/src/accordion.ws.ts index d63cb4ffd8d1..9699bb47cb94 100644 --- a/packages/sdk-components-react-radix/src/accordion.ws.ts +++ b/packages/sdk-components-react-radix/src/accordion.ws.ts @@ -5,11 +5,7 @@ import { TriggerIcon, ContentIcon, } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { div, h3, button } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { buttonReset } from "./shared/preset-styles"; @@ -28,9 +24,9 @@ export const metaAccordion: WsComponentMeta = { children: ["instance"], descendants: [radix.AccordionItem], }, - presetStyle: { - div, - }, + presetStyle: { div }, + initialProps: ["value", "collapsible"], + props: propsAccordion, }; export const metaAccordionItem: WsComponentMeta = { @@ -42,9 +38,9 @@ export const metaAccordionItem: WsComponentMeta = { children: ["instance"], descendants: [radix.AccordionHeader, radix.AccordionContent], }, - presetStyle: { - div, - }, + presetStyle: { div }, + initialProps: ["value"], + props: propsAccordionItem, }; export const metaAccordionHeader: WsComponentMeta = { @@ -68,6 +64,7 @@ export const metaAccordionHeader: WsComponentMeta = { }, ], }, + props: propsAccordionHeader, }; export const metaAccordionTrigger: WsComponentMeta = { @@ -88,6 +85,7 @@ export const metaAccordionTrigger: WsComponentMeta = { presetStyle: { button: [button, buttonReset].flat(), }, + props: propsAccordionTrigger, }; export const metaAccordionContent: WsComponentMeta = { @@ -100,26 +98,5 @@ export const metaAccordionContent: WsComponentMeta = { presetStyle: { div, }, -}; - -export const propsMetaAccordion: WsComponentPropsMeta = { - props: propsAccordion, - initialProps: ["value", "collapsible"], -}; - -export const propsMetaAccordionItem: WsComponentPropsMeta = { - props: propsAccordionItem, - initialProps: ["value"], -}; - -export const propsMetaAccordionHeader: WsComponentPropsMeta = { - props: propsAccordionHeader, -}; - -export const propsMetaAccordionTrigger: WsComponentPropsMeta = { - props: propsAccordionTrigger, -}; - -export const propsMetaAccordionContent: WsComponentPropsMeta = { props: propsAccordionContent, }; diff --git a/packages/sdk-components-react-radix/src/checkbox.tsx b/packages/sdk-components-react-radix/src/checkbox.tsx index ff41e3bfd2ec..dcf99a39ec11 100644 --- a/packages/sdk-components-react-radix/src/checkbox.tsx +++ b/packages/sdk-components-react-radix/src/checkbox.tsx @@ -5,6 +5,7 @@ import { type ComponentProps, } from "react"; import { Root, Indicator } from "@radix-ui/react-checkbox"; +import { useControllableState } from "@radix-ui/react-use-controllable-state"; export const Checkbox = forwardRef< HTMLButtonElement, @@ -14,9 +15,18 @@ export const Checkbox = forwardRef< checked?: boolean; defaultChecked?: boolean; } ->(({ checked, defaultChecked, ...props }, ref) => { +>(({ defaultChecked, ...props }, ref) => { + const [checked, onCheckedChange] = useControllableState({ + prop: props.checked ?? defaultChecked ?? false, + defaultProp: false, + }); return ( - + onCheckedChange(open === true)} + /> ); }); diff --git a/packages/sdk-components-react-radix/src/checkbox.ws.ts b/packages/sdk-components-react-radix/src/checkbox.ws.ts index 7bae2fad3f6d..73d1a34c62e9 100644 --- a/packages/sdk-components-react-radix/src/checkbox.ws.ts +++ b/packages/sdk-components-react-radix/src/checkbox.ws.ts @@ -1,9 +1,5 @@ import { CheckboxCheckedIcon, TriggerIcon } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { button, span } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { buttonReset } from "./shared/preset-styles"; @@ -35,6 +31,8 @@ export const metaCheckbox: WsComponentMeta = { presetStyle: { button: [button, buttonReset].flat(), }, + initialProps: ["id", "class", "name", "value", "required", "checked"], + props: propsCheckbox, }; export const metaCheckboxIndicator: WsComponentMeta = { @@ -47,13 +45,5 @@ export const metaCheckboxIndicator: WsComponentMeta = { presetStyle: { span, }, -}; - -export const propsMetaCheckbox: WsComponentPropsMeta = { - props: propsCheckbox, - initialProps: ["id", "className", "name", "value", "required", "checked"], -}; - -export const propsMetaCheckboxIndicator: WsComponentPropsMeta = { props: propsCheckboxIndicator, }; diff --git a/packages/sdk-components-react-radix/src/collapsible.ws.ts b/packages/sdk-components-react-radix/src/collapsible.ws.ts index 5f45be20989a..19bb850b37f9 100644 --- a/packages/sdk-components-react-radix/src/collapsible.ws.ts +++ b/packages/sdk-components-react-radix/src/collapsible.ws.ts @@ -3,7 +3,7 @@ import { TriggerIcon, ContentIcon, } from "@webstudio-is/icons/svg"; -import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk"; +import type { WsComponentMeta } from "@webstudio-is/sdk"; import { div } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -22,6 +22,8 @@ export const metaCollapsible: WsComponentMeta = { presetStyle: { div, }, + initialProps: ["open"], + props: propsCollapsible, }; export const metaCollapsibleTrigger: WsComponentMeta = { @@ -30,6 +32,7 @@ export const metaCollapsibleTrigger: WsComponentMeta = { category: "none", children: ["instance", "rich-text"], }, + props: propsCollapsibleTrigger, }; export const metaCollapsibleContent: WsComponentMeta = { @@ -41,24 +44,5 @@ export const metaCollapsibleContent: WsComponentMeta = { presetStyle: { div, }, -}; - -export const propsMetaCollapsible: WsComponentPropsMeta = { - props: { - ...propsCollapsible, - onOpenChange: { - type: "action", - control: "action", - required: false, - }, - }, - initialProps: ["open", "onOpenChange"], -}; - -export const propsMetaCollapsibleTrigger: WsComponentPropsMeta = { - props: propsCollapsibleTrigger, -}; - -export const propsMetaCollapsibleContent: WsComponentPropsMeta = { props: propsCollapsibleContent, }; diff --git a/packages/sdk-components-react-radix/src/dialog.ws.ts b/packages/sdk-components-react-radix/src/dialog.ws.ts index cab7473c0e28..e5d2ca917be2 100644 --- a/packages/sdk-components-react-radix/src/dialog.ws.ts +++ b/packages/sdk-components-react-radix/src/dialog.ws.ts @@ -7,11 +7,7 @@ import { TextIcon, ButtonElementIcon, } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { div, button, h2, p } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -32,6 +28,7 @@ export const metaDialogTrigger: WsComponentMeta = { category: "none", children: ["instance"], }, + props: propsDialogTrigger, }; export const metaDialogOverlay: WsComponentMeta = { @@ -41,9 +38,8 @@ export const metaDialogOverlay: WsComponentMeta = { children: ["instance"], descendants: [radix.DialogContent], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsDialogOverlay, }; export const metaDialogContent: WsComponentMeta = { @@ -57,9 +53,8 @@ export const metaDialogContent: WsComponentMeta = { radix.DialogClose, ], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsDialogContent, }; export const metaDialogTitle: WsComponentMeta = { @@ -68,9 +63,8 @@ export const metaDialogTitle: WsComponentMeta = { category: "none", children: ["instance", "rich-text"], }, - presetStyle: { - h2, - }, + presetStyle: { h2 }, + props: propsDialogTitle, }; export const metaDialogDescription: WsComponentMeta = { @@ -79,9 +73,8 @@ export const metaDialogDescription: WsComponentMeta = { category: "none", children: ["instance", "rich-text"], }, - presetStyle: { - p, - }, + presetStyle: { p }, + props: propsDialogDescription, }; export const metaDialogClose: WsComponentMeta = { @@ -95,6 +88,7 @@ export const metaDialogClose: WsComponentMeta = { presetStyle: { button: [buttonReset, button].flat(), }, + props: propsDialogClose, }; export const metaDialog: WsComponentMeta = { @@ -104,38 +98,5 @@ export const metaDialog: WsComponentMeta = { children: ["instance"], descendants: [radix.DialogTrigger, radix.DialogOverlay], }, -}; - -export const propsMetaDialog: WsComponentPropsMeta = { props: propsDialog, - initialProps: [], -}; - -export const propsMetaDialogTrigger: WsComponentPropsMeta = { - props: propsDialogTrigger, -}; - -export const propsMetaDialogContent: WsComponentPropsMeta = { - props: propsDialogContent, - initialProps: [], -}; - -export const propsMetaDialogOverlay: WsComponentPropsMeta = { - props: propsDialogOverlay, - initialProps: [], -}; - -export const propsMetaDialogClose: WsComponentPropsMeta = { - props: propsDialogClose, - initialProps: [], -}; - -export const propsMetaDialogTitle: WsComponentPropsMeta = { - props: propsDialogTitle, - initialProps: [], -}; - -export const propsMetaDialogDescription: WsComponentPropsMeta = { - props: propsDialogDescription, - initialProps: [], }; diff --git a/packages/sdk-components-react-radix/src/label.ws.ts b/packages/sdk-components-react-radix/src/label.ws.ts index 9cc8d942d300..f16a81f81ca6 100644 --- a/packages/sdk-components-react-radix/src/label.ws.ts +++ b/packages/sdk-components-react-radix/src/label.ws.ts @@ -1,9 +1,5 @@ import { LabelIcon } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { label } from "@webstudio-is/sdk/normalize.css"; import { props } from "./__generated__/label.props"; @@ -13,9 +9,6 @@ export const meta: WsComponentMeta = { presetStyle: { label, }, -}; - -export const propsMeta: WsComponentPropsMeta = { + initialProps: ["id", "class", "for"], props, - initialProps: ["id", "className", "htmlFor"], }; diff --git a/packages/sdk-components-react-radix/src/navigation-menu.ws.ts b/packages/sdk-components-react-radix/src/navigation-menu.ws.ts index fce38a371fed..7f169f227595 100644 --- a/packages/sdk-components-react-radix/src/navigation-menu.ws.ts +++ b/packages/sdk-components-react-radix/src/navigation-menu.ws.ts @@ -7,7 +7,7 @@ import { ViewportIcon, NavigationMenuIcon, } from "@webstudio-is/icons/svg"; -import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk"; +import type { WsComponentMeta } from "@webstudio-is/sdk"; import { div } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -30,6 +30,7 @@ export const metaNavigationMenu: WsComponentMeta = { presetStyle: { div, }, + props: propsNavigationMenu, }; export const metaNavigationMenuList: WsComponentMeta = { @@ -43,6 +44,7 @@ export const metaNavigationMenuList: WsComponentMeta = { presetStyle: { div, }, + props: propsNavigationMenuList, }; export const metaNavigationMenuItem: WsComponentMeta = { @@ -61,6 +63,7 @@ export const metaNavigationMenuItem: WsComponentMeta = { presetStyle: { div, }, + props: propsNavigationMenuItem, }; export const metaNavigationMenuTrigger: WsComponentMeta = { @@ -70,6 +73,7 @@ export const metaNavigationMenuTrigger: WsComponentMeta = { category: "none", children: ["instance"], }, + props: propsNavigationMenuTrigger, }; export const metaNavigationMenuContent: WsComponentMeta = { @@ -83,6 +87,7 @@ export const metaNavigationMenuContent: WsComponentMeta = { presetStyle: { div, }, + props: propsNavigationMenuContent, }; export const metaNavigationMenuLink: WsComponentMeta = { @@ -92,6 +97,7 @@ export const metaNavigationMenuLink: WsComponentMeta = { category: "none", children: ["instance"], }, + props: propsNavigationMenuLink, }; export const metaNavigationMenuViewport: WsComponentMeta = { @@ -104,26 +110,5 @@ export const metaNavigationMenuViewport: WsComponentMeta = { presetStyle: { div, }, -}; - -export const propsMetaNavigationMenu: WsComponentPropsMeta = { - props: propsNavigationMenu, -}; -export const propsMetaNavigationMenuItem: WsComponentPropsMeta = { - props: propsNavigationMenuItem, -}; -export const propsMetaNavigationMenuTrigger: WsComponentPropsMeta = { - props: propsNavigationMenuTrigger, -}; -export const propsMetaNavigationMenuContent: WsComponentPropsMeta = { - props: propsNavigationMenuContent, -}; -export const propsMetaNavigationMenuLink: WsComponentPropsMeta = { - props: propsNavigationMenuLink, -}; -export const propsMetaNavigationMenuList: WsComponentPropsMeta = { - props: propsNavigationMenuList, -}; -export const propsMetaNavigationMenuViewport: WsComponentPropsMeta = { props: propsNavigationMenuViewport, }; diff --git a/packages/sdk-components-react-radix/src/popover.ws.ts b/packages/sdk-components-react-radix/src/popover.ws.ts index bd50c179cb62..a76dfd12c87e 100644 --- a/packages/sdk-components-react-radix/src/popover.ws.ts +++ b/packages/sdk-components-react-radix/src/popover.ws.ts @@ -4,11 +4,7 @@ import { ContentIcon, ButtonElementIcon, } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { button, div } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -26,6 +22,7 @@ export const metaPopoverTrigger: WsComponentMeta = { category: "none", children: ["instance"], }, + props: propsPopoverTrigger, }; export const metaPopoverContent: WsComponentMeta = { @@ -38,6 +35,8 @@ export const metaPopoverContent: WsComponentMeta = { presetStyle: { div, }, + initialProps: ["side", "sideOffset", "align", "alignOffset"], + props: propsPopoverContent, }; export const metaPopover: WsComponentMeta = { @@ -47,6 +46,8 @@ export const metaPopover: WsComponentMeta = { children: ["instance"], descendants: [radix.PopoverTrigger, radix.PopoverContent], }, + initialProps: ["open"], + props: propsPopover, }; export const metaPopoverClose: WsComponentMeta = { @@ -60,23 +61,5 @@ export const metaPopoverClose: WsComponentMeta = { presetStyle: { button: [buttonReset, button].flat(), }, -}; - -export const propsMetaPopover: WsComponentPropsMeta = { - props: propsPopover, - initialProps: ["open"], -}; - -export const propsMetaPopoverTrigger: WsComponentPropsMeta = { - props: propsPopoverTrigger, -}; - -export const propsMetaPopoverContent: WsComponentPropsMeta = { - props: propsPopoverContent, - initialProps: ["side", "sideOffset", "align", "alignOffset"], -}; - -export const propsMetaPopoverClose: WsComponentPropsMeta = { props: propsPopoverClose, - initialProps: [], }; diff --git a/packages/sdk-components-react-radix/src/props.ts b/packages/sdk-components-react-radix/src/props.ts index 8550297d3de2..e69de29bb2d1 100644 --- a/packages/sdk-components-react-radix/src/props.ts +++ b/packages/sdk-components-react-radix/src/props.ts @@ -1,74 +0,0 @@ -export { - propsMetaCollapsible as Collapsible, - propsMetaCollapsibleTrigger as CollapsibleTrigger, - propsMetaCollapsibleContent as CollapsibleContent, -} from "./collapsible.ws"; -export { - propsMetaDialog as Dialog, - propsMetaDialogTrigger as DialogTrigger, - propsMetaDialogOverlay as DialogOverlay, - propsMetaDialogContent as DialogContent, - propsMetaDialogClose as DialogClose, - propsMetaDialogTitle as DialogTitle, - propsMetaDialogDescription as DialogDescription, -} from "./dialog.ws"; -export { - propsMetaPopover as Popover, - propsMetaPopoverTrigger as PopoverTrigger, - propsMetaPopoverContent as PopoverContent, - propsMetaPopoverClose as PopoverClose, -} from "./popover.ws"; -export { - propsMetaTooltip as Tooltip, - propsMetaTooltipTrigger as TooltipTrigger, - propsMetaTooltipContent as TooltipContent, -} from "./tooltip.ws"; -export { - propsMetaTabs as Tabs, - propsMetaTabsList as TabsList, - propsMetaTabsTrigger as TabsTrigger, - propsMetaTabsContent as TabsContent, -} from "./tabs.ws"; -export { propsMeta as Label } from "./label.ws"; -export { - propsMetaAccordion as Accordion, - propsMetaAccordionItem as AccordionItem, - propsMetaAccordionHeader as AccordionHeader, - propsMetaAccordionTrigger as AccordionTrigger, - propsMetaAccordionContent as AccordionContent, -} from "./accordion.ws"; - -export { - propsMetaNavigationMenu as NavigationMenu, - propsMetaNavigationMenuList as NavigationMenuList, - propsMetaNavigationMenuItem as NavigationMenuItem, - propsMetaNavigationMenuTrigger as NavigationMenuTrigger, - propsMetaNavigationMenuContent as NavigationMenuContent, - propsMetaNavigationMenuLink as NavigationMenuLink, - propsMetaNavigationMenuViewport as NavigationMenuViewport, -} from "./navigation-menu.ws"; - -export { - propsMetaSelect as Select, - propsMetaSelectTrigger as SelectTrigger, - propsMetaSelectValue as SelectValue, - propsMetaSelectViewport as SelectViewport, - propsMetaSelectContent as SelectContent, - propsMetaSelectItem as SelectItem, - propsMetaSelectItemIndicator as SelectItemIndicator, - propsMetaSelectItemText as SelectItemText, -} from "./select.ws"; - -export { - propsMetaSwitch as Switch, - propsMetaSwitchThumb as SwitchThumb, -} from "./switch.ws"; -export { - propsMetaCheckbox as Checkbox, - propsMetaCheckboxIndicator as CheckboxIndicator, -} from "./checkbox.ws"; -export { - propsMetaRadioGroup as RadioGroup, - propsMetaRadioGroupItem as RadioGroupItem, - propsMetaRadioGroupIndicator as RadioGroupIndicator, -} from "./radio-group.ws"; diff --git a/packages/sdk-components-react-radix/src/radio-group.tsx b/packages/sdk-components-react-radix/src/radio-group.tsx index ad91964246b8..b706e34d8f21 100644 --- a/packages/sdk-components-react-radix/src/radio-group.tsx +++ b/packages/sdk-components-react-radix/src/radio-group.tsx @@ -6,6 +6,7 @@ import { forwardRef, } from "react"; import { Root, Item, Indicator } from "@radix-ui/react-radio-group"; +import { useControllableState } from "@radix-ui/react-use-controllable-state"; const defaultTag = "div"; @@ -13,9 +14,15 @@ export const RadioGroup = forwardRef< ElementRef, ComponentProps & RefAttributes // Make sure children are not passed down to an input, because this will result in error. ->(({ value, defaultValue, ...props }, ref) => ( - -)); +>(({ defaultValue, ...props }, ref) => { + const [value, onValueChange] = useControllableState({ + prop: props.value ?? defaultValue ?? "", + defaultProp: "", + }); + return ( + + ); +}); export const RadioGroupItem: ForwardRefExoticComponent< ComponentProps & RefAttributes diff --git a/packages/sdk-components-react-radix/src/radio-group.ws.ts b/packages/sdk-components-react-radix/src/radio-group.ws.ts index 4fa5b986f63c..7182bedc0c9e 100644 --- a/packages/sdk-components-react-radix/src/radio-group.ws.ts +++ b/packages/sdk-components-react-radix/src/radio-group.ws.ts @@ -1,9 +1,5 @@ import { ItemIcon, RadioGroupIcon, TriggerIcon } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { button, div, span } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { buttonReset } from "./shared/preset-styles"; @@ -36,6 +32,8 @@ export const metaRadioGroup: WsComponentMeta = { presetStyle: { div, }, + initialProps: ["id", "class", "name", "value", "required"], + props: propsRadioGroup, }; export const metaRadioGroupItem: WsComponentMeta = { @@ -49,6 +47,8 @@ export const metaRadioGroupItem: WsComponentMeta = { presetStyle: { button: [button, buttonReset].flat(), }, + initialProps: ["value"], + props: propsRadioGroupItem, }; export const metaRadioGroupIndicator: WsComponentMeta = { @@ -61,18 +61,5 @@ export const metaRadioGroupIndicator: WsComponentMeta = { presetStyle: { span, }, -}; - -export const propsMetaRadioGroup: WsComponentPropsMeta = { - props: propsRadioGroup, - initialProps: ["id", "className", "name", "value", "required"], -}; - -export const propsMetaRadioGroupItem: WsComponentPropsMeta = { - props: propsRadioGroupItem, - initialProps: ["value"], -}; - -export const propsMetaRadioGroupIndicator: WsComponentPropsMeta = { props: propsRadioGroupIndicator, }; diff --git a/packages/sdk-components-react-radix/src/select.ws.ts b/packages/sdk-components-react-radix/src/select.ws.ts index c86a0ab1e627..4d34468d9ed4 100644 --- a/packages/sdk-components-react-radix/src/select.ws.ts +++ b/packages/sdk-components-react-radix/src/select.ws.ts @@ -8,7 +8,7 @@ import { TextIcon, CheckMarkIcon, } from "@webstudio-is/icons/svg"; -import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk"; +import type { WsComponentMeta } from "@webstudio-is/sdk"; import { button, div, span } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -29,6 +29,8 @@ export const metaSelect: WsComponentMeta = { children: ["instance"], descendants: [radix.SelectTrigger, radix.SelectContent], }, + initialProps: ["name", "value", "open", "required"], + props: propsSelect, }; export const metaSelectTrigger: WsComponentMeta = { @@ -38,9 +40,8 @@ export const metaSelectTrigger: WsComponentMeta = { children: ["instance"], descendants: [radix.SelectValue], }, - presetStyle: { - button, - }, + presetStyle: { button }, + props: propsSelectTrigger, }; export const metaSelectValue: WsComponentMeta = { @@ -50,9 +51,9 @@ export const metaSelectValue: WsComponentMeta = { category: "none", children: [], }, - presetStyle: { - span, - }, + presetStyle: { span }, + initialProps: ["placeholder"], + props: propsSelectValue, }; export const metaSelectContent: WsComponentMeta = { @@ -62,9 +63,8 @@ export const metaSelectContent: WsComponentMeta = { children: ["instance"], descendants: [radix.SelectViewport], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsSelectContent, }; export const metaSelectViewport: WsComponentMeta = { @@ -74,9 +74,8 @@ export const metaSelectViewport: WsComponentMeta = { children: ["instance"], descendants: [radix.SelectItem], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsSelectViewport, }; export const metaSelectItem: WsComponentMeta = { @@ -86,9 +85,9 @@ export const metaSelectItem: WsComponentMeta = { children: ["instance"], descendants: [radix.SelectItemIndicator, radix.SelectItemText], }, - presetStyle: { - div, - }, + presetStyle: { div }, + initialProps: ["value"], + props: propsSelectItem, }; export const metaSelectItemIndicator: WsComponentMeta = { @@ -98,9 +97,8 @@ export const metaSelectItemIndicator: WsComponentMeta = { category: "none", children: ["instance"], }, - presetStyle: { - span, - }, + presetStyle: { span }, + props: propsSelectItemIndicator, }; export const metaSelectItemText: WsComponentMeta = { @@ -110,42 +108,6 @@ export const metaSelectItemText: WsComponentMeta = { category: "none", children: ["instance", "rich-text"], }, - presetStyle: { - span, - }, -}; - -export const propsMetaSelect: WsComponentPropsMeta = { - props: propsSelect, - initialProps: ["name", "value", "open", "required"], -}; - -export const propsMetaSelectTrigger: WsComponentPropsMeta = { - props: propsSelectTrigger, -}; - -export const propsMetaSelectValue: WsComponentPropsMeta = { - props: propsSelectValue, - initialProps: ["placeholder"], -}; - -export const propsMetaSelectContent: WsComponentPropsMeta = { - props: propsSelectContent, -}; - -export const propsMetaSelectViewport: WsComponentPropsMeta = { - props: propsSelectViewport, -}; - -export const propsMetaSelectItem: WsComponentPropsMeta = { - props: propsSelectItem, - initialProps: ["value"], -}; - -export const propsMetaSelectItemIndicator: WsComponentPropsMeta = { - props: propsSelectItemIndicator, -}; - -export const propsMetaSelectItemText: WsComponentPropsMeta = { + presetStyle: { span }, props: propsSelectItemText, }; diff --git a/packages/sdk-components-react-radix/src/switch.tsx b/packages/sdk-components-react-radix/src/switch.tsx index 0345f8de329c..55d94d6087c0 100644 --- a/packages/sdk-components-react-radix/src/switch.tsx +++ b/packages/sdk-components-react-radix/src/switch.tsx @@ -5,13 +5,23 @@ import { forwardRef, } from "react"; import { Root, Thumb } from "@radix-ui/react-switch"; +import { useControllableState } from "@radix-ui/react-use-controllable-state"; export const Switch = forwardRef< HTMLButtonElement, ComponentProps ->(({ defaultChecked, checked, ...props }, ref) => { +>(({ defaultChecked, ...props }, ref) => { + const [checked, onCheckedChange] = useControllableState({ + prop: props.checked ?? defaultChecked ?? false, + defaultProp: false, + }); return ( - + ); }); diff --git a/packages/sdk-components-react-radix/src/switch.ws.ts b/packages/sdk-components-react-radix/src/switch.ws.ts index 9f52d0cae94a..615736ed8afc 100644 --- a/packages/sdk-components-react-radix/src/switch.ws.ts +++ b/packages/sdk-components-react-radix/src/switch.ws.ts @@ -1,9 +1,5 @@ import { SwitchIcon, TriggerIcon } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { button, span } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { buttonReset } from "./shared/preset-styles"; @@ -32,6 +28,8 @@ export const metaSwitch: WsComponentMeta = { presetStyle: { button: [button, buttonReset].flat(), }, + initialProps: ["id", "class", "name", "value", "checked", "required"], + props: propsSwitch, }; export const metaSwitchThumb: WsComponentMeta = { @@ -56,13 +54,5 @@ export const metaSwitchThumb: WsComponentMeta = { presetStyle: { span, }, -}; - -export const propsMetaSwitch: WsComponentPropsMeta = { - props: propsSwitch, - initialProps: ["id", "className", "name", "value", "checked", "required"], -}; - -export const propsMetaSwitchThumb: WsComponentPropsMeta = { props: propsSwitchThumb, }; diff --git a/packages/sdk-components-react-radix/src/tabs.ws.ts b/packages/sdk-components-react-radix/src/tabs.ws.ts index b21fc28659e6..0c211d441fd2 100644 --- a/packages/sdk-components-react-radix/src/tabs.ws.ts +++ b/packages/sdk-components-react-radix/src/tabs.ws.ts @@ -4,11 +4,7 @@ import { TabsIcon, TriggerIcon, } from "@webstudio-is/icons/svg"; -import { - defaultStates, - type WsComponentMeta, - type WsComponentPropsMeta, -} from "@webstudio-is/sdk"; +import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk"; import { button, div } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { buttonReset } from "./shared/preset-styles"; @@ -26,9 +22,8 @@ export const metaTabs: WsComponentMeta = { children: ["instance"], descendants: [radix.TabsList, radix.TabsContent], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsTabs, }; export const metaTabsList: WsComponentMeta = { @@ -38,9 +33,8 @@ export const metaTabsList: WsComponentMeta = { children: ["instance"], descendants: [radix.TabsTrigger], }, - presetStyle: { - div, - }, + presetStyle: { div }, + props: propsTabsList, }; export const metaTabsTrigger: WsComponentMeta = { @@ -62,6 +56,7 @@ export const metaTabsTrigger: WsComponentMeta = { presetStyle: { button: [button, buttonReset].flat(), }, + props: propsTabsTrigger, }; export const metaTabsContent: WsComponentMeta = { @@ -72,23 +67,6 @@ export const metaTabsContent: WsComponentMeta = { category: "none", children: ["instance", "rich-text"], }, - presetStyle: { - div, - }, -}; - -export const propsMetaTabs: WsComponentPropsMeta = { - props: propsTabs, -}; - -export const propsMetaTabsList: WsComponentPropsMeta = { - props: propsTabsList, -}; - -export const propsMetaTabsTrigger: WsComponentPropsMeta = { - props: propsTabsTrigger, -}; - -export const propsMetaTabsContent: WsComponentPropsMeta = { + presetStyle: { div }, props: propsTabsContent, }; diff --git a/packages/sdk-components-react-radix/src/tooltip.ws.ts b/packages/sdk-components-react-radix/src/tooltip.ws.ts index 6c8d1af8a635..084d0549de4b 100644 --- a/packages/sdk-components-react-radix/src/tooltip.ws.ts +++ b/packages/sdk-components-react-radix/src/tooltip.ws.ts @@ -1,5 +1,5 @@ import { TooltipIcon, TriggerIcon, ContentIcon } from "@webstudio-is/icons/svg"; -import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk"; +import type { WsComponentMeta } from "@webstudio-is/sdk"; import { div } from "@webstudio-is/sdk/normalize.css"; import { radix } from "./shared/meta"; import { @@ -15,6 +15,7 @@ export const metaTooltipTrigger: WsComponentMeta = { category: "none", children: ["instance"], }, + props: propsTooltipTrigger, }; export const metaTooltipContent: WsComponentMeta = { @@ -23,9 +24,9 @@ export const metaTooltipContent: WsComponentMeta = { category: "none", children: ["instance"], }, - presetStyle: { - div, - }, + presetStyle: { div }, + initialProps: ["side", "sideOffset", "align", "alignOffset"], + props: propsTooltipContent, }; export const metaTooltip: WsComponentMeta = { @@ -35,18 +36,6 @@ export const metaTooltip: WsComponentMeta = { children: ["instance"], descendants: [radix.TooltipTrigger, radix.TooltipContent], }, -}; - -export const propsMetaTooltip: WsComponentPropsMeta = { - props: propsTooltip, initialProps: ["open", "delayDuration", "disableHoverableContent"], -}; - -export const propsMetaTooltipTrigger: WsComponentPropsMeta = { - props: propsTooltipTrigger, -}; - -export const propsMetaTooltipContent: WsComponentPropsMeta = { - props: propsTooltipContent, - initialProps: ["side", "sideOffset", "align", "alignOffset"], + props: propsTooltip, }; diff --git a/packages/sdk/src/schema/component-meta.ts b/packages/sdk/src/schema/component-meta.ts index 8a334bedc3e7..9995577d9a35 100644 --- a/packages/sdk/src/schema/component-meta.ts +++ b/packages/sdk/src/schema/component-meta.ts @@ -109,6 +109,9 @@ export const WsComponentMeta = z.object({ presetStyle: z.optional(z.record(z.string(), z.array(PresetStyleDecl))), states: z.optional(z.array(ComponentState)), order: z.number().optional(), + // properties and html attributes that will be always visible in properties panel + initialProps: z.array(z.string()).optional(), + props: z.record(PropMeta).optional(), }); export type WsComponentMeta = Omit< From deb02c458543c352cc57c7098d61655dd2af9b7f Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Fri, 16 May 2025 17:12:16 +0300 Subject: [PATCH 2/2] Fix import --- apps/builder/app/canvas/canvas.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/builder/app/canvas/canvas.tsx b/apps/builder/app/canvas/canvas.tsx index b24632391b52..41fd172d61c2 100644 --- a/apps/builder/app/canvas/canvas.tsx +++ b/apps/builder/app/canvas/canvas.tsx @@ -18,7 +18,6 @@ import * as animationTemplates from "@webstudio-is/sdk-components-animation/temp import { hooks as animationComponentHooks } from "@webstudio-is/sdk-components-animation/hooks"; import * as radixComponents from "@webstudio-is/sdk-components-react-radix"; import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas"; -import * as radixComponentPropsMetas from "@webstudio-is/sdk-components-react-radix/props"; import * as radixTemplates from "@webstudio-is/sdk-components-react-radix/templates"; import { hooks as radixComponentHooks } from "@webstudio-is/sdk-components-react-radix/hooks"; import { ErrorMessage } from "~/shared/error"; @@ -267,7 +266,7 @@ export const Canvas = () => { namespace: "@webstudio-is/sdk-components-react-radix", components: radixComponents, metas: radixComponentMetas, - propsMetas: radixComponentPropsMetas, + propsMetas: {}, hooks: radixComponentHooks, templates: radixTemplates, });