@webstudio-is/sdk-components-react 0.82.0 → 0.83.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 (168) hide show
  1. package/LICENSE +661 -21
  2. package/lib/__generated__/blockquote.props.js +30 -5
  3. package/lib/__generated__/body.props.js +30 -5
  4. package/lib/__generated__/bold.props.js +30 -5
  5. package/lib/__generated__/box.props.js +30 -5
  6. package/lib/__generated__/button.props.js +30 -5
  7. package/lib/__generated__/checkbox.props.js +31 -6
  8. package/lib/__generated__/code-text.props.js +30 -5
  9. package/lib/__generated__/form.props.js +30 -5
  10. package/lib/__generated__/heading.props.js +30 -5
  11. package/lib/__generated__/image.props.js +30 -5
  12. package/lib/__generated__/input.props.js +30 -5
  13. package/lib/__generated__/italic.props.js +30 -5
  14. package/lib/__generated__/label.props.js +30 -5
  15. package/lib/__generated__/link.props.js +30 -5
  16. package/lib/__generated__/list-item.props.js +30 -5
  17. package/lib/__generated__/list.props.js +30 -5
  18. package/lib/__generated__/paragraph.props.js +30 -5
  19. package/lib/__generated__/radio-button.props.js +31 -6
  20. package/lib/__generated__/radix-dialog.props.js +2120 -0
  21. package/lib/__generated__/radix-popover.props.js +463 -0
  22. package/lib/__generated__/radix-tooltip.props.js +473 -0
  23. package/lib/__generated__/rich-text-link.props.js +30 -5
  24. package/lib/__generated__/separator.props.js +30 -5
  25. package/lib/__generated__/span.props.js +30 -5
  26. package/lib/__generated__/subscript.props.js +30 -5
  27. package/lib/__generated__/superscript.props.js +30 -5
  28. package/lib/__generated__/text.props.js +30 -5
  29. package/lib/__generated__/textarea.props.js +30 -5
  30. package/lib/__generated__/vimeo-play-button.props.js +30 -5
  31. package/lib/__generated__/vimeo-preview-image.props.js +30 -5
  32. package/lib/__generated__/vimeo-spinner.props.js +30 -5
  33. package/lib/__generated__/vimeo.props.js +30 -5
  34. package/lib/body.ws.js +11 -1
  35. package/lib/cjs/__generated__/blockquote.props.js +30 -5
  36. package/lib/cjs/__generated__/body.props.js +30 -5
  37. package/lib/cjs/__generated__/bold.props.js +30 -5
  38. package/lib/cjs/__generated__/box.props.js +30 -5
  39. package/lib/cjs/__generated__/button.props.js +30 -5
  40. package/lib/cjs/__generated__/checkbox.props.js +31 -6
  41. package/lib/cjs/__generated__/code-text.props.js +30 -5
  42. package/lib/cjs/__generated__/form.props.js +30 -5
  43. package/lib/cjs/__generated__/heading.props.js +30 -5
  44. package/lib/cjs/__generated__/image.props.js +30 -5
  45. package/lib/cjs/__generated__/input.props.js +30 -5
  46. package/lib/cjs/__generated__/italic.props.js +30 -5
  47. package/lib/cjs/__generated__/label.props.js +30 -5
  48. package/lib/cjs/__generated__/link.props.js +30 -5
  49. package/lib/cjs/__generated__/list-item.props.js +30 -5
  50. package/lib/cjs/__generated__/list.props.js +30 -5
  51. package/lib/cjs/__generated__/paragraph.props.js +30 -5
  52. package/lib/cjs/__generated__/radio-button.props.js +31 -6
  53. package/lib/cjs/__generated__/radix-dialog.props.js +2140 -0
  54. package/lib/cjs/__generated__/radix-popover.props.js +483 -0
  55. package/lib/cjs/__generated__/radix-tooltip.props.js +493 -0
  56. package/lib/cjs/__generated__/rich-text-link.props.js +30 -5
  57. package/lib/cjs/__generated__/separator.props.js +30 -5
  58. package/lib/cjs/__generated__/span.props.js +30 -5
  59. package/lib/cjs/__generated__/subscript.props.js +30 -5
  60. package/lib/cjs/__generated__/superscript.props.js +30 -5
  61. package/lib/cjs/__generated__/text.props.js +30 -5
  62. package/lib/cjs/__generated__/textarea.props.js +30 -5
  63. package/lib/cjs/__generated__/vimeo-play-button.props.js +30 -5
  64. package/lib/cjs/__generated__/vimeo-preview-image.props.js +30 -5
  65. package/lib/cjs/__generated__/vimeo-spinner.props.js +30 -5
  66. package/lib/cjs/__generated__/vimeo.props.js +30 -5
  67. package/lib/cjs/body.ws.js +11 -1
  68. package/lib/cjs/components.js +16 -0
  69. package/lib/cjs/label.ws.js +1 -1
  70. package/lib/cjs/metas.js +16 -0
  71. package/lib/cjs/props.js +16 -0
  72. package/lib/cjs/radix-dialog.js +61 -0
  73. package/lib/cjs/radix-dialog.ws.js +300 -0
  74. package/lib/cjs/radix-popover.js +59 -0
  75. package/lib/cjs/radix-popover.ws.js +139 -0
  76. package/lib/cjs/radix-tooltip.js +51 -0
  77. package/lib/cjs/radix-tooltip.ws.js +140 -0
  78. package/lib/cjs/theme/radix-common-types.js +16 -0
  79. package/lib/cjs/theme/tailwind-classes.js +439 -0
  80. package/lib/cjs/theme/tailwind-colors.js +33 -0
  81. package/lib/cjs/theme/tailwind-theme.js +46 -0
  82. package/lib/cjs/vimeo-play-button.ws.js +1 -0
  83. package/lib/cjs/vimeo-preview-image.ws.js +1 -0
  84. package/lib/cjs/vimeo.ws.js +1 -0
  85. package/lib/components.js +24 -0
  86. package/lib/label.ws.js +2 -2
  87. package/lib/metas.js +32 -0
  88. package/lib/props.js +32 -0
  89. package/lib/radix-dialog.js +36 -0
  90. package/lib/radix-dialog.ws.js +279 -0
  91. package/lib/radix-popover.js +34 -0
  92. package/lib/radix-popover.ws.js +114 -0
  93. package/lib/radix-tooltip.js +26 -0
  94. package/lib/radix-tooltip.ws.js +115 -0
  95. package/lib/theme/radix-common-types.js +0 -0
  96. package/lib/theme/tailwind-classes.js +419 -0
  97. package/lib/theme/tailwind-colors.js +13 -0
  98. package/lib/theme/tailwind-theme.js +16 -0
  99. package/lib/types/__generated__/radix-dialog.props.d.ts +8 -0
  100. package/lib/types/__generated__/radix-popover.props.d.ts +4 -0
  101. package/lib/types/__generated__/radix-tooltip.props.d.ts +4 -0
  102. package/lib/types/components.d.ts +3 -0
  103. package/lib/types/metas.d.ts +3 -0
  104. package/lib/types/props.d.ts +3 -0
  105. package/lib/types/radix-dialog.d.ts +26 -0
  106. package/lib/types/radix-dialog.ws.d.ts +23 -0
  107. package/lib/types/radix-popover.d.ts +22 -0
  108. package/lib/types/radix-popover.ws.d.ts +15 -0
  109. package/lib/types/radix-tooltip.d.ts +22 -0
  110. package/lib/types/radix-tooltip.ws.d.ts +15 -0
  111. package/lib/types/theme/radix-common-types.d.ts +84 -0
  112. package/lib/types/theme/tailwind-classes.d.ts +69 -0
  113. package/lib/types/theme/tailwind-colors.d.ts +19 -0
  114. package/lib/types/theme/tailwind-theme.d.ts +72 -0
  115. package/lib/types/vimeo-preview-image.d.ts +6 -1
  116. package/lib/vimeo-play-button.ws.js +1 -0
  117. package/lib/vimeo-preview-image.js +1 -1
  118. package/lib/vimeo-preview-image.ws.js +2 -0
  119. package/lib/vimeo.ws.js +1 -0
  120. package/package.json +18 -13
  121. package/src/LICENSE +661 -21
  122. package/src/__generated__/blockquote.props.ts +34 -5
  123. package/src/__generated__/body.props.ts +34 -5
  124. package/src/__generated__/bold.props.ts +34 -5
  125. package/src/__generated__/box.props.ts +34 -5
  126. package/src/__generated__/button.props.ts +34 -5
  127. package/src/__generated__/checkbox.props.ts +35 -6
  128. package/src/__generated__/code-text.props.ts +34 -5
  129. package/src/__generated__/form.props.ts +34 -5
  130. package/src/__generated__/heading.props.ts +34 -5
  131. package/src/__generated__/image.props.ts +34 -5
  132. package/src/__generated__/input.props.ts +34 -5
  133. package/src/__generated__/italic.props.ts +34 -5
  134. package/src/__generated__/label.props.ts +34 -5
  135. package/src/__generated__/link.props.ts +34 -5
  136. package/src/__generated__/list-item.props.ts +34 -5
  137. package/src/__generated__/list.props.ts +34 -5
  138. package/src/__generated__/paragraph.props.ts +34 -5
  139. package/src/__generated__/radio-button.props.ts +35 -6
  140. package/src/__generated__/radix-dialog.props.ts +2363 -0
  141. package/src/__generated__/radix-popover.props.ts +510 -0
  142. package/src/__generated__/radix-tooltip.props.ts +521 -0
  143. package/src/__generated__/rich-text-link.props.ts +34 -5
  144. package/src/__generated__/separator.props.ts +34 -5
  145. package/src/__generated__/span.props.ts +34 -5
  146. package/src/__generated__/subscript.props.ts +34 -5
  147. package/src/__generated__/superscript.props.ts +34 -5
  148. package/src/__generated__/text.props.ts +34 -5
  149. package/src/__generated__/textarea.props.ts +34 -5
  150. package/src/__generated__/vimeo-play-button.props.ts +34 -5
  151. package/src/__generated__/vimeo-preview-image.props.ts +34 -5
  152. package/src/__generated__/vimeo-spinner.props.ts +34 -5
  153. package/src/__generated__/vimeo.props.ts +34 -5
  154. package/src/body.ws.tsx +11 -1
  155. package/src/components.ts +11 -0
  156. package/src/label.ws.tsx +2 -2
  157. package/src/metas.ts +21 -0
  158. package/src/props.ts +19 -0
  159. package/src/radix-dialog.tsx +91 -0
  160. package/src/radix-dialog.ws.tsx +291 -0
  161. package/src/radix-popover.tsx +89 -0
  162. package/src/radix-popover.ws.tsx +124 -0
  163. package/src/radix-tooltip.tsx +84 -0
  164. package/src/radix-tooltip.ws.tsx +125 -0
  165. package/src/theme/radix-common-types.ts +495 -0
  166. package/src/theme/tailwind-classes.ts +570 -0
  167. package/src/theme/tailwind-colors.ts +47 -0
  168. package/src/theme/tailwind-theme.ts +24 -0
@@ -25,13 +25,21 @@ export const props: Record<string, PropMeta> = {
25
25
  type: "string",
26
26
  options: ["list", "none", "inline", "both"],
27
27
  },
28
- "aria-busy": {
28
+ "aria-braillelabel": {
29
29
  description:
30
- "Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user.",
30
+ "Defines a string value that labels the current element, which is intended to be converted into Braille.\n@see aria-label.",
31
31
  required: false,
32
- control: "boolean",
33
- type: "boolean",
32
+ control: "text",
33
+ type: "string",
34
34
  },
35
+ "aria-brailleroledescription": {
36
+ description:
37
+ "Defines a human-readable, author-localized abbreviated description for the role of an element, which is intended to be converted into Braille.\n@see aria-roledescription.",
38
+ required: false,
39
+ control: "text",
40
+ type: "string",
41
+ },
42
+ "aria-busy": { required: false, control: "boolean", type: "boolean" },
35
43
  "aria-checked": {
36
44
  description:
37
45
  'Indicates the current "checked" state of checkboxes, radio buttons, and other widgets.\n@see aria-pressed\n@see aria-selected.',
@@ -53,6 +61,13 @@ export const props: Record<string, PropMeta> = {
53
61
  control: "number",
54
62
  type: "number",
55
63
  },
64
+ "aria-colindextext": {
65
+ description:
66
+ "Defines a human readable text alternative of aria-colindex.\n@see aria-rowindextext.",
67
+ required: false,
68
+ control: "text",
69
+ type: "string",
70
+ },
56
71
  "aria-colspan": {
57
72
  description:
58
73
  "Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.\n@see aria-colindex\n@see aria-rowspan.",
@@ -81,6 +96,13 @@ export const props: Record<string, PropMeta> = {
81
96
  control: "text",
82
97
  type: "string",
83
98
  },
99
+ "aria-description": {
100
+ description:
101
+ "Defines a string value that describes or annotates the current element.\n@see related aria-describedby.",
102
+ required: false,
103
+ control: "text",
104
+ type: "string",
105
+ },
84
106
  "aria-details": {
85
107
  description:
86
108
  "Identifies the element that provides a detailed, extended description for the object.\n@see aria-describedby.",
@@ -298,6 +320,13 @@ export const props: Record<string, PropMeta> = {
298
320
  control: "number",
299
321
  type: "number",
300
322
  },
323
+ "aria-rowindextext": {
324
+ description:
325
+ "Defines a human readable text alternative of aria-rowindex.\n@see aria-colindextext.",
326
+ required: false,
327
+ control: "text",
328
+ type: "string",
329
+ },
301
330
  "aria-rowspan": {
302
331
  description:
303
332
  "Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.\n@see aria-rowindex\n@see aria-colspan.",
@@ -420,10 +449,10 @@ export const props: Record<string, PropMeta> = {
420
449
  control: "select",
421
450
  type: "string",
422
451
  options: [
452
+ "search",
423
453
  "text",
424
454
  "url",
425
455
  "none",
426
- "search",
427
456
  "tel",
428
457
  "email",
429
458
  "numeric",
package/src/body.ws.tsx CHANGED
@@ -10,7 +10,17 @@ import { props } from "./__generated__/body.props";
10
10
  import type { defaultTag } from "./body";
11
11
 
12
12
  const presetStyle = {
13
- body,
13
+ body: [
14
+ ...body,
15
+ {
16
+ property: "WebkitFontSmoothing",
17
+ value: { type: "keyword", value: "antialiased" },
18
+ },
19
+ {
20
+ property: "MozOsxFontSmoothing",
21
+ value: { type: "keyword", value: "grayscale" },
22
+ },
23
+ ],
14
24
  } satisfies PresetStyle<typeof defaultTag>;
15
25
 
16
26
  export const meta: WsComponentMeta = {
package/src/components.ts CHANGED
@@ -30,3 +30,14 @@ export { Vimeo } from "./vimeo";
30
30
  export { VimeoPreviewImage } from "./vimeo-preview-image";
31
31
  export { VimeoPlayButton } from "./vimeo-play-button";
32
32
  export { VimeoSpinner } from "./vimeo-spinner";
33
+ export { Tooltip, TooltipContent, TooltipTrigger } from "./radix-tooltip";
34
+ export { Popover, PopoverContent, PopoverTrigger } from "./radix-popover";
35
+ export {
36
+ Dialog,
37
+ DialogContent,
38
+ DialogTrigger,
39
+ DialogOverlay,
40
+ DialogClose,
41
+ DialogDescription,
42
+ DialogTitle,
43
+ } from "./radix-dialog";
package/src/label.ws.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { TextIcon } from "@webstudio-is/icons/svg";
1
+ import { LabelIcon } from "@webstudio-is/icons/svg";
2
2
  import {
3
3
  type WsComponentMeta,
4
4
  type WsComponentPropsMeta,
@@ -21,7 +21,7 @@ export const meta: WsComponentMeta = {
21
21
  invalidAncestors: ["Button"],
22
22
  type: "container",
23
23
  label: "Input Label",
24
- icon: TextIcon,
24
+ icon: LabelIcon,
25
25
  states: defaultStates,
26
26
  presetStyle,
27
27
  order: 2,
package/src/metas.ts CHANGED
@@ -30,3 +30,24 @@ export { meta as Vimeo } from "./vimeo.ws";
30
30
  export { meta as VimeoPreviewImage } from "./vimeo-preview-image.ws";
31
31
  export { meta as VimeoPlayButton } from "./vimeo-play-button.ws";
32
32
  export { meta as VimeoSpinner } from "./vimeo-spinner.ws";
33
+ export {
34
+ metaTooltip as Tooltip,
35
+ metaTooltipContent as TooltipContent,
36
+ metaTooltipTrigger as TooltipTrigger,
37
+ } from "./radix-tooltip.ws";
38
+
39
+ export {
40
+ metaPopover as Popover,
41
+ metaPopoverContent as PopoverContent,
42
+ metaPopoverTrigger as PopoverTrigger,
43
+ } from "./radix-popover.ws";
44
+
45
+ export {
46
+ metaDialog as Dialog,
47
+ metaDialogContent as DialogContent,
48
+ metaDialogTrigger as DialogTrigger,
49
+ metaDialogOverlay as DialogOverlay,
50
+ metaDialogClose as DialogClose,
51
+ metaDialogDescription as DialogDescription,
52
+ metaDialogTitle as DialogTitle,
53
+ } from "./radix-dialog.ws";
package/src/props.ts CHANGED
@@ -30,3 +30,22 @@ export { propsMeta as Vimeo } from "./vimeo.ws";
30
30
  export { propsMeta as VimeoPreviewImage } from "./vimeo-preview-image.ws";
31
31
  export { propsMeta as VimeoPlayButton } from "./vimeo-play-button.ws";
32
32
  export { propsMeta as VimeoSpinner } from "./vimeo-spinner.ws";
33
+ export {
34
+ propsMetaTooltip as Tooltip,
35
+ propsMetaTooltipContent as TooltipContent,
36
+ propsMetaTooltipTrigger as TooltipTrigger,
37
+ } from "./radix-tooltip.ws";
38
+ export {
39
+ propsMetaPopover as Popover,
40
+ propsMetaPopoverContent as PopoverContent,
41
+ propsMetaPopoverTrigger as PopoverTrigger,
42
+ } from "./radix-popover.ws";
43
+ export {
44
+ propsMetaDialog as Dialog,
45
+ propsMetaDialogContent as DialogContent,
46
+ propsMetaDialogTrigger as DialogTrigger,
47
+ propsMetaDialogOverlay as DialogOverlay,
48
+ propsMetaDialogClose as DialogClose,
49
+ propsMetaDialogDescription as DialogDescription,
50
+ propsMetaDialogTitle as DialogTitle,
51
+ } from "./radix-dialog.ws";
@@ -0,0 +1,91 @@
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 * as DialogPrimitive from "@radix-ui/react-dialog";
5
+ import {
6
+ splitPropsWithWebstudioAttributes,
7
+ type WebstudioAttributes,
8
+ } from "@webstudio-is/react-sdk";
9
+
10
+ import {
11
+ forwardRef,
12
+ type ElementRef,
13
+ type ComponentPropsWithoutRef,
14
+ Children,
15
+ type ReactNode,
16
+ } from "react";
17
+
18
+ /**
19
+ * We don't have support for boolean or undefined nor in UI not at Data variables,
20
+ * instead of binding on "open" prop we bind variable on a isOpen prop to be able to show Dialog in the builder
21
+ **/
22
+ type BuilderDialogProps = {
23
+ isOpen: "initial" | "open" | "closed";
24
+ };
25
+
26
+ /**
27
+ * Dialog and DialogTrigger are HTML-less components.
28
+ * To make them work in our system, we wrap their attributes with a div that has a display: contents property.
29
+ *
30
+ * These divs function like fragments, with all web studio-related attributes attached to them.
31
+ */
32
+ const DisplayContentsStyle = { display: "contents" };
33
+
34
+ export const Dialog = forwardRef<
35
+ ElementRef<"div">,
36
+ WebstudioAttributes &
37
+ ComponentPropsWithoutRef<typeof DialogPrimitive.Root> &
38
+ BuilderDialogProps
39
+ >(({ open: openProp, isOpen, ...props }, ref) => {
40
+ const [webstudioAttributes, restProps] =
41
+ splitPropsWithWebstudioAttributes(props);
42
+
43
+ const open =
44
+ openProp ??
45
+ (isOpen === "open" ? true : isOpen === "closed" ? false : undefined);
46
+
47
+ return (
48
+ <div ref={ref} style={DisplayContentsStyle} {...webstudioAttributes}>
49
+ <DialogPrimitive.Root open={open} {...restProps} />
50
+ </div>
51
+ );
52
+ });
53
+
54
+ /**
55
+ * We're not exposing the 'asChild' property for the Trigger.
56
+ * Instead, we're enforcing 'asChild=true' for the Trigger and making it style-less.
57
+ * This avoids situations where the Trigger inadvertently passes all styles to its child,
58
+ * which would prevent us from displaying styles properly in the builder.
59
+ */
60
+ export const DialogTrigger = forwardRef<
61
+ ElementRef<"div">,
62
+ WebstudioAttributes & { children: ReactNode }
63
+ >(({ children, ...props }, ref) => {
64
+ const firstChild = Children.toArray(children)[0];
65
+ const [webstudioAttributes, restProps] =
66
+ splitPropsWithWebstudioAttributes(props);
67
+
68
+ return (
69
+ <div ref={ref} style={DisplayContentsStyle} {...webstudioAttributes}>
70
+ <DialogPrimitive.Trigger asChild={true} {...restProps}>
71
+ {firstChild ?? <button>Add button or link</button>}
72
+ </DialogPrimitive.Trigger>
73
+ </div>
74
+ );
75
+ });
76
+
77
+ export const DialogOverlay = forwardRef<
78
+ ElementRef<"div">,
79
+ ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
80
+ >((props, ref) => {
81
+ return (
82
+ <DialogPrimitive.DialogPortal>
83
+ <DialogPrimitive.Overlay ref={ref} {...props} />
84
+ </DialogPrimitive.DialogPortal>
85
+ );
86
+ });
87
+
88
+ export const DialogContent = DialogPrimitive.Content;
89
+ export const DialogClose = DialogPrimitive.Close;
90
+ export const DialogTitle = DialogPrimitive.Title;
91
+ export const DialogDescription = DialogPrimitive.Description;
@@ -0,0 +1,291 @@
1
+ import { RadioCheckedIcon } from "@webstudio-is/icons/svg";
2
+ import {
3
+ type WsComponentMeta,
4
+ type WsComponentPropsMeta,
5
+ } from "@webstudio-is/react-sdk";
6
+ import * as tc from "./theme/tailwind-classes";
7
+
8
+ import {
9
+ propsDialog,
10
+ propsDialogContent,
11
+ propsDialogTrigger,
12
+ propsDialogOverlay,
13
+ propsDialogClose,
14
+ propsDialogTitle,
15
+ propsDialogDescription,
16
+ } from "./__generated__/radix-dialog.props";
17
+
18
+ // @todo add [data-state] to button and link
19
+ export const metaDialogTrigger: WsComponentMeta = {
20
+ category: "hidden",
21
+ invalidAncestors: [],
22
+ type: "container",
23
+ label: "DialogTrigger",
24
+ icon: RadioCheckedIcon,
25
+ stylable: false,
26
+ detachable: false,
27
+ };
28
+
29
+ export const metaDialogContent: WsComponentMeta = {
30
+ category: "hidden",
31
+ invalidAncestors: [],
32
+ type: "container",
33
+ label: "DialogContent",
34
+ icon: RadioCheckedIcon,
35
+ detachable: false,
36
+ };
37
+
38
+ export const metaDialogOverlay: WsComponentMeta = {
39
+ category: "hidden",
40
+ invalidAncestors: [],
41
+ type: "container",
42
+ label: "DialogOverlay",
43
+ icon: RadioCheckedIcon,
44
+ detachable: false,
45
+ };
46
+
47
+ export const metaDialogTitle: WsComponentMeta = {
48
+ category: "hidden",
49
+ invalidAncestors: [],
50
+ type: "container",
51
+ label: "DialogTitle",
52
+ icon: RadioCheckedIcon,
53
+ };
54
+
55
+ export const metaDialogDescription: WsComponentMeta = {
56
+ category: "hidden",
57
+ invalidAncestors: [],
58
+ type: "container",
59
+ label: "DialogDescription",
60
+ icon: RadioCheckedIcon,
61
+ };
62
+
63
+ export const metaDialogClose: WsComponentMeta = {
64
+ category: "hidden",
65
+ invalidAncestors: [],
66
+ type: "container",
67
+ label: "DialogClose",
68
+ icon: RadioCheckedIcon,
69
+ };
70
+
71
+ /**
72
+ * Styles source without animations:
73
+ * https://github.com/shadcn-ui/ui/blob/main/apps/www/registry/default/ui/dialog.tsx
74
+ *
75
+ * Attributions
76
+ * MIT License
77
+ * Copyright (c) 2023 shadcn
78
+ **/
79
+ export const metaDialog: WsComponentMeta = {
80
+ category: "radix",
81
+ invalidAncestors: [],
82
+ type: "container",
83
+ label: "Dialog",
84
+ icon: RadioCheckedIcon,
85
+ order: 15,
86
+ stylable: false,
87
+ template: [
88
+ {
89
+ type: "instance",
90
+ component: "Dialog",
91
+ label: "Dialog",
92
+ props: [
93
+ {
94
+ name: "isOpen",
95
+ // We don't have support for boolean or undefined, instead of binding on open we bind on a string
96
+ type: "string",
97
+ value: "initial",
98
+ dataSourceRef: {
99
+ type: "variable",
100
+ name: "isOpen",
101
+ },
102
+ },
103
+ ],
104
+ children: [
105
+ {
106
+ type: "instance",
107
+ component: "DialogTrigger",
108
+ props: [],
109
+ children: [
110
+ {
111
+ type: "instance",
112
+ component: "Button",
113
+ children: [{ type: "text", value: "Button" }],
114
+ },
115
+ ],
116
+ },
117
+ {
118
+ type: "instance",
119
+ component: "DialogOverlay",
120
+ label: "Dialog Overlay",
121
+ props: [],
122
+ /**
123
+ * fixed inset-0 z-50 bg-background/80 backdrop-blur-sm
124
+ * flex
125
+ **/
126
+ styles: [
127
+ tc.fixed(),
128
+ tc.inset(0),
129
+ tc.z(50),
130
+ tc.bg("background", 80),
131
+ tc.backdropBlur("sm"),
132
+ // To allow positioning Content
133
+ tc.flex(),
134
+ ].flat(),
135
+ children: [
136
+ {
137
+ type: "instance",
138
+ component: "DialogContent",
139
+ label: "Dialog Content",
140
+ props: [],
141
+ /**
142
+ * fixed w-full z-50
143
+ * grid gap-4 max-w-lg
144
+ * m-auto
145
+ * border bg-background p-6 shadow-lg
146
+ **/
147
+ styles: [
148
+ tc.w("full"),
149
+ tc.z(50),
150
+ tc.flex(),
151
+ tc.flex("col"),
152
+ tc.gap(4),
153
+ tc.m("auto"),
154
+ tc.maxW("lg"),
155
+ tc.border(),
156
+ tc.bg("background"),
157
+ tc.p(6),
158
+ tc.shadow("lg"),
159
+ tc.relative(),
160
+ ].flat(),
161
+ children: [
162
+ {
163
+ type: "instance",
164
+ component: "Box",
165
+ label: "Dialog Header",
166
+ props: [],
167
+ styles: [tc.flex(), tc.flex("col"), tc.gap(1)].flat(),
168
+ children: [
169
+ {
170
+ type: "instance",
171
+ component: "DialogTitle",
172
+ label: "Dialog Title",
173
+ props: [],
174
+ /**
175
+ * text-lg leading-none tracking-tight
176
+ **/
177
+ styles: [
178
+ tc.my(0),
179
+ tc.leading("none"),
180
+ tc.text("lg"),
181
+ tc.tracking("tight"),
182
+ ].flat(),
183
+ children: [
184
+ {
185
+ type: "text",
186
+ value: "Dialog Title",
187
+ },
188
+ ],
189
+ },
190
+ {
191
+ type: "instance",
192
+ component: "DialogDescription",
193
+ label: "Dialog Description",
194
+ props: [],
195
+ /**
196
+ * text-sm text-muted-foreground
197
+ **/
198
+ styles: [
199
+ tc.my(0),
200
+ tc.text("sm"),
201
+ tc.text("mutedForeground"),
202
+ ].flat(),
203
+ children: [
204
+ {
205
+ type: "text",
206
+ value: "dialog description text you can edit",
207
+ },
208
+ ],
209
+ },
210
+ ],
211
+ },
212
+
213
+ {
214
+ type: "instance",
215
+ component: "Text",
216
+ children: [{ type: "text", value: "The text you can edit" }],
217
+ },
218
+
219
+ {
220
+ type: "instance",
221
+ component: "DialogClose",
222
+ label: "Dialog Close",
223
+ props: [],
224
+ /**
225
+ * absolute right-4 top-4
226
+ * rounded-sm opacity-70
227
+ * ring-offset-background
228
+ * hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
229
+ * flex items-center justify-center h-4 w-4
230
+ **/
231
+ styles: [
232
+ tc.absolute(),
233
+ tc.right(4),
234
+ tc.top(4),
235
+ tc.rounded("sm"),
236
+ tc.opacity(70),
237
+ tc.flex(),
238
+ tc.items("center"),
239
+ tc.justify("center"),
240
+ tc.h(4),
241
+ tc.w(4),
242
+ tc.border(0),
243
+ tc.bg("transparent"),
244
+ tc.outline("none"),
245
+ tc.hover(tc.opacity(100)),
246
+ tc.focus(tc.ring("ring", 2, "background", 2)),
247
+ ].flat(),
248
+ children: [{ type: "text", value: "✕" }],
249
+ },
250
+ ],
251
+ },
252
+ ],
253
+ },
254
+ ],
255
+ },
256
+ ],
257
+ };
258
+
259
+ export const propsMetaDialog: WsComponentPropsMeta = {
260
+ props: propsDialog,
261
+ initialProps: ["isOpen", "modal"],
262
+ };
263
+
264
+ export const propsMetaDialogTrigger: WsComponentPropsMeta = {
265
+ props: propsDialogTrigger,
266
+ };
267
+
268
+ export const propsMetaDialogContent: WsComponentPropsMeta = {
269
+ props: propsDialogContent,
270
+ initialProps: [],
271
+ };
272
+
273
+ export const propsMetaDialogOverlay: WsComponentPropsMeta = {
274
+ props: propsDialogOverlay,
275
+ initialProps: [],
276
+ };
277
+
278
+ export const propsMetaDialogClose: WsComponentPropsMeta = {
279
+ props: propsDialogClose,
280
+ initialProps: [],
281
+ };
282
+
283
+ export const propsMetaDialogTitle: WsComponentPropsMeta = {
284
+ props: propsDialogTitle,
285
+ initialProps: [],
286
+ };
287
+
288
+ export const propsMetaDialogDescription: WsComponentPropsMeta = {
289
+ props: propsDialogDescription,
290
+ initialProps: [],
291
+ };
@@ -0,0 +1,89 @@
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 * as PopoverPrimitive from "@radix-ui/react-popover";
5
+ import {
6
+ splitPropsWithWebstudioAttributes,
7
+ type WebstudioAttributes,
8
+ } from "@webstudio-is/react-sdk";
9
+
10
+ import {
11
+ forwardRef,
12
+ type ElementRef,
13
+ type ComponentPropsWithoutRef,
14
+ Children,
15
+ type ReactNode,
16
+ } from "react";
17
+
18
+ /**
19
+ * We don't have support for boolean or undefined nor in UI not at Data variables,
20
+ * instead of binding on "open" prop we bind variable on a isOpen prop to be able to show Popover in the builder
21
+ **/
22
+ type BuilderPopoverProps = {
23
+ isOpen: "initial" | "open" | "closed";
24
+ };
25
+
26
+ /**
27
+ * Popover and PopoverTrigger are HTML-less components.
28
+ * To make them work in our system, we wrap their attributes with a div that has a display: contents property.
29
+ *
30
+ * These divs function like fragments, with all web studio-related attributes attached to them.
31
+ */
32
+ const DisplayContentsStyle = { display: "contents" };
33
+
34
+ export const Popover = forwardRef<
35
+ ElementRef<"div">,
36
+ WebstudioAttributes &
37
+ ComponentPropsWithoutRef<typeof PopoverPrimitive.Root> &
38
+ BuilderPopoverProps
39
+ >(({ open: openProp, isOpen, ...props }, ref) => {
40
+ const [webstudioAttributes, restProps] =
41
+ splitPropsWithWebstudioAttributes(props);
42
+
43
+ const open =
44
+ openProp ??
45
+ (isOpen === "open" ? true : isOpen === "closed" ? false : undefined);
46
+
47
+ return (
48
+ <div ref={ref} style={DisplayContentsStyle} {...webstudioAttributes}>
49
+ <PopoverPrimitive.Root open={open} {...restProps} />
50
+ </div>
51
+ );
52
+ });
53
+
54
+ /**
55
+ * We're not exposing the 'asChild' property for the Trigger.
56
+ * Instead, we're enforcing 'asChild=true' for the Trigger and making it style-less.
57
+ * This avoids situations where the Trigger inadvertently passes all styles to its child,
58
+ * which would prevent us from displaying styles properly in the builder.
59
+ */
60
+ export const PopoverTrigger = forwardRef<
61
+ ElementRef<"div">,
62
+ WebstudioAttributes & { children: ReactNode }
63
+ >(({ children, ...props }, ref) => {
64
+ const firstChild = Children.toArray(children)[0];
65
+ const [webstudioAttributes, restProps] =
66
+ splitPropsWithWebstudioAttributes(props);
67
+
68
+ return (
69
+ <div ref={ref} style={DisplayContentsStyle} {...webstudioAttributes}>
70
+ <PopoverPrimitive.Trigger asChild={true} {...restProps}>
71
+ {firstChild ?? <button>Add button or link</button>}
72
+ </PopoverPrimitive.Trigger>
73
+ </div>
74
+ );
75
+ });
76
+
77
+ export const PopoverContent = forwardRef<
78
+ ElementRef<typeof PopoverPrimitive.Content>,
79
+ ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
80
+ >(({ sideOffset = 4, align = "center", ...props }, ref) => (
81
+ <PopoverPrimitive.Portal>
82
+ <PopoverPrimitive.Content
83
+ ref={ref}
84
+ align="center"
85
+ sideOffset={sideOffset}
86
+ {...props}
87
+ />
88
+ </PopoverPrimitive.Portal>
89
+ ));