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/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, }); 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<