@webstudio-is/sdk-components-react-radix 0.85.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/lib/__generated__/accordion.props.js +2134 -0
  2. package/lib/__generated__/button.props.js +454 -0
  3. package/lib/__generated__/dialog.props.js +0 -7
  4. package/lib/__generated__/input.props.js +451 -0
  5. package/lib/__generated__/label.props.js +421 -0
  6. package/lib/__generated__/popover.props.js +0 -7
  7. package/lib/__generated__/sheet.props.js +0 -7
  8. package/lib/__generated__/textarea.props.js +431 -0
  9. package/lib/__generated__/tooltip.props.js +0 -7
  10. package/lib/accordion.js +51 -0
  11. package/lib/accordion.ws.js +243 -0
  12. package/lib/button.js +8 -0
  13. package/lib/button.ws.js +133 -0
  14. package/lib/cjs/__generated__/accordion.props.js +2154 -0
  15. package/lib/cjs/__generated__/button.props.js +474 -0
  16. package/lib/cjs/__generated__/dialog.props.js +0 -7
  17. package/lib/cjs/__generated__/input.props.js +471 -0
  18. package/lib/cjs/__generated__/label.props.js +441 -0
  19. package/lib/cjs/__generated__/popover.props.js +0 -7
  20. package/lib/cjs/__generated__/sheet.props.js +0 -7
  21. package/lib/cjs/__generated__/textarea.props.js +451 -0
  22. package/lib/cjs/__generated__/tooltip.props.js +0 -7
  23. package/lib/cjs/accordion.js +60 -0
  24. package/lib/cjs/accordion.ws.js +261 -0
  25. package/lib/cjs/button.js +28 -0
  26. package/lib/cjs/button.ws.js +160 -0
  27. package/lib/cjs/collapsible.js +2 -16
  28. package/lib/cjs/collapsible.ws.js +1 -8
  29. package/lib/cjs/components.js +14 -0
  30. package/lib/cjs/dialog.js +38 -6
  31. package/lib/cjs/dialog.ws.js +15 -26
  32. package/lib/cjs/hooks.js +15 -1
  33. package/lib/cjs/input.js +28 -0
  34. package/lib/cjs/input.ws.js +103 -0
  35. package/lib/cjs/label.js +37 -0
  36. package/lib/cjs/label.ws.js +74 -0
  37. package/lib/cjs/metas.js +14 -0
  38. package/lib/cjs/popover.js +37 -5
  39. package/lib/cjs/popover.ws.js +15 -18
  40. package/lib/cjs/props.js +14 -0
  41. package/lib/cjs/sheet.js +34 -1
  42. package/lib/cjs/sheet.ws.js +33 -19
  43. package/lib/cjs/tabs.js +20 -1
  44. package/lib/cjs/tabs.ws.js +3 -25
  45. package/lib/cjs/textarea.js +28 -0
  46. package/lib/cjs/textarea.ws.js +98 -0
  47. package/lib/cjs/theme/tailwind-classes.js +186 -23
  48. package/lib/cjs/theme/tailwind-colors.js +10 -1
  49. package/lib/cjs/tooltip.js +36 -4
  50. package/lib/cjs/tooltip.ws.js +15 -18
  51. package/lib/collapsible.js +2 -16
  52. package/lib/collapsible.ws.js +1 -8
  53. package/lib/components.js +20 -0
  54. package/lib/dialog.js +38 -6
  55. package/lib/dialog.ws.js +15 -26
  56. package/lib/hooks.js +15 -1
  57. package/lib/input.js +8 -0
  58. package/lib/input.ws.js +75 -0
  59. package/lib/label.js +9 -0
  60. package/lib/label.ws.js +46 -0
  61. package/lib/metas.js +20 -0
  62. package/lib/popover.js +37 -5
  63. package/lib/popover.ws.js +15 -18
  64. package/lib/props.js +20 -0
  65. package/lib/sheet.js +34 -1
  66. package/lib/sheet.ws.js +33 -19
  67. package/lib/tabs.js +24 -2
  68. package/lib/tabs.ws.js +3 -25
  69. package/lib/textarea.js +8 -0
  70. package/lib/textarea.ws.js +70 -0
  71. package/lib/theme/tailwind-classes.js +191 -24
  72. package/lib/theme/tailwind-colors.js +10 -1
  73. package/lib/tooltip.js +36 -4
  74. package/lib/tooltip.ws.js +15 -18
  75. package/lib/types/__generated__/accordion.props.d.ts +6 -0
  76. package/lib/types/__generated__/button.props.d.ts +2 -0
  77. package/lib/types/__generated__/input.props.d.ts +2 -0
  78. package/lib/types/__generated__/label.props.d.ts +2 -0
  79. package/lib/types/__generated__/textarea.props.d.ts +2 -0
  80. package/lib/types/accordion.d.ts +12 -0
  81. package/lib/types/accordion.ws.d.ts +11 -0
  82. package/lib/types/button.d.ts +7 -0
  83. package/lib/types/button.stories.d.ts +20 -0
  84. package/lib/types/button.ws.d.ts +7 -0
  85. package/lib/types/components.d.ts +5 -0
  86. package/lib/types/dialog.d.ts +5 -11
  87. package/lib/types/input.d.ts +2 -0
  88. package/lib/types/input.stories.d.ts +20 -0
  89. package/lib/types/input.ws.d.ts +3 -0
  90. package/lib/types/label.d.ts +3 -0
  91. package/lib/types/label.stories.d.ts +9 -0
  92. package/lib/types/label.ws.d.ts +3 -0
  93. package/lib/types/metas.d.ts +5 -0
  94. package/lib/types/popover.d.ts +4 -10
  95. package/lib/types/props.d.ts +5 -0
  96. package/lib/types/sheet.d.ts +4 -4
  97. package/lib/types/tabs.d.ts +2 -0
  98. package/lib/types/textarea.d.ts +2 -0
  99. package/lib/types/textarea.stories.d.ts +14 -0
  100. package/lib/types/textarea.ws.d.ts +3 -0
  101. package/lib/types/theme/tailwind-classes.d.ts +16 -5
  102. package/lib/types/theme/tailwind-colors.d.ts +9 -0
  103. package/lib/types/tooltip.d.ts +3 -9
  104. package/package.json +9 -7
  105. package/src/__generated__/accordion.props.ts +2382 -0
  106. package/src/__generated__/button.props.ts +503 -0
  107. package/src/__generated__/dialog.props.ts +0 -7
  108. package/src/__generated__/input.props.ts +500 -0
  109. package/src/__generated__/label.props.ts +470 -0
  110. package/src/__generated__/popover.props.ts +0 -7
  111. package/src/__generated__/sheet.props.ts +0 -7
  112. package/src/__generated__/textarea.props.ts +480 -0
  113. package/src/__generated__/tooltip.props.ts +0 -7
  114. package/src/accordion.stories.tsx +21 -0
  115. package/src/accordion.tsx +81 -0
  116. package/src/accordion.ws.ts +270 -0
  117. package/src/button.stories.ts +35 -0
  118. package/src/button.tsx +25 -0
  119. package/src/button.ws.ts +155 -0
  120. package/src/collapsible.tsx +2 -16
  121. package/src/collapsible.ws.ts +1 -8
  122. package/src/components.ts +11 -0
  123. package/src/dialog.stories.tsx +21 -0
  124. package/src/dialog.tsx +50 -24
  125. package/src/dialog.ws.tsx +15 -26
  126. package/src/hooks.ts +15 -1
  127. package/src/input.stories.ts +31 -0
  128. package/src/input.tsx +12 -0
  129. package/src/input.ws.ts +78 -0
  130. package/src/label.stories.ts +22 -0
  131. package/src/label.tsx +15 -0
  132. package/src/label.ws.ts +48 -0
  133. package/src/metas.ts +11 -0
  134. package/src/popover.stories.tsx +21 -0
  135. package/src/popover.tsx +49 -23
  136. package/src/popover.ws.tsx +15 -18
  137. package/src/props.ts +11 -0
  138. package/src/sheet.tsx +39 -0
  139. package/src/sheet.ws.tsx +33 -19
  140. package/src/tabs.tsx +32 -1
  141. package/src/tabs.ws.ts +1 -23
  142. package/src/textarea.stories.ts +27 -0
  143. package/src/textarea.tsx +12 -0
  144. package/src/textarea.ws.ts +74 -0
  145. package/src/theme/tailwind-classes.ts +233 -38
  146. package/src/theme/tailwind-colors.ts +9 -16
  147. package/src/tooltip.stories.tsx +21 -0
  148. package/src/tooltip.tsx +46 -20
  149. package/src/tooltip.ws.tsx +15 -18
package/src/dialog.ws.tsx CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  propsDialogTitle,
23
23
  propsDialogDescription,
24
24
  } from "./__generated__/dialog.props";
25
+ import { template as buttonTemplate } from "./button.ws";
25
26
 
26
27
  import { div, button, h2, p } from "@webstudio-is/react-sdk/css-normalize";
27
28
 
@@ -44,9 +45,7 @@ const descriptionPresetStyle = {
44
45
  // @todo add [data-state] to button and link
45
46
  export const metaDialogTrigger: WsComponentMeta = {
46
47
  category: "hidden",
47
- invalidAncestors: [],
48
48
  type: "container",
49
- label: "Dialog Trigger",
50
49
  icon: TriggerIcon,
51
50
  stylable: false,
52
51
  detachable: false,
@@ -54,9 +53,7 @@ export const metaDialogTrigger: WsComponentMeta = {
54
53
 
55
54
  export const metaDialogContent: WsComponentMeta = {
56
55
  category: "hidden",
57
- invalidAncestors: [],
58
56
  type: "container",
59
- label: "Dialog Content",
60
57
  presetStyle,
61
58
  icon: ContentIcon,
62
59
  detachable: false,
@@ -64,9 +61,7 @@ export const metaDialogContent: WsComponentMeta = {
64
61
 
65
62
  export const metaDialogOverlay: WsComponentMeta = {
66
63
  category: "hidden",
67
- invalidAncestors: [],
68
64
  type: "container",
69
- label: "Dialog Overlay",
70
65
  presetStyle,
71
66
  icon: OverlayIcon,
72
67
  detachable: false,
@@ -74,28 +69,22 @@ export const metaDialogOverlay: WsComponentMeta = {
74
69
 
75
70
  export const metaDialogTitle: WsComponentMeta = {
76
71
  category: "hidden",
77
- invalidAncestors: [],
78
72
  type: "container",
79
73
  presetStyle: titlePresetStyle,
80
- label: "Dialog Title",
81
74
  icon: HeadingIcon,
82
75
  };
83
76
 
84
77
  export const metaDialogDescription: WsComponentMeta = {
85
78
  category: "hidden",
86
- invalidAncestors: [],
87
79
  type: "container",
88
80
  presetStyle: descriptionPresetStyle,
89
- label: "Dialog Description",
90
81
  icon: TextIcon,
91
82
  };
92
83
 
93
84
  export const metaDialogClose: WsComponentMeta = {
94
85
  category: "hidden",
95
- invalidAncestors: [],
96
86
  type: "container",
97
87
  presetStyle: buttonPresetStyle,
98
- label: "Dialog Close",
99
88
  icon: ButtonElementIcon,
100
89
  };
101
90
 
@@ -109,9 +98,7 @@ export const metaDialogClose: WsComponentMeta = {
109
98
  **/
110
99
  export const metaDialog: WsComponentMeta = {
111
100
  category: "radix",
112
- invalidAncestors: [],
113
101
  type: "container",
114
- label: "Dialog",
115
102
  icon: DialogIcon,
116
103
  order: 15,
117
104
  stylable: false,
@@ -120,14 +107,20 @@ export const metaDialog: WsComponentMeta = {
120
107
  type: "instance",
121
108
  component: "Dialog",
122
109
  dataSources: {
123
- // We don't have support for boolean or undefined, instead of binding on open we bind on a string
124
- isOpen: { type: "variable", initialValue: "initial" },
110
+ dialogOpen: { type: "variable", initialValue: false },
125
111
  },
126
112
  props: [
127
113
  {
128
114
  type: "dataSource",
129
- name: "isOpen",
130
- dataSourceName: "isOpen",
115
+ name: "open",
116
+ dataSourceName: "dialogOpen",
117
+ },
118
+ {
119
+ name: "onOpenChange",
120
+ type: "action",
121
+ value: [
122
+ { type: "execute", args: ["open"], code: `dialogOpen = open` },
123
+ ],
131
124
  },
132
125
  ],
133
126
  children: [
@@ -135,13 +128,9 @@ export const metaDialog: WsComponentMeta = {
135
128
  type: "instance",
136
129
  component: "DialogTrigger",
137
130
  props: [],
138
- children: [
139
- {
140
- type: "instance",
141
- component: "Button",
142
- children: [{ type: "text", value: "Button" }],
143
- },
144
- ],
131
+ children: buttonTemplate({
132
+ children: [{ type: "text", value: "Button" }],
133
+ }),
145
134
  },
146
135
  {
147
136
  type: "instance",
@@ -282,7 +271,7 @@ export const metaDialog: WsComponentMeta = {
282
271
 
283
272
  export const propsMetaDialog: WsComponentPropsMeta = {
284
273
  props: propsDialog,
285
- initialProps: ["isOpen", "modal"],
274
+ initialProps: ["open", "modal"],
286
275
  };
287
276
 
288
277
  export const propsMetaDialogTrigger: WsComponentPropsMeta = {
package/src/hooks.ts CHANGED
@@ -1,4 +1,18 @@
1
1
  import type { Hook } from "@webstudio-is/react-sdk";
2
2
  import { hooksCollapsible } from "./collapsible";
3
+ import { hooksTabs } from "./tabs";
4
+ import { hooksDialog } from "./dialog";
5
+ import { hooksPopover } from "./popover";
6
+ import { hooksSheet } from "./sheet";
7
+ import { hooksTooltip } from "./tooltip";
8
+ import { hooksAccordion } from "./accordion";
3
9
 
4
- export const hooks: Hook[] = [hooksCollapsible];
10
+ export const hooks: Hook[] = [
11
+ hooksCollapsible,
12
+ hooksTabs,
13
+ hooksDialog,
14
+ hooksPopover,
15
+ hooksSheet,
16
+ hooksTooltip,
17
+ hooksAccordion,
18
+ ];
@@ -0,0 +1,31 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { renderComponentTemplate } from "@webstudio-is/react-sdk";
3
+ import { Input as InputPrimitive } from "./input";
4
+ import * as baseComponents from "@webstudio-is/sdk-components-react";
5
+ import * as baseMetas from "@webstudio-is/sdk-components-react/metas";
6
+ import * as radixComponents from "./components";
7
+ import * as radixMetas from "./metas";
8
+
9
+ export default {
10
+ title: "Components/Input",
11
+ component: InputPrimitive,
12
+ argTypes: {
13
+ placeholder: {
14
+ type: "string",
15
+ },
16
+ type: {
17
+ options: ["text", "file"],
18
+ control: { type: "select" },
19
+ },
20
+ },
21
+ } satisfies Meta<typeof InputPrimitive>;
22
+
23
+ export const Input: StoryObj<typeof InputPrimitive> = {
24
+ render: (props) =>
25
+ renderComponentTemplate({
26
+ name: "Input",
27
+ props: { ...props },
28
+ components: { ...baseComponents, ...radixComponents },
29
+ metas: { ...baseMetas, ...radixMetas },
30
+ }),
31
+ };
package/src/input.tsx ADDED
@@ -0,0 +1,12 @@
1
+ /* eslint-disable react/display-name */
2
+ // We can't use .displayName until this is merged https://github.com/styleguidist/react-docgen-typescript/pull/449
3
+
4
+ import { forwardRef, type ComponentPropsWithoutRef } from "react";
5
+
6
+ export const Input = forwardRef<
7
+ HTMLInputElement,
8
+ ComponentPropsWithoutRef<"input">
9
+ // Make sure children are not passed down to an input, because this will result in error.
10
+ >(({ children: _children, ...props }, ref) => {
11
+ return <input ref={ref} {...props} />;
12
+ });
@@ -0,0 +1,78 @@
1
+ import { FormTextFieldIcon } from "@webstudio-is/icons/svg";
2
+ import {
3
+ defaultStates,
4
+ type PresetStyle,
5
+ type WsComponentMeta,
6
+ type WsComponentPropsMeta,
7
+ } from "@webstudio-is/react-sdk";
8
+ import { input } from "@webstudio-is/react-sdk/css-normalize";
9
+ import { props } from "./__generated__/input.props";
10
+ import * as tc from "./theme/tailwind-classes";
11
+
12
+ const presetStyle = {
13
+ input,
14
+ } satisfies PresetStyle<"input">;
15
+
16
+ export const meta: WsComponentMeta = {
17
+ category: "radix",
18
+ type: "control",
19
+ invalidAncestors: ["Button"],
20
+ icon: FormTextFieldIcon,
21
+ presetStyle,
22
+ states: [
23
+ ...defaultStates,
24
+ { selector: ":disabled", label: "Disabled" },
25
+ { selector: "::placeholder", label: "Placeholder" },
26
+ { selector: "::file-selector-button", label: "File Selector Button" },
27
+ // @todo share https://github.com/webstudio-is/webstudio-builder/issues/2102
28
+ { selector: ":valid", label: "Valid" },
29
+ { selector: ":invalid", label: "Invalid" },
30
+ { selector: ":required", label: "Required" },
31
+ { selector: ":optional", label: "Optional" },
32
+ { selector: ":enabled", label: "Enabled" },
33
+ { selector: ":read-only", label: "Read Only" },
34
+ { selector: ":read-write", label: "Read Write" },
35
+ ],
36
+ order: 1,
37
+ template: [
38
+ {
39
+ type: "instance",
40
+ component: "Input",
41
+ styles: [
42
+ // flex h-10 w-full rounded-md border border-input bg-background
43
+ // px-3 py-2 text-sm
44
+ // ring-offset-background
45
+ // file:border-0 file:bg-transparent file:text-sm file:font-medium
46
+ // placeholder:text-muted-foreground
47
+ // focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
48
+ // disabled:cursor-not-allowed disabled:opacity-50"
49
+ tc.flex(),
50
+ tc.h(10),
51
+ tc.w("full"),
52
+ tc.rounded("md"),
53
+ tc.border(),
54
+ tc.border("input"),
55
+ tc.bg("background"),
56
+ tc.px(3),
57
+ tc.py(2),
58
+ tc.text("sm"),
59
+ tc.state(
60
+ [tc.border(0), tc.bg("transparent"), tc.font("medium")].flat(),
61
+ "::file-selector-button"
62
+ ),
63
+ tc.state(tc.text("mutedForeground"), "::placeholder"),
64
+ tc.focusVisible(
65
+ [tc.outline("none"), tc.ring("ring", 2, "background", 2)].flat()
66
+ ),
67
+ tc.disabled([tc.cursor("not-allowed"), tc.opacity(50)].flat()),
68
+ ].flat(),
69
+
70
+ children: [],
71
+ },
72
+ ],
73
+ };
74
+
75
+ export const propsMeta: WsComponentPropsMeta = {
76
+ props,
77
+ initialProps: ["id", "name", "type", "placeholder", "required", "autoFocus"],
78
+ };
@@ -0,0 +1,22 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { renderComponentTemplate } from "@webstudio-is/react-sdk";
3
+ import { Label as LabelPrimitive } from "./label";
4
+ import * as baseComponents from "@webstudio-is/sdk-components-react";
5
+ import * as baseMetas from "@webstudio-is/sdk-components-react/metas";
6
+ import * as radixComponents from "./components";
7
+ import * as radixMetas from "./metas";
8
+
9
+ export default {
10
+ title: "Components/Label",
11
+ component: LabelPrimitive,
12
+ } satisfies Meta<typeof LabelPrimitive>;
13
+
14
+ export const Label: StoryObj<typeof LabelPrimitive> = {
15
+ render: (props) =>
16
+ renderComponentTemplate({
17
+ name: "Label",
18
+ props: { ...props },
19
+ components: { ...baseComponents, ...radixComponents },
20
+ metas: { ...baseMetas, ...radixMetas },
21
+ }),
22
+ };
package/src/label.tsx ADDED
@@ -0,0 +1,15 @@
1
+ /* eslint-disable react/display-name */
2
+ // We can't use .displayName until this is merged https://github.com/styleguidist/react-docgen-typescript/pull/449
3
+
4
+ import {
5
+ forwardRef,
6
+ type ComponentPropsWithoutRef,
7
+ type ElementRef,
8
+ } from "react";
9
+
10
+ import * as LabelPrimitive from "@radix-ui/react-label";
11
+
12
+ export const Label = forwardRef<
13
+ ElementRef<typeof LabelPrimitive.Root>,
14
+ Omit<ComponentPropsWithoutRef<typeof LabelPrimitive.Root>, "asChild">
15
+ >((props, ref) => <LabelPrimitive.Root ref={ref} {...props} />);
@@ -0,0 +1,48 @@
1
+ import { LabelIcon } from "@webstudio-is/icons/svg";
2
+ import {
3
+ defaultStates,
4
+ type PresetStyle,
5
+ type WsComponentMeta,
6
+ type WsComponentPropsMeta,
7
+ } from "@webstudio-is/react-sdk";
8
+ import { label } from "@webstudio-is/react-sdk/css-normalize";
9
+ import { props } from "./__generated__/label.props";
10
+ import * as tc from "./theme/tailwind-classes";
11
+
12
+ const presetStyle = {
13
+ label,
14
+ } satisfies PresetStyle<"label">;
15
+
16
+ export const meta: WsComponentMeta = {
17
+ category: "radix",
18
+ type: "container",
19
+ icon: LabelIcon,
20
+ presetStyle,
21
+ states: defaultStates,
22
+ order: 1,
23
+ template: [
24
+ {
25
+ type: "instance",
26
+ component: "Label",
27
+ styles: [
28
+ // text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70
29
+ tc.text("sm"),
30
+ tc.font("medium"),
31
+ tc.leading("none"),
32
+ // We are not supporting peer like styles yet
33
+ ].flat(),
34
+ children: [{ type: "text", value: "Form Label" }],
35
+ },
36
+ ],
37
+ };
38
+
39
+ export const propsMeta: WsComponentPropsMeta = {
40
+ props: {
41
+ ...props,
42
+ htmlFor: {
43
+ ...props.htmlFor,
44
+ label: "For",
45
+ },
46
+ },
47
+ initialProps: ["id", "htmlFor"],
48
+ };
package/src/metas.ts CHANGED
@@ -37,3 +37,14 @@ export {
37
37
  metaTabsTrigger as TabsTrigger,
38
38
  metaTabsContent as TabsContent,
39
39
  } from "./tabs.ws";
40
+ export { meta as Button } from "./button.ws";
41
+ export { meta as Input } from "./input.ws";
42
+ export { meta as Textarea } from "./textarea.ws";
43
+ export { meta as Label } from "./label.ws";
44
+ export {
45
+ metaAccordion as Accordion,
46
+ metaAccordionItem as AccordionItem,
47
+ metaAccordionHeader as AccordionHeader,
48
+ metaAccordionTrigger as AccordionTrigger,
49
+ metaAccordionContent as AccordionContent,
50
+ } from "./accordion.ws";
@@ -0,0 +1,21 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { renderComponentTemplate } from "@webstudio-is/react-sdk";
3
+ import { Popover as PopoverPrimitive } from "./popover";
4
+ import * as baseComponents from "@webstudio-is/sdk-components-react";
5
+ import * as baseMetas from "@webstudio-is/sdk-components-react/metas";
6
+ import * as radixComponents from "./components";
7
+ import * as radixMetas from "./metas";
8
+
9
+ export default {
10
+ title: "Components/Popover",
11
+ component: PopoverPrimitive,
12
+ } satisfies Meta<typeof PopoverPrimitive>;
13
+
14
+ export const Popover: StoryObj<typeof PopoverPrimitive> = {
15
+ render: () =>
16
+ renderComponentTemplate({
17
+ name: "Popover",
18
+ components: { ...baseComponents, ...radixComponents },
19
+ metas: { ...baseMetas, ...radixMetas },
20
+ }),
21
+ };
package/src/popover.tsx CHANGED
@@ -1,33 +1,21 @@
1
1
  /* eslint-disable react/display-name */
2
2
  // We can't use .displayName until this is merged https://github.com/styleguidist/react-docgen-typescript/pull/449
3
3
 
4
- import * as PopoverPrimitive from "@radix-ui/react-popover";
5
-
6
4
  import {
7
- forwardRef,
8
- type ElementRef,
9
5
  type ComponentPropsWithoutRef,
10
- Children,
11
6
  type ReactNode,
7
+ forwardRef,
8
+ Children,
12
9
  } from "react";
10
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
11
+ import { getClosestInstance, type Hook } from "@webstudio-is/react-sdk";
13
12
 
14
- /**
15
- * We don't have support for boolean or undefined nor in UI not at Data variables,
16
- * instead of binding on "open" prop we bind variable on a isOpen prop to be able to show Popover in the builder
17
- **/
18
- type BuilderPopoverProps = {
19
- isOpen: "initial" | "open" | "closed";
20
- };
21
-
13
+ // wrap in forwardRef because Root is functional component without ref
22
14
  export const Popover = forwardRef<
23
- ElementRef<"div">,
24
- ComponentPropsWithoutRef<typeof PopoverPrimitive.Root> & BuilderPopoverProps
25
- >(({ open: openProp, isOpen, ...props }, ref) => {
26
- const open =
27
- openProp ??
28
- (isOpen === "open" ? true : isOpen === "closed" ? false : undefined);
29
-
30
- return <PopoverPrimitive.Root open={open} {...props} />;
15
+ HTMLDivElement,
16
+ Omit<ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>, "defaultOpen">
17
+ >((props, _ref) => {
18
+ return <PopoverPrimitive.Root {...props} />;
31
19
  });
32
20
 
33
21
  /**
@@ -37,7 +25,7 @@ export const Popover = forwardRef<
37
25
  * which would prevent us from displaying styles properly in the builder.
38
26
  */
39
27
  export const PopoverTrigger = forwardRef<
40
- ElementRef<"button">,
28
+ HTMLButtonElement,
41
29
  { children: ReactNode }
42
30
  >(({ children, ...props }, ref) => {
43
31
  const firstChild = Children.toArray(children)[0];
@@ -50,7 +38,7 @@ export const PopoverTrigger = forwardRef<
50
38
  });
51
39
 
52
40
  export const PopoverContent = forwardRef<
53
- ElementRef<typeof PopoverPrimitive.Content>,
41
+ HTMLDivElement,
54
42
  ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
55
43
  >(
56
44
  (
@@ -68,3 +56,41 @@ export const PopoverContent = forwardRef<
68
56
  </PopoverPrimitive.Portal>
69
57
  )
70
58
  );
59
+
60
+ /* BUILDER HOOKS */
61
+
62
+ const namespace = "@webstudio-is/sdk-components-react-radix";
63
+
64
+ // For each PopoverContent component within the selection,
65
+ // we identify its closest parent Popover component
66
+ // and update its open prop bound to variable.
67
+ export const hooksPopover: Hook = {
68
+ onNavigatorUnselect: (context, event) => {
69
+ for (const instance of event.instancePath) {
70
+ if (instance.component === `${namespace}:PopoverContent`) {
71
+ const popover = getClosestInstance(
72
+ event.instancePath,
73
+ instance,
74
+ `${namespace}:Popover`
75
+ );
76
+ if (popover) {
77
+ context.setPropVariable(popover.id, "open", false);
78
+ }
79
+ }
80
+ }
81
+ },
82
+ onNavigatorSelect: (context, event) => {
83
+ for (const instance of event.instancePath) {
84
+ if (instance.component === `${namespace}:PopoverContent`) {
85
+ const popover = getClosestInstance(
86
+ event.instancePath,
87
+ instance,
88
+ `${namespace}:Popover`
89
+ );
90
+ if (popover) {
91
+ context.setPropVariable(popover.id, "open", true);
92
+ }
93
+ }
94
+ }
95
+ },
96
+ };
@@ -11,6 +11,7 @@ import {
11
11
  propsPopoverTrigger,
12
12
  } from "./__generated__/popover.props";
13
13
  import { div } from "@webstudio-is/react-sdk/css-normalize";
14
+ import { template as buttonTemplate } from "./button.ws";
14
15
 
15
16
  const presetStyle = {
16
17
  div,
@@ -19,9 +20,7 @@ const presetStyle = {
19
20
  // @todo add [data-state] to button and link
20
21
  export const metaPopoverTrigger: WsComponentMeta = {
21
22
  category: "hidden",
22
- invalidAncestors: [],
23
23
  type: "container",
24
- label: "Popover Trigger",
25
24
  icon: TriggerIcon,
26
25
  stylable: false,
27
26
  detachable: false,
@@ -29,10 +28,8 @@ export const metaPopoverTrigger: WsComponentMeta = {
29
28
 
30
29
  export const metaPopoverContent: WsComponentMeta = {
31
30
  category: "hidden",
32
- invalidAncestors: [],
33
31
  type: "container",
34
32
  presetStyle,
35
- label: "Popover Content",
36
33
  icon: ContentIcon,
37
34
  detachable: false,
38
35
  };
@@ -47,9 +44,7 @@ export const metaPopoverContent: WsComponentMeta = {
47
44
  **/
48
45
  export const metaPopover: WsComponentMeta = {
49
46
  category: "radix",
50
- invalidAncestors: [],
51
47
  type: "container",
52
- label: "Popover",
53
48
  icon: PopoverIcon,
54
49
  order: 15,
55
50
  stylable: false,
@@ -58,14 +53,20 @@ export const metaPopover: WsComponentMeta = {
58
53
  type: "instance",
59
54
  component: "Popover",
60
55
  dataSources: {
61
- // We don't have support for boolean or undefined, instead of binding on open we bind on a string
62
- isOpen: { type: "variable", initialValue: "initial" },
56
+ popoverOpen: { type: "variable", initialValue: false },
63
57
  },
64
58
  props: [
65
59
  {
66
60
  type: "dataSource",
67
- name: "isOpen",
68
- dataSourceName: "isOpen",
61
+ name: "open",
62
+ dataSourceName: "popoverOpen",
63
+ },
64
+ {
65
+ name: "onOpenChange",
66
+ type: "action",
67
+ value: [
68
+ { type: "execute", args: ["open"], code: `popoverOpen = open` },
69
+ ],
69
70
  },
70
71
  ],
71
72
  children: [
@@ -73,13 +74,9 @@ export const metaPopover: WsComponentMeta = {
73
74
  type: "instance",
74
75
  component: "PopoverTrigger",
75
76
  props: [],
76
- children: [
77
- {
78
- type: "instance",
79
- component: "Button",
80
- children: [{ type: "text", value: "Button" }],
81
- },
82
- ],
77
+ children: buttonTemplate({
78
+ children: [{ type: "text", value: "Button" }],
79
+ }),
83
80
  },
84
81
  {
85
82
  type: "instance",
@@ -114,7 +111,7 @@ export const metaPopover: WsComponentMeta = {
114
111
 
115
112
  export const propsMetaPopover: WsComponentPropsMeta = {
116
113
  props: propsPopover,
117
- initialProps: ["isOpen", "modal"],
114
+ initialProps: ["open", "modal"],
118
115
  };
119
116
 
120
117
  export const propsMetaPopoverTrigger: WsComponentPropsMeta = {
package/src/props.ts CHANGED
@@ -37,3 +37,14 @@ export {
37
37
  propsMetaTabsTrigger as TabsTrigger,
38
38
  propsMetaTabsContent as TabsContent,
39
39
  } from "./tabs.ws";
40
+ export { propsMeta as Button } from "./button.ws";
41
+ export { propsMeta as Input } from "./input.ws";
42
+ export { propsMeta as Textarea } from "./textarea.ws";
43
+ export { propsMeta as Label } from "./label.ws";
44
+ export {
45
+ propsMetaAccordion as Accordion,
46
+ propsMetaAccordionItem as AccordionItem,
47
+ propsMetaAccordionHeader as AccordionHeader,
48
+ propsMetaAccordionTrigger as AccordionTrigger,
49
+ propsMetaAccordionContent as AccordionContent,
50
+ } from "./accordion.ws";
package/src/sheet.tsx CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  type ElementRef,
4
4
  type ComponentPropsWithoutRef,
5
5
  } from "react";
6
+ import { getClosestInstance, type Hook } from "@webstudio-is/react-sdk";
6
7
  import * as Dialog from "./dialog";
7
8
 
8
9
  export const Sheet = Dialog.Dialog;
@@ -38,3 +39,41 @@ export const SheetContent = forwardRef<
38
39
  );
39
40
  }
40
41
  );
42
+
43
+ /* BUILDER HOOKS */
44
+
45
+ const namespace = "@webstudio-is/sdk-components-react-radix";
46
+
47
+ // For each SheetOverlay component within the selection,
48
+ // we identify its closest parent Sheet component
49
+ // and update its open prop bound to variable.
50
+ export const hooksSheet: Hook = {
51
+ onNavigatorUnselect: (context, event) => {
52
+ for (const instance of event.instancePath) {
53
+ if (instance.component === `${namespace}:SheetOverlay`) {
54
+ const sheet = getClosestInstance(
55
+ event.instancePath,
56
+ instance,
57
+ `${namespace}:Sheet`
58
+ );
59
+ if (sheet) {
60
+ context.setPropVariable(sheet.id, "open", false);
61
+ }
62
+ }
63
+ }
64
+ },
65
+ onNavigatorSelect: (context, event) => {
66
+ for (const instance of event.instancePath) {
67
+ if (instance.component === `${namespace}:SheetOverlay`) {
68
+ const sheet = getClosestInstance(
69
+ event.instancePath,
70
+ instance,
71
+ `${namespace}:Sheet`
72
+ );
73
+ if (sheet) {
74
+ context.setPropVariable(sheet.id, "open", true);
75
+ }
76
+ }
77
+ }
78
+ },
79
+ };