@webstudio-is/sdk-components-react-radix 0.87.0 → 0.88.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 (182) hide show
  1. package/lib/__generated__/accordion.props.js +0 -5
  2. package/lib/__generated__/button.props.js +0 -21
  3. package/lib/__generated__/checkbox.props.js +850 -0
  4. package/lib/__generated__/collapsible.props.js +0 -2
  5. package/lib/__generated__/dialog.props.js +0 -11
  6. package/lib/__generated__/label.props.js +0 -1
  7. package/lib/__generated__/navigation-menu.props.js +2104 -0
  8. package/lib/__generated__/popover.props.js +0 -3
  9. package/lib/__generated__/radio-group.props.js +1282 -0
  10. package/lib/__generated__/select.props.js +2962 -0
  11. package/lib/__generated__/sheet.props.js +0 -11
  12. package/lib/__generated__/switch.props.js +850 -0
  13. package/lib/__generated__/tabs.props.js +428 -5
  14. package/lib/__generated__/tooltip.props.js +0 -2
  15. package/lib/accordion.js +11 -4
  16. package/lib/accordion.ws.js +87 -72
  17. package/lib/checkbox.js +13 -0
  18. package/lib/checkbox.ws.js +151 -0
  19. package/lib/cjs/__generated__/accordion.props.js +0 -5
  20. package/lib/cjs/__generated__/button.props.js +0 -21
  21. package/lib/cjs/__generated__/checkbox.props.js +870 -0
  22. package/lib/cjs/__generated__/collapsible.props.js +0 -2
  23. package/lib/cjs/__generated__/dialog.props.js +0 -11
  24. package/lib/cjs/__generated__/label.props.js +0 -1
  25. package/lib/cjs/__generated__/navigation-menu.props.js +2124 -0
  26. package/lib/cjs/__generated__/popover.props.js +0 -3
  27. package/lib/cjs/__generated__/radio-group.props.js +1302 -0
  28. package/lib/cjs/__generated__/select.props.js +2982 -0
  29. package/lib/cjs/__generated__/sheet.props.js +0 -11
  30. package/lib/cjs/__generated__/switch.props.js +870 -0
  31. package/lib/cjs/__generated__/tabs.props.js +428 -5
  32. package/lib/cjs/__generated__/tooltip.props.js +0 -2
  33. package/lib/cjs/accordion.js +11 -4
  34. package/lib/cjs/accordion.ws.js +85 -71
  35. package/lib/cjs/{textarea.js → checkbox.js} +9 -6
  36. package/lib/cjs/checkbox.ws.js +172 -0
  37. package/lib/cjs/collapsible.ws.js +4 -1
  38. package/lib/cjs/components.js +27 -14
  39. package/lib/cjs/dialog.ws.js +17 -17
  40. package/lib/cjs/hooks.js +5 -1
  41. package/lib/cjs/label.ws.js +1 -1
  42. package/lib/cjs/metas.js +29 -14
  43. package/lib/cjs/navigation-menu.js +107 -0
  44. package/lib/cjs/navigation-menu.ws.js +513 -0
  45. package/lib/cjs/popover.ws.js +12 -9
  46. package/lib/cjs/props.js +27 -14
  47. package/lib/cjs/{button.js → radio-group.js} +10 -8
  48. package/lib/cjs/radio-group.ws.js +188 -0
  49. package/lib/cjs/select.js +81 -0
  50. package/lib/cjs/select.ws.js +349 -0
  51. package/lib/cjs/sheet.ws.js +87 -176
  52. package/lib/cjs/{input.js → switch.js} +8 -9
  53. package/lib/cjs/switch.ws.js +171 -0
  54. package/lib/cjs/tabs.js +2 -3
  55. package/lib/cjs/tabs.ws.js +13 -18
  56. package/lib/cjs/theme/styles.js +100 -0
  57. package/lib/cjs/theme/tailwind-classes.js +125 -16
  58. package/lib/cjs/theme/tailwind-colors.js +1 -0
  59. package/lib/cjs/tooltip.ws.js +11 -8
  60. package/lib/collapsible.ws.js +4 -1
  61. package/lib/components.js +44 -22
  62. package/lib/dialog.ws.js +17 -17
  63. package/lib/hooks.js +5 -1
  64. package/lib/label.ws.js +1 -1
  65. package/lib/metas.js +58 -24
  66. package/lib/navigation-menu.js +85 -0
  67. package/lib/navigation-menu.ws.js +500 -0
  68. package/lib/popover.ws.js +12 -9
  69. package/lib/props.js +56 -24
  70. package/lib/radio-group.js +11 -0
  71. package/lib/radio-group.ws.js +170 -0
  72. package/lib/select.js +73 -0
  73. package/lib/select.ws.js +337 -0
  74. package/lib/sheet.ws.js +88 -194
  75. package/lib/switch.js +7 -0
  76. package/lib/switch.ws.js +143 -0
  77. package/lib/tabs.js +3 -5
  78. package/lib/tabs.ws.js +14 -19
  79. package/lib/theme/styles.js +70 -0
  80. package/lib/theme/tailwind-classes.js +125 -16
  81. package/lib/theme/tailwind-colors.js +1 -0
  82. package/lib/tooltip.ws.js +11 -8
  83. package/lib/types/__generated__/checkbox.props.d.ts +3 -0
  84. package/lib/types/__generated__/navigation-menu.props.d.ts +8 -0
  85. package/lib/types/__generated__/radio-group.props.d.ts +4 -0
  86. package/lib/types/__generated__/select.props.d.ts +9 -0
  87. package/lib/types/__generated__/switch.props.d.ts +3 -0
  88. package/lib/types/checkbox.d.ts +6 -0
  89. package/lib/types/checkbox.stories.d.ts +11 -0
  90. package/lib/types/checkbox.ws.d.ts +5 -0
  91. package/lib/types/components.d.ts +5 -4
  92. package/lib/types/metas.d.ts +6 -4
  93. package/lib/types/navigation-menu.d.ts +15 -0
  94. package/lib/types/navigation-menu.ws.d.ts +15 -0
  95. package/lib/types/props.d.ts +5 -4
  96. package/lib/types/radio-group.d.ts +5 -0
  97. package/lib/types/radio-group.stories.d.ts +9 -0
  98. package/lib/types/radio-group.ws.d.ts +7 -0
  99. package/lib/types/select.d.ts +12 -0
  100. package/lib/types/select.ws.d.ts +17 -0
  101. package/lib/types/sheet.ws.d.ts +2 -15
  102. package/lib/types/switch.d.ts +4 -0
  103. package/lib/types/switch.stories.d.ts +9 -0
  104. package/lib/types/switch.ws.d.ts +5 -0
  105. package/lib/types/tabs.d.ts +3 -12
  106. package/lib/types/theme/radix-common-types.d.ts +3 -2
  107. package/lib/types/theme/styles.d.ts +215 -0
  108. package/lib/types/theme/tailwind-classes.d.ts +16 -6
  109. package/lib/types/theme/tailwind-colors.d.ts +1 -0
  110. package/lib/types/theme/tailwind-theme.d.ts +1 -1
  111. package/package.json +12 -7
  112. package/src/__generated__/accordion.props.ts +0 -5
  113. package/src/__generated__/button.props.ts +0 -21
  114. package/src/__generated__/checkbox.props.ts +948 -0
  115. package/src/__generated__/collapsible.props.ts +0 -2
  116. package/src/__generated__/dialog.props.ts +0 -11
  117. package/src/__generated__/label.props.ts +0 -1
  118. package/src/__generated__/navigation-menu.props.ts +2349 -0
  119. package/src/__generated__/popover.props.ts +0 -3
  120. package/src/__generated__/radio-group.props.ts +1429 -0
  121. package/src/__generated__/select.props.ts +3304 -0
  122. package/src/__generated__/sheet.props.ts +0 -11
  123. package/src/__generated__/switch.props.ts +948 -0
  124. package/src/__generated__/tabs.props.ts +477 -4
  125. package/src/__generated__/tooltip.props.ts +0 -2
  126. package/src/accordion.tsx +14 -7
  127. package/src/accordion.ws.ts +85 -70
  128. package/src/{textarea.stories.ts → checkbox.stories.ts} +6 -11
  129. package/src/checkbox.tsx +22 -0
  130. package/src/checkbox.ws.ts +151 -0
  131. package/src/collapsible.ws.ts +4 -1
  132. package/src/components.ts +25 -12
  133. package/src/dialog.ws.tsx +15 -16
  134. package/src/hooks.ts +4 -0
  135. package/src/label.ws.ts +1 -1
  136. package/src/metas.ts +36 -12
  137. package/src/navigation-menu.stories.tsx +21 -0
  138. package/src/navigation-menu.tsx +130 -0
  139. package/src/navigation-menu.ws.ts +523 -0
  140. package/src/popover.ws.tsx +12 -9
  141. package/src/props.ts +35 -12
  142. package/src/{input.stories.ts → radio-group.stories.ts} +6 -15
  143. package/src/radio-group.tsx +17 -0
  144. package/src/radio-group.ws.ts +174 -0
  145. package/src/select.stories.tsx +21 -0
  146. package/src/select.tsx +107 -0
  147. package/src/select.ws.ts +347 -0
  148. package/src/sheet.ws.tsx +89 -209
  149. package/src/{button.stories.ts → switch.stories.ts} +6 -19
  150. package/src/switch.tsx +10 -0
  151. package/src/switch.ws.ts +143 -0
  152. package/src/tabs.tsx +4 -17
  153. package/src/tabs.ws.ts +17 -19
  154. package/src/theme/radix-common-types.ts +3 -2
  155. package/src/theme/styles.ts +80 -0
  156. package/src/theme/tailwind-classes.ts +150 -14
  157. package/src/theme/tailwind-colors.ts +1 -0
  158. package/src/tooltip.ws.tsx +11 -8
  159. package/lib/button.js +0 -8
  160. package/lib/button.ws.js +0 -133
  161. package/lib/cjs/button.ws.js +0 -160
  162. package/lib/cjs/input.ws.js +0 -103
  163. package/lib/cjs/textarea.ws.js +0 -98
  164. package/lib/input.js +0 -8
  165. package/lib/input.ws.js +0 -75
  166. package/lib/textarea.js +0 -8
  167. package/lib/textarea.ws.js +0 -70
  168. package/lib/types/button.d.ts +0 -7
  169. package/lib/types/button.stories.d.ts +0 -20
  170. package/lib/types/button.ws.d.ts +0 -7
  171. package/lib/types/input.d.ts +0 -2
  172. package/lib/types/input.stories.d.ts +0 -20
  173. package/lib/types/input.ws.d.ts +0 -3
  174. package/lib/types/textarea.d.ts +0 -2
  175. package/lib/types/textarea.stories.d.ts +0 -14
  176. package/lib/types/textarea.ws.d.ts +0 -3
  177. package/src/button.tsx +0 -25
  178. package/src/button.ws.ts +0 -155
  179. package/src/input.tsx +0 -12
  180. package/src/input.ws.ts +0 -78
  181. package/src/textarea.tsx +0 -12
  182. package/src/textarea.ws.ts +0 -74
@@ -0,0 +1,174 @@
1
+ import {
2
+ ItemIcon,
3
+ RadioCheckedIcon,
4
+ RadioDotIcon,
5
+ TriggerIcon,
6
+ } from "@webstudio-is/icons/svg";
7
+ import {
8
+ defaultStates,
9
+ WsEmbedTemplate,
10
+ type WsComponentMeta,
11
+ type WsComponentPropsMeta,
12
+ } from "@webstudio-is/react-sdk";
13
+ import { button, div, span } from "@webstudio-is/react-sdk/css-normalize";
14
+ import * as tc from "./theme/tailwind-classes";
15
+ import { buttonReset } from "./theme/styles";
16
+ import {
17
+ propsRadioGroup,
18
+ propsRadioGroupIndicator,
19
+ propsRadioGroupItem,
20
+ } from "./__generated__/radio-group.props";
21
+
22
+ const createRadioGroupItem = ({
23
+ value,
24
+ label,
25
+ }: {
26
+ value: string;
27
+ label: string;
28
+ }): WsEmbedTemplate[number] => ({
29
+ type: "instance",
30
+ component: "Label",
31
+ // flex items-center space-x-2
32
+ styles: [tc.flex(), tc.items("center"), tc.gap(2)].flat(),
33
+ children: [
34
+ {
35
+ type: "instance",
36
+ component: "RadioGroupItem",
37
+ props: [{ name: "value", type: "string", value }],
38
+ // aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background
39
+ // focus:outline-none
40
+ // focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
41
+ // disabled:cursor-not-allowed disabled:opacity-50
42
+ styles: [
43
+ tc.aspect("square"),
44
+ tc.h(4),
45
+ tc.w(4),
46
+ tc.rounded("full"),
47
+ tc.border(),
48
+ tc.border("primary"),
49
+ tc.text("primary"),
50
+ tc.focusVisible(
51
+ [tc.outline("none"), tc.ring("ring", 2, "background", 2)].flat()
52
+ ),
53
+ tc.disabled([tc.cursor("not-allowed"), tc.opacity(50)].flat()),
54
+ ].flat(),
55
+ children: [
56
+ {
57
+ type: "instance",
58
+ component: "RadioGroupIndicator",
59
+ children: [
60
+ {
61
+ type: "instance",
62
+ component: "HtmlEmbed",
63
+ label: "Indicator Icon",
64
+ props: [
65
+ {
66
+ type: "string",
67
+ name: "code",
68
+ value: RadioDotIcon,
69
+ },
70
+ ],
71
+ children: [],
72
+ },
73
+ ],
74
+ },
75
+ ],
76
+ },
77
+ {
78
+ type: "instance",
79
+ component: "Text",
80
+ children: [{ type: "text", value: label }],
81
+ },
82
+ ],
83
+ });
84
+
85
+ export const metaRadioGroup: WsComponentMeta = {
86
+ category: "radix",
87
+ order: 100,
88
+ type: "container",
89
+ icon: RadioCheckedIcon,
90
+ states: [
91
+ ...defaultStates,
92
+ {
93
+ label: "Checked",
94
+ selector: "[data-state=checked]",
95
+ category: "component-states",
96
+ },
97
+ {
98
+ label: "Unchecked",
99
+ selector: "[data-state=unchecked]",
100
+ category: "component-states",
101
+ },
102
+ ],
103
+ presetStyle: {
104
+ div,
105
+ },
106
+ template: [
107
+ {
108
+ type: "instance",
109
+ component: "RadioGroup",
110
+ dataSources: {
111
+ radioGroupValue: { type: "variable", initialValue: "" },
112
+ },
113
+ // grid gap-2
114
+ styles: [tc.flex(), tc.flex("col"), tc.gap(2)].flat(),
115
+ props: [
116
+ {
117
+ type: "dataSource",
118
+ name: "value",
119
+ dataSourceName: "radioGroupValue",
120
+ },
121
+ {
122
+ name: "onValueChange",
123
+ type: "action",
124
+ value: [
125
+ {
126
+ type: "execute",
127
+ args: ["value"],
128
+ code: `radioGroupValue = value`,
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ children: [
134
+ createRadioGroupItem({ value: "default", label: "Default" }),
135
+ createRadioGroupItem({ value: "comfortable", label: "Comfortable" }),
136
+ createRadioGroupItem({ value: "compact", label: "Compact" }),
137
+ ],
138
+ },
139
+ ],
140
+ };
141
+
142
+ export const metaRadioGroupItem: WsComponentMeta = {
143
+ category: "hidden",
144
+ type: "container",
145
+ icon: ItemIcon,
146
+ states: defaultStates,
147
+ presetStyle: {
148
+ button: [button, buttonReset].flat(),
149
+ },
150
+ };
151
+
152
+ export const metaRadioGroupIndicator: WsComponentMeta = {
153
+ category: "hidden",
154
+ type: "container",
155
+ icon: TriggerIcon,
156
+ states: defaultStates,
157
+ presetStyle: {
158
+ span,
159
+ },
160
+ };
161
+
162
+ export const propsMetaRadioGroup: WsComponentPropsMeta = {
163
+ props: propsRadioGroup,
164
+ initialProps: ["id", "value", "name", "required"],
165
+ };
166
+
167
+ export const propsMetaRadioGroupItem: WsComponentPropsMeta = {
168
+ props: propsRadioGroupItem,
169
+ initialProps: ["value"],
170
+ };
171
+
172
+ export const propsMetaRadioGroupIndicator: WsComponentPropsMeta = {
173
+ props: propsRadioGroupIndicator,
174
+ };
@@ -0,0 +1,21 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { renderComponentTemplate } from "@webstudio-is/react-sdk";
3
+ import { Select as SelectPrimitive } from "./select";
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/Select",
11
+ component: SelectPrimitive,
12
+ } satisfies Meta<typeof SelectPrimitive>;
13
+
14
+ export const Select: StoryObj<typeof SelectPrimitive> = {
15
+ render: () =>
16
+ renderComponentTemplate({
17
+ name: "Select",
18
+ components: { ...baseComponents, ...radixComponents },
19
+ metas: { ...baseMetas, ...radixMetas },
20
+ }),
21
+ };
package/src/select.tsx ADDED
@@ -0,0 +1,107 @@
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
+ type ForwardRefExoticComponent,
6
+ type ComponentPropsWithRef,
7
+ type ComponentPropsWithoutRef,
8
+ forwardRef,
9
+ } from "react";
10
+ import {
11
+ Root,
12
+ Value,
13
+ Trigger,
14
+ Content,
15
+ Item,
16
+ ItemIndicator,
17
+ ItemText,
18
+ Portal,
19
+ Viewport,
20
+ } from "@radix-ui/react-select";
21
+ import { type Hook, getClosestInstance } from "@webstudio-is/react-sdk";
22
+
23
+ // wrap in forwardRef because Root is functional component without ref
24
+ export const Select = forwardRef<
25
+ HTMLDivElement,
26
+ ComponentPropsWithoutRef<typeof Root>
27
+ >(({ value, ...props }, _ref) => {
28
+ // radix consider empty string as empty value since this change but not released yet
29
+ // https://github.com/radix-ui/primitives/commit/a3dadb0a825524dd60629d426538dac74930791a
30
+ if (value === "") {
31
+ value = undefined;
32
+ }
33
+ return <Root value={value} {...props} />;
34
+ });
35
+
36
+ export const SelectTrigger: ForwardRefExoticComponent<
37
+ ComponentPropsWithRef<typeof Trigger>
38
+ > = Trigger;
39
+
40
+ export const SelectValue: ForwardRefExoticComponent<
41
+ ComponentPropsWithRef<typeof Value>
42
+ > = Value;
43
+
44
+ export const SelectContent = forwardRef<
45
+ HTMLDivElement,
46
+ Omit<ComponentPropsWithoutRef<typeof Content>, "position" | "side">
47
+ >((props, ref) => {
48
+ return (
49
+ <Portal>
50
+ <Content ref={ref} {...props} position="popper" />
51
+ </Portal>
52
+ );
53
+ });
54
+
55
+ export const SelectViewport: ForwardRefExoticComponent<
56
+ ComponentPropsWithRef<typeof Viewport>
57
+ > = Viewport;
58
+
59
+ export const SelectItem: ForwardRefExoticComponent<
60
+ ComponentPropsWithRef<typeof Item>
61
+ > = Item;
62
+
63
+ export const SelectItemIndicator: ForwardRefExoticComponent<
64
+ ComponentPropsWithRef<typeof ItemIndicator>
65
+ > = ItemIndicator;
66
+
67
+ export const SelectItemText: ForwardRefExoticComponent<
68
+ ComponentPropsWithRef<typeof ItemText>
69
+ > = ItemText;
70
+
71
+ /* BUILDER HOOKS */
72
+
73
+ const namespace = "@webstudio-is/sdk-components-react-radix";
74
+
75
+ // For each SelectContent component within the selection,
76
+ // we identify its closest parent Select component
77
+ // and update its open prop bound to variable.
78
+ export const hooksSelect: Hook = {
79
+ onNavigatorUnselect: (context, event) => {
80
+ for (const instance of event.instancePath) {
81
+ if (instance.component === `${namespace}:SelectContent`) {
82
+ const select = getClosestInstance(
83
+ event.instancePath,
84
+ instance,
85
+ `${namespace}:Select`
86
+ );
87
+ if (select) {
88
+ context.setPropVariable(select.id, "open", false);
89
+ }
90
+ }
91
+ }
92
+ },
93
+ onNavigatorSelect: (context, event) => {
94
+ for (const instance of event.instancePath) {
95
+ if (instance.component === `${namespace}:SelectContent`) {
96
+ const select = getClosestInstance(
97
+ event.instancePath,
98
+ instance,
99
+ `${namespace}:Select`
100
+ );
101
+ if (select) {
102
+ context.setPropVariable(select.id, "open", true);
103
+ }
104
+ }
105
+ }
106
+ },
107
+ };
@@ -0,0 +1,347 @@
1
+ import {
2
+ SelectIcon,
3
+ TriggerIcon,
4
+ FormTextFieldIcon,
5
+ ContentIcon,
6
+ ItemIcon,
7
+ ViewportIcon,
8
+ TextIcon,
9
+ CheckMarkIcon,
10
+ } from "@webstudio-is/icons/svg";
11
+ import type {
12
+ EmbedTemplateInstance,
13
+ PresetStyle,
14
+ WsComponentMeta,
15
+ WsComponentPropsMeta,
16
+ WsEmbedTemplate,
17
+ } from "@webstudio-is/react-sdk";
18
+ import { button, div, span } from "@webstudio-is/react-sdk/css-normalize";
19
+ import * as tc from "./theme/tailwind-classes";
20
+ import {
21
+ propsSelect,
22
+ propsSelectContent,
23
+ propsSelectItem,
24
+ propsSelectItemIndicator,
25
+ propsSelectItemText,
26
+ propsSelectTrigger,
27
+ propsSelectValue,
28
+ propsSelectViewport,
29
+ } from "./__generated__/select.props";
30
+
31
+ const presetStyle = {
32
+ div,
33
+ } satisfies PresetStyle<"div">;
34
+
35
+ const createSelectItem = ({
36
+ props,
37
+ children,
38
+ }: {
39
+ props?: EmbedTemplateInstance["props"];
40
+ children: WsEmbedTemplate;
41
+ }): EmbedTemplateInstance => ({
42
+ type: "instance",
43
+ component: "SelectItem",
44
+ props,
45
+ // relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none
46
+ // focus:bg-accent focus:text-accent-foreground
47
+ // data-[disabled]:pointer-events-none data-[disabled]:opacity-50
48
+ styles: [
49
+ tc.relative(),
50
+ tc.flex(),
51
+ tc.w("full"),
52
+ tc.cursor("default"),
53
+ tc.select("none"),
54
+ tc.items("center"),
55
+ tc.rounded("md"),
56
+ tc.py(1.5),
57
+ tc.pl(8),
58
+ tc.pr(2),
59
+ tc.text("sm"),
60
+ tc.outline("none"),
61
+ tc.focus([tc.bg("accent"), tc.text("accentForeground")].flat()),
62
+ tc.state(
63
+ [tc.pointerEvents("none"), tc.opacity(50)].flat(),
64
+ "[data-disabled]"
65
+ ),
66
+ ].flat(),
67
+ children: [
68
+ {
69
+ type: "instance",
70
+ component: "SelectItemIndicator",
71
+ // absolute left-2 flex h-3.5 w-3.5 items-center justify-center
72
+ styles: [
73
+ tc.absolute(),
74
+ tc.left(2),
75
+ tc.flex(),
76
+ tc.h(3.5),
77
+ tc.w(3.5),
78
+ tc.items("center"),
79
+ tc.justify("center"),
80
+ ].flat(),
81
+ children: [
82
+ {
83
+ type: "instance",
84
+ component: "HtmlEmbed",
85
+ label: "Indicator Icon",
86
+ props: [
87
+ {
88
+ type: "string",
89
+ name: "code",
90
+ value: CheckMarkIcon,
91
+ },
92
+ ],
93
+ children: [],
94
+ },
95
+ ],
96
+ },
97
+ {
98
+ type: "instance",
99
+ component: "SelectItemText",
100
+ children,
101
+ },
102
+ ],
103
+ });
104
+
105
+ export const metaSelect: WsComponentMeta = {
106
+ category: "radix",
107
+ order: 10,
108
+ type: "container",
109
+ icon: SelectIcon,
110
+ stylable: false,
111
+ template: [
112
+ {
113
+ type: "instance",
114
+ component: "Select",
115
+ dataSources: {
116
+ selectValue: { type: "variable", initialValue: "" },
117
+ selectOpen: { type: "variable", initialValue: false },
118
+ },
119
+ props: [
120
+ {
121
+ name: "value",
122
+ type: "dataSource",
123
+ dataSourceName: "selectValue",
124
+ },
125
+ {
126
+ name: "onValueChange",
127
+ type: "action",
128
+ value: [
129
+ { type: "execute", args: ["value"], code: `selectValue = value` },
130
+ ],
131
+ },
132
+ {
133
+ name: "open",
134
+ type: "dataSource",
135
+ dataSourceName: "selectOpen",
136
+ },
137
+ {
138
+ name: "onOpenChange",
139
+ type: "action",
140
+ value: [
141
+ { type: "execute", args: ["open"], code: `selectOpen = open` },
142
+ ],
143
+ },
144
+ ],
145
+ children: [
146
+ {
147
+ type: "instance",
148
+ component: "SelectTrigger",
149
+ // flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background
150
+ // placeholder:text-muted-foreground
151
+ // focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
152
+ // disabled:cursor-not-allowed disabled:opacity-50
153
+ styles: [
154
+ tc.flex(),
155
+ tc.h(10),
156
+ tc.w("full"),
157
+ tc.items("center"),
158
+ tc.justify("between"),
159
+ tc.rounded("md"),
160
+ tc.border(),
161
+ tc.border("input"),
162
+ tc.bg("background"),
163
+ tc.px(3),
164
+ tc.py(2),
165
+ tc.text("sm"),
166
+ tc.state([tc.text("mutedForeground")].flat(), "::placeholder"),
167
+ tc.focus(
168
+ [tc.outline("none"), tc.ring("ring", 2, "background", 2)].flat()
169
+ ),
170
+ tc.disabled([tc.cursor("not-allowed"), tc.opacity(50)].flat()),
171
+ ].flat(),
172
+ children: [
173
+ {
174
+ type: "instance",
175
+ component: "SelectValue",
176
+ props: [{ name: "placeholder", type: "string", value: "Theme" }],
177
+ children: [],
178
+ },
179
+ ],
180
+ },
181
+ {
182
+ type: "instance",
183
+ component: "SelectContent",
184
+ // relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md
185
+ // data-[state=open]:animate-in
186
+ // data-[state=closed]:animate-out data-[state=closed]:fade-out-0
187
+ // data-[state=open]:fade-in-0
188
+ // data-[state=closed]:zoom-out-95
189
+ // data-[state=open]:zoom-in-95
190
+ // data-[side=bottom]:slide-in-from-top-2
191
+ // data-[side=left]:slide-in-from-right-2
192
+ // data-[side=right]:slide-in-from-left-2
193
+ // data-[side=top]:slide-in-from-bottom-2
194
+ // position=popper
195
+ // data-[side=bottom]:translate-y-1
196
+ // data-[side=left]:-translate-x-1
197
+ // data-[side=right]:translate-x-1
198
+ // data-[side=top]:-translate-y-1
199
+ styles: [
200
+ tc.relative(),
201
+ tc.z(50),
202
+ tc.property("minWidth", "8rem"),
203
+ tc.overflow("hidden"),
204
+ tc.rounded("md"),
205
+ tc.border(),
206
+ tc.bg("popover"),
207
+ tc.text("popoverForeground"),
208
+ tc.shadow("md"),
209
+ ].flat(),
210
+ children: [
211
+ {
212
+ type: "instance",
213
+ component: "SelectViewport",
214
+ // p-1
215
+ // position=popper
216
+ // h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]
217
+ styles: [
218
+ tc.p(1),
219
+ tc.property("height", "--radix-select-trigger-height"),
220
+ tc.w("full"),
221
+ tc.property("minWidth", "--radix-select-trigger-width"),
222
+ ].flat(),
223
+ children: [
224
+ createSelectItem({
225
+ props: [{ name: "value", type: "string", value: "light" }],
226
+ children: [{ type: "text", value: "Light" }],
227
+ }),
228
+ createSelectItem({
229
+ props: [{ name: "value", type: "string", value: "dark" }],
230
+ children: [{ type: "text", value: "Dark" }],
231
+ }),
232
+ createSelectItem({
233
+ props: [{ name: "value", type: "string", value: "system" }],
234
+ children: [{ type: "text", value: "System" }],
235
+ }),
236
+ ],
237
+ },
238
+ ],
239
+ },
240
+ ],
241
+ },
242
+ ],
243
+ };
244
+
245
+ export const metaSelectTrigger: WsComponentMeta = {
246
+ category: "hidden",
247
+ type: "container",
248
+ icon: TriggerIcon,
249
+ detachable: false,
250
+ presetStyle: {
251
+ button,
252
+ },
253
+ };
254
+
255
+ export const metaSelectValue: WsComponentMeta = {
256
+ category: "hidden",
257
+ type: "container",
258
+ label: "Value",
259
+ icon: FormTextFieldIcon,
260
+ detachable: false,
261
+ presetStyle: {
262
+ span,
263
+ },
264
+ };
265
+
266
+ export const metaSelectContent: WsComponentMeta = {
267
+ category: "hidden",
268
+ type: "container",
269
+ icon: ContentIcon,
270
+ detachable: false,
271
+ presetStyle,
272
+ };
273
+
274
+ export const metaSelectViewport: WsComponentMeta = {
275
+ category: "hidden",
276
+ type: "container",
277
+ icon: ViewportIcon,
278
+ detachable: false,
279
+ presetStyle,
280
+ };
281
+
282
+ export const metaSelectItem: WsComponentMeta = {
283
+ category: "hidden",
284
+ type: "container",
285
+ icon: ItemIcon,
286
+ requiredAncestors: ["SelectViewport"],
287
+ presetStyle,
288
+ };
289
+
290
+ export const metaSelectItemIndicator: WsComponentMeta = {
291
+ category: "hidden",
292
+ type: "container",
293
+ label: "Indicator",
294
+ icon: CheckMarkIcon,
295
+ detachable: false,
296
+ requiredAncestors: ["SelectItem"],
297
+ presetStyle: {
298
+ span,
299
+ },
300
+ };
301
+
302
+ export const metaSelectItemText: WsComponentMeta = {
303
+ category: "hidden",
304
+ type: "container",
305
+ label: "Item Text",
306
+ icon: TextIcon,
307
+ detachable: false,
308
+ requiredAncestors: ["SelectItem"],
309
+ presetStyle: {
310
+ span,
311
+ },
312
+ };
313
+
314
+ export const propsMetaSelect: WsComponentPropsMeta = {
315
+ props: propsSelect,
316
+ initialProps: ["value", "open", "name", "required"],
317
+ };
318
+
319
+ export const propsMetaSelectTrigger: WsComponentPropsMeta = {
320
+ props: propsSelectTrigger,
321
+ };
322
+
323
+ export const propsMetaSelectValue: WsComponentPropsMeta = {
324
+ props: propsSelectValue,
325
+ initialProps: ["placeholder"],
326
+ };
327
+
328
+ export const propsMetaSelectContent: WsComponentPropsMeta = {
329
+ props: propsSelectContent,
330
+ };
331
+
332
+ export const propsMetaSelectViewport: WsComponentPropsMeta = {
333
+ props: propsSelectViewport,
334
+ };
335
+
336
+ export const propsMetaSelectItem: WsComponentPropsMeta = {
337
+ props: propsSelectItem,
338
+ initialProps: ["value"],
339
+ };
340
+
341
+ export const propsMetaSelectItemIndicator: WsComponentPropsMeta = {
342
+ props: propsSelectItemIndicator,
343
+ };
344
+
345
+ export const propsMetaSelectItemText: WsComponentPropsMeta = {
346
+ props: propsSelectItemText,
347
+ };