@webstudio-is/react-sdk 0.49.0 → 0.51.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 (165) hide show
  1. package/lib/app/custom-components/image.js +11 -13
  2. package/lib/app/custom-components/shared/remix-link.js +7 -24
  3. package/lib/app/handle-request.server.js +1 -4
  4. package/lib/app/root.js +11 -29
  5. package/lib/cjs/app/custom-components/image.cjs +10 -12
  6. package/lib/cjs/app/custom-components/shared/remix-link.cjs +6 -23
  7. package/lib/cjs/app/handle-request.server.cjs +1 -4
  8. package/lib/cjs/app/root.cjs +11 -29
  9. package/lib/cjs/components/__generated__/fragment.props.cjs +24 -0
  10. package/lib/cjs/components/__generated__/link-block.props.cjs +5 -5
  11. package/lib/cjs/components/__generated__/link.props.cjs +6 -6
  12. package/lib/cjs/components/__generated__/rich-text-link.props.cjs +5 -5
  13. package/lib/cjs/components/__generated__/slot.props.cjs +24 -0
  14. package/lib/cjs/components/blockquote.ws.cjs +1 -0
  15. package/lib/cjs/components/body.cjs +1 -4
  16. package/lib/cjs/components/body.ws.cjs +1 -1
  17. package/lib/cjs/components/bold.cjs +1 -4
  18. package/lib/cjs/components/box.ws.cjs +1 -0
  19. package/lib/cjs/components/button.cjs +1 -6
  20. package/lib/cjs/components/button.ws.cjs +1 -0
  21. package/lib/cjs/components/code.ws.cjs +1 -0
  22. package/lib/cjs/components/{component-type.cjs → component-meta.cjs} +22 -4
  23. package/lib/cjs/components/components-utils.cjs +6 -0
  24. package/lib/cjs/components/components.cjs +4 -0
  25. package/lib/cjs/components/form.cjs +1 -4
  26. package/lib/cjs/components/form.ws.cjs +1 -0
  27. package/lib/cjs/components/fragment.cjs +29 -0
  28. package/lib/cjs/components/fragment.ws.cjs +32 -0
  29. package/lib/cjs/components/heading.ws.cjs +1 -0
  30. package/lib/cjs/components/image.cjs +8 -5
  31. package/lib/cjs/components/image.ws.cjs +4 -0
  32. package/lib/cjs/components/index.cjs +8 -0
  33. package/lib/cjs/components/input.cjs +1 -4
  34. package/lib/cjs/components/input.ws.cjs +1 -0
  35. package/lib/cjs/components/italic.cjs +1 -4
  36. package/lib/cjs/components/link-block.cjs +1 -4
  37. package/lib/cjs/components/link-block.ws.cjs +7 -2
  38. package/lib/cjs/components/link.cjs +10 -7
  39. package/lib/cjs/components/link.ws.cjs +9 -1
  40. package/lib/cjs/components/list-item.ws.cjs +1 -0
  41. package/lib/cjs/components/list.ws.cjs +1 -0
  42. package/lib/cjs/components/paragraph.cjs +1 -4
  43. package/lib/cjs/components/paragraph.ws.cjs +1 -0
  44. package/lib/cjs/components/rich-text-link.cjs +1 -4
  45. package/lib/cjs/components/rich-text-link.ws.cjs +7 -3
  46. package/lib/cjs/components/separator.ws.cjs +1 -0
  47. package/lib/cjs/components/slot.cjs +36 -0
  48. package/lib/cjs/components/slot.ws.cjs +34 -0
  49. package/lib/cjs/components/span.cjs +1 -4
  50. package/lib/cjs/components/subscript.cjs +1 -4
  51. package/lib/cjs/components/superscript.cjs +1 -4
  52. package/lib/cjs/components/text-block.cjs +1 -4
  53. package/lib/cjs/components/text-block.ws.cjs +1 -0
  54. package/lib/cjs/context.cjs +2 -1
  55. package/lib/cjs/css/categories.cjs +6 -0
  56. package/lib/cjs/index.cjs +2 -0
  57. package/lib/cjs/props.cjs +43 -2
  58. package/lib/cjs/pubsub/create.cjs +13 -0
  59. package/lib/cjs/tree/create-elements-tree.cjs +33 -22
  60. package/lib/cjs/tree/root.cjs +1 -0
  61. package/lib/cjs/tree/session-storage-polyfill.cjs +7 -4
  62. package/lib/cjs/tree/webstudio-component.cjs +5 -10
  63. package/lib/components/__generated__/fragment.props.js +4 -0
  64. package/lib/components/__generated__/link-block.props.js +5 -5
  65. package/lib/components/__generated__/link.props.js +6 -6
  66. package/lib/components/__generated__/rich-text-link.props.js +5 -5
  67. package/lib/components/__generated__/slot.props.js +4 -0
  68. package/lib/components/blockquote.ws.js +1 -0
  69. package/lib/components/body.js +1 -4
  70. package/lib/components/body.ws.js +1 -1
  71. package/lib/components/bold.js +1 -4
  72. package/lib/components/box.ws.js +1 -0
  73. package/lib/components/button.js +1 -6
  74. package/lib/components/button.ws.js +1 -0
  75. package/lib/components/code.ws.js +1 -0
  76. package/lib/components/component-meta.js +34 -0
  77. package/lib/components/components-utils.js +2 -0
  78. package/lib/components/components.js +4 -0
  79. package/lib/components/form.js +1 -4
  80. package/lib/components/form.ws.js +1 -0
  81. package/lib/components/fragment.js +9 -0
  82. package/lib/components/fragment.ws.js +12 -0
  83. package/lib/components/heading.ws.js +1 -0
  84. package/lib/components/image.js +8 -5
  85. package/lib/components/image.ws.js +4 -0
  86. package/lib/components/index.js +8 -0
  87. package/lib/components/input.js +1 -4
  88. package/lib/components/input.ws.js +1 -0
  89. package/lib/components/italic.js +1 -4
  90. package/lib/components/link-block.js +1 -4
  91. package/lib/components/link-block.ws.js +7 -2
  92. package/lib/components/link.js +10 -7
  93. package/lib/components/link.ws.js +9 -1
  94. package/lib/components/list-item.ws.js +1 -0
  95. package/lib/components/list.ws.js +1 -0
  96. package/lib/components/paragraph.js +1 -4
  97. package/lib/components/paragraph.ws.js +1 -0
  98. package/lib/components/rich-text-link.js +1 -4
  99. package/lib/components/rich-text-link.ws.js +8 -4
  100. package/lib/components/separator.ws.js +1 -0
  101. package/lib/components/slot.js +16 -0
  102. package/lib/components/slot.ws.js +14 -0
  103. package/lib/components/span.js +1 -4
  104. package/lib/components/subscript.js +1 -4
  105. package/lib/components/superscript.js +1 -4
  106. package/lib/components/text-block.js +1 -4
  107. package/lib/components/text-block.ws.js +1 -0
  108. package/lib/context.js +2 -1
  109. package/lib/css/categories.js +6 -0
  110. package/lib/index.js +4 -0
  111. package/lib/props.js +43 -2
  112. package/lib/pubsub/create.js +9 -0
  113. package/lib/tree/create-elements-tree.js +33 -22
  114. package/lib/tree/root.js +1 -0
  115. package/lib/tree/session-storage-polyfill.js +7 -4
  116. package/lib/tree/webstudio-component.js +5 -10
  117. package/package.json +12 -16
  118. package/src/app/custom-components/image.tsx +4 -7
  119. package/src/app/custom-components/index.ts +1 -1
  120. package/src/app/custom-components/shared/remix-link.tsx +12 -48
  121. package/src/components/__generated__/fragment.props.ts +3 -0
  122. package/src/components/__generated__/link-block.props.ts +5 -5
  123. package/src/components/__generated__/link.props.ts +6 -6
  124. package/src/components/__generated__/rich-text-link.props.ts +5 -5
  125. package/src/components/__generated__/slot.props.ts +3 -0
  126. package/src/components/blockquote.ws.tsx +2 -1
  127. package/src/components/body.ws.tsx +2 -2
  128. package/src/components/bold.ws.tsx +1 -1
  129. package/src/components/box.ws.ts +2 -1
  130. package/src/components/button.ws.tsx +2 -1
  131. package/src/components/code.ws.tsx +2 -1
  132. package/src/components/{component-type.ts → component-meta.ts} +21 -23
  133. package/src/components/components-utils.ts +4 -0
  134. package/src/components/components.ts +2 -0
  135. package/src/components/form.ws.tsx +2 -1
  136. package/src/components/fragment.tsx +11 -0
  137. package/src/components/fragment.ws.ts +11 -0
  138. package/src/components/heading.ws.tsx +2 -1
  139. package/src/components/image.ws.tsx +2 -1
  140. package/src/components/index.ts +11 -1
  141. package/src/components/input.ws.tsx +2 -1
  142. package/src/components/italic.ws.tsx +1 -1
  143. package/src/components/link-block.ws.tsx +8 -3
  144. package/src/components/link.tsx +12 -6
  145. package/src/components/link.ws.tsx +10 -2
  146. package/src/components/list-item.ws.tsx +2 -1
  147. package/src/components/list.ws.tsx +2 -1
  148. package/src/components/paragraph.ws.tsx +2 -1
  149. package/src/components/rich-text-link.ws.tsx +10 -5
  150. package/src/components/separator.ws.tsx +2 -1
  151. package/src/components/slot.stories.tsx +16 -0
  152. package/src/components/slot.tsx +17 -0
  153. package/src/components/slot.ws.ts +13 -0
  154. package/src/components/span.ws.tsx +1 -1
  155. package/src/components/subscript.ws.tsx +1 -1
  156. package/src/components/superscript.ws.tsx +1 -1
  157. package/src/components/text-block.ws.tsx +2 -1
  158. package/src/context.tsx +3 -1
  159. package/src/index.ts +5 -4
  160. package/src/props.test.ts +95 -0
  161. package/src/props.ts +59 -3
  162. package/src/tree/create-elements-tree.tsx +30 -12
  163. package/src/tree/root.ts +2 -0
  164. package/src/tree/webstudio-component.tsx +1 -0
  165. package/lib/components/component-type.js +0 -20
@@ -0,0 +1,3 @@
1
+ import type { PropMeta } from "@webstudio-is/generate-arg-types";
2
+
3
+ export const props: Record<string, PropMeta> = {};
@@ -4,18 +4,18 @@ export const props: Record<string, PropMeta> = {
4
4
  slot: { required: false, control: "text", type: "string" },
5
5
  style: { required: false, control: "text", type: "string" },
6
6
  title: { required: false, control: "text", type: "string" },
7
- download: { required: false, control: "text", type: "string" },
8
7
  href: { required: false, control: "text", type: "string" },
9
- hrefLang: { required: false, control: "text", type: "string" },
10
- media: { required: false, control: "text", type: "string" },
11
- ping: { required: false, control: "text", type: "string" },
12
- rel: { required: false, control: "text", type: "string" },
13
8
  target: {
14
9
  required: false,
15
10
  control: "select",
16
11
  type: "string",
17
12
  options: ["_self", "_blank", "_parent", "_top"],
18
13
  },
14
+ download: { required: false, control: "text", type: "string" },
15
+ hrefLang: { required: false, control: "text", type: "string" },
16
+ media: { required: false, control: "text", type: "string" },
17
+ ping: { required: false, control: "text", type: "string" },
18
+ rel: { required: false, control: "text", type: "string" },
19
19
  type: { required: false, control: "text", type: "string" },
20
20
  referrerPolicy: {
21
21
  required: false,
@@ -4,18 +4,18 @@ export const props: Record<string, PropMeta> = {
4
4
  slot: { required: false, control: "text", type: "string" },
5
5
  style: { required: false, control: "text", type: "string" },
6
6
  title: { required: false, control: "text", type: "string" },
7
- download: { required: false, control: "text", type: "string" },
8
- href: { required: false, control: "text", type: "string", defaultValue: "" },
9
- hrefLang: { required: false, control: "text", type: "string" },
10
- media: { required: false, control: "text", type: "string" },
11
- ping: { required: false, control: "text", type: "string" },
12
- rel: { required: false, control: "text", type: "string" },
7
+ href: { required: false, control: "text", type: "string" },
13
8
  target: {
14
9
  required: false,
15
10
  control: "select",
16
11
  type: "string",
17
12
  options: ["_self", "_blank", "_parent", "_top"],
18
13
  },
14
+ download: { required: false, control: "text", type: "string" },
15
+ hrefLang: { required: false, control: "text", type: "string" },
16
+ media: { required: false, control: "text", type: "string" },
17
+ ping: { required: false, control: "text", type: "string" },
18
+ rel: { required: false, control: "text", type: "string" },
19
19
  type: { required: false, control: "text", type: "string" },
20
20
  referrerPolicy: {
21
21
  required: false,
@@ -4,18 +4,18 @@ export const props: Record<string, PropMeta> = {
4
4
  slot: { required: false, control: "text", type: "string" },
5
5
  style: { required: false, control: "text", type: "string" },
6
6
  title: { required: false, control: "text", type: "string" },
7
- download: { required: false, control: "text", type: "string" },
8
7
  href: { required: false, control: "text", type: "string" },
9
- hrefLang: { required: false, control: "text", type: "string" },
10
- media: { required: false, control: "text", type: "string" },
11
- ping: { required: false, control: "text", type: "string" },
12
- rel: { required: false, control: "text", type: "string" },
13
8
  target: {
14
9
  required: false,
15
10
  control: "select",
16
11
  type: "string",
17
12
  options: ["_self", "_blank", "_parent", "_top"],
18
13
  },
14
+ download: { required: false, control: "text", type: "string" },
15
+ hrefLang: { required: false, control: "text", type: "string" },
16
+ media: { required: false, control: "text", type: "string" },
17
+ ping: { required: false, control: "text", type: "string" },
18
+ rel: { required: false, control: "text", type: "string" },
19
19
  type: { required: false, control: "text", type: "string" },
20
20
  referrerPolicy: {
21
21
  required: false,
@@ -0,0 +1,3 @@
1
+ import type { PropMeta } from "@webstudio-is/generate-arg-types";
2
+
3
+ export const props: Record<string, PropMeta> = {};
@@ -1,5 +1,5 @@
1
1
  import { BlockquoteIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/blockquote.props";
4
4
 
5
5
  const presetStyle = {
@@ -42,6 +42,7 @@ const presetStyle = {
42
42
  } as const;
43
43
 
44
44
  export const meta: WsComponentMeta = {
45
+ category: "typography",
45
46
  type: "rich-text",
46
47
  label: "Blockquote",
47
48
  Icon: BlockquoteIcon,
@@ -1,5 +1,5 @@
1
1
  import { BodyIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/body.props";
4
4
 
5
5
  const presetStyle = {
@@ -53,7 +53,7 @@ const presetStyle = {
53
53
  } as const;
54
54
 
55
55
  export const meta: WsComponentMeta = {
56
- type: "body",
56
+ type: "container",
57
57
  label: "Body",
58
58
  Icon: BodyIcon,
59
59
  presetStyle,
@@ -1,5 +1,5 @@
1
1
  import { FontBoldIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/bold.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
@@ -1,5 +1,5 @@
1
1
  import { BoxIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/box.props";
4
4
 
5
5
  const presetStyle = {
@@ -10,6 +10,7 @@ const presetStyle = {
10
10
  } as const;
11
11
 
12
12
  export const meta: WsComponentMeta = {
13
+ category: "general",
13
14
  type: "container",
14
15
  label: "Box",
15
16
  Icon: BoxIcon,
@@ -1,8 +1,9 @@
1
1
  import { ButtonIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/button.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
6
+ category: "forms",
6
7
  type: "container",
7
8
  label: "Button",
8
9
  Icon: ButtonIcon,
@@ -1,5 +1,5 @@
1
1
  import { CodeIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { displayVarNamespace } from "./code";
4
4
  import { props } from "./__generated__/code.props";
5
5
 
@@ -33,6 +33,7 @@ const presetStyle: WsComponentMeta["presetStyle"] = {
33
33
  };
34
34
 
35
35
  export const meta: WsComponentMeta = {
36
+ category: "general",
36
37
  type: "rich-text",
37
38
  label: "Code",
38
39
  Icon: CodeIcon,
@@ -13,31 +13,21 @@ const WsComponentPropsMeta = z.object({
13
13
 
14
14
  export type WsComponentPropsMeta = z.infer<typeof WsComponentPropsMeta>;
15
15
 
16
- export type WsComponentMeta = {
17
- /**
18
- * body - can accept other components with dnd but not listed
19
- * container - can accept other components with dnd
20
- * control - usually form controls like inputs, without children
21
- * embed - images, videos or other embeddable components, without children
22
- * rich-text - editable text component
23
- * rich-text-child - formatted text fragment, not listed in components list
24
- */
25
- type:
26
- | "body"
27
- | "container"
28
- | "control"
29
- | "embed"
30
- | "rich-text"
31
- | "rich-text-child";
32
- label: string;
33
- Icon: FunctionComponent<IconProps>;
34
- presetStyle?: Style;
35
- children?: Array<string>;
36
- };
16
+ export const componentCategories = [
17
+ "general",
18
+ "typography",
19
+ "media",
20
+ "forms",
21
+ ] as const;
37
22
 
38
23
  const WsComponentMeta = z.object({
24
+ category: z.enum(componentCategories).optional(),
25
+ // container - can accept other components with dnd
26
+ // control - usually form controls like inputs, without children
27
+ // embed - images, videos or other embeddable components, without children
28
+ // rich-text - editable text component
29
+ // rich-text-child - formatted text fragment, not listed in components list
39
30
  type: z.enum([
40
- "body",
41
31
  "container",
42
32
  "control",
43
33
  "embed",
@@ -45,7 +35,15 @@ const WsComponentMeta = z.object({
45
35
  "rich-text-child",
46
36
  ]),
47
37
  label: z.string(),
48
- Icon: z.any(),
38
+ Icon: z.function(),
49
39
  presetStyle: z.optional(z.any()),
50
40
  children: z.optional(z.array(z.string())),
51
41
  });
42
+
43
+ export type WsComponentMeta = Omit<
44
+ z.infer<typeof WsComponentMeta>,
45
+ "presetStyle" | "Icon"
46
+ > & {
47
+ presetStyle?: Style;
48
+ Icon: FunctionComponent<IconProps>;
49
+ };
@@ -6,8 +6,12 @@ export type ComponentName = keyof typeof components;
6
6
  /**
7
7
  * We need to define component names manually here, instead of using Object.keys(components)
8
8
  * Otherwise every component would be included in the bundle, even if it is not used
9
+ *
10
+ * @todo this list should not be hardcoded!
9
11
  */
10
12
  const componentNames = Object.keys({
13
+ Slot: 1,
14
+ Fragment: 1,
11
15
  Box: 1,
12
16
  Body: 1,
13
17
  TextBlock: 1,
@@ -5,6 +5,8 @@
5
5
  * getComponent = createGetComponent({ Box, BlaBla })to pass them to RootInstance
6
6
  * see example /packages/sdk-size-test/app/routes/$.tsx
7
7
  */
8
+ export { Slot } from "./slot";
9
+ export { Fragment } from "./fragment";
8
10
  export { Body } from "./body";
9
11
  export { Box } from "./box";
10
12
  export { TextBlock } from "./text-block";
@@ -1,5 +1,5 @@
1
1
  import { FormIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/form.props";
4
4
 
5
5
  const presetStyle = {
@@ -15,6 +15,7 @@ const presetStyle = {
15
15
  } as const;
16
16
 
17
17
  export const meta: WsComponentMeta = {
18
+ category: "forms",
18
19
  type: "container",
19
20
  label: "Form",
20
21
  Icon: FormIcon,
@@ -0,0 +1,11 @@
1
+ import { forwardRef, type ElementRef, type ReactNode } from "react";
2
+
3
+ type Props = {
4
+ children?: ReactNode;
5
+ };
6
+
7
+ export const Fragment = forwardRef<ElementRef<"div">, Props>((props, ref) => {
8
+ return <div {...props} ref={ref} style={{ display: "contents" }} />;
9
+ });
10
+
11
+ Fragment.displayName = "Fragment";
@@ -0,0 +1,11 @@
1
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
2
+
3
+ export const meta: WsComponentMeta = {
4
+ type: "container",
5
+ label: "Fragment",
6
+ Icon: () => null,
7
+ };
8
+
9
+ export const propsMeta: WsComponentPropsMeta = {
10
+ props: {},
11
+ };
@@ -1,8 +1,9 @@
1
1
  import { HeadingIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/heading.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
6
+ category: "typography",
6
7
  type: "rich-text",
7
8
  label: "Heading",
8
9
  Icon: HeadingIcon,
@@ -1,5 +1,5 @@
1
1
  import { ImageIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/image.props";
4
4
 
5
5
  const presetStyle = {
@@ -18,6 +18,7 @@ const presetStyle = {
18
18
  } as const;
19
19
 
20
20
  export const meta: WsComponentMeta = {
21
+ category: "media",
21
22
  type: "embed",
22
23
  label: "Image",
23
24
  Icon: ImageIcon,
@@ -1,6 +1,8 @@
1
1
  import { PropMeta } from "@webstudio-is/generate-arg-types";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import type { ComponentName } from "./components-utils";
4
+ import { meta as SlotMeta } from "./slot.ws";
5
+ import { meta as FragmentMeta } from "./fragment.ws";
4
6
  import { meta as BodyMeta } from "./body.ws";
5
7
  import { meta as BoxMeta } from "./box.ws";
6
8
  import { meta as TextBlockMeta } from "./text-block.ws";
@@ -25,6 +27,8 @@ import { meta as SeparatorMeta } from "./separator.ws";
25
27
  import { meta as CodeMeta } from "./code.ws";
26
28
 
27
29
  // these are huge JSON objects that we want to be tree-shaken when not used!
30
+ import { propsMeta as SlotMetaPropsMeta } from "./slot.ws";
31
+ import { propsMeta as FragmentMetaPropsMeta } from "./fragment.ws";
28
32
  import { propsMeta as BodyMetaPropsMeta } from "./body.ws";
29
33
  import { propsMeta as BoxMetaPropsMeta } from "./box.ws";
30
34
  import { propsMeta as TextBlockMetaPropsMeta } from "./text-block.ws";
@@ -48,7 +52,10 @@ import { propsMeta as ListItemPropsMeta } from "./list-item.ws";
48
52
  import { propsMeta as SeparatorPropsMeta } from "./separator.ws";
49
53
  import { propsMeta as CodePropsMeta } from "./code.ws";
50
54
 
55
+ // @todo this list should not be hardcoded!
51
56
  const defaultMetas: Record<string, WsComponentMeta> = {
57
+ Slot: SlotMeta,
58
+ Fragment: FragmentMeta,
52
59
  Box: BoxMeta,
53
60
  Body: BodyMeta,
54
61
  TextBlock: TextBlockMeta,
@@ -89,7 +96,10 @@ export const registerComponentMetas = (
89
96
  currentMetas = result;
90
97
  };
91
98
 
99
+ // @todo this list should not be hardcoded!
92
100
  const defaultPropsMetasRaw = {
101
+ Slot: SlotMetaPropsMeta,
102
+ Fragment: FragmentMetaPropsMeta,
93
103
  Box: BoxMetaPropsMeta,
94
104
  Body: BodyMetaPropsMeta,
95
105
  TextBlock: TextBlockMetaPropsMeta,
@@ -1,8 +1,9 @@
1
1
  import { InputIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/input.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
6
+ category: "forms",
6
7
  type: "control",
7
8
  label: "Input",
8
9
  Icon: InputIcon,
@@ -1,5 +1,5 @@
1
1
  import { FontItalicIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/italic.props";
4
4
 
5
5
  const presetStyle = {
@@ -1,6 +1,7 @@
1
1
  import { BoxLinkIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/link-block.props";
4
+ import { propsMeta as linkPropsMeta } from "./link.ws";
4
5
 
5
6
  const presetStyle = {
6
7
  boxSizing: {
@@ -14,6 +15,7 @@ const presetStyle = {
14
15
  } as const;
15
16
 
16
17
  export const meta: WsComponentMeta = {
18
+ category: "general",
17
19
  type: "container",
18
20
  label: "Link Block",
19
21
  Icon: BoxLinkIcon,
@@ -21,6 +23,9 @@ export const meta: WsComponentMeta = {
21
23
  };
22
24
 
23
25
  export const propsMeta: WsComponentPropsMeta = {
24
- props,
25
- initialProps: ["href", "target", "prefetch"],
26
+ props: {
27
+ ...props,
28
+ href: linkPropsMeta.props.href,
29
+ },
30
+ initialProps: linkPropsMeta.initialProps,
26
31
  };
@@ -1,4 +1,5 @@
1
- import { forwardRef, type ElementRef, type ComponentProps } from "react";
1
+ import { forwardRef, type ComponentProps } from "react";
2
+ import { usePropUrl, getInstanceIdFromComponentProps } from "../props";
2
3
 
3
4
  // @todo props that come from remix link, shouldn't be here at all
4
5
  // - prefetch should be only on remix component and it already is
@@ -10,10 +11,15 @@ type Props = Omit<ComponentProps<"a">, "href" | "target"> & {
10
11
  prefetch?: "none" | "intent" | "render";
11
12
  };
12
13
 
13
- export const Link = forwardRef<ElementRef<"a">, Props>(
14
- ({ href = "", ...props }, ref) => {
15
- return <a {...props} href={href} ref={ref} />;
16
- }
17
- );
14
+ export const Link = forwardRef<HTMLAnchorElement, Props>((props, ref) => {
15
+ const href = usePropUrl(getInstanceIdFromComponentProps(props), "href");
16
+ return (
17
+ <a
18
+ {...props}
19
+ href={typeof href === "string" ? href : href?.path}
20
+ ref={ref}
21
+ />
22
+ );
23
+ });
18
24
 
19
25
  Link.displayName = "Link";
@@ -1,5 +1,5 @@
1
1
  import { Link2Icon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/link.props";
4
4
 
5
5
  const presetStyle = {
@@ -15,6 +15,7 @@ const presetStyle = {
15
15
  } as const;
16
16
 
17
17
  export const meta: WsComponentMeta = {
18
+ category: "general",
18
19
  type: "rich-text",
19
20
  label: "Link Text",
20
21
  Icon: Link2Icon,
@@ -23,6 +24,13 @@ export const meta: WsComponentMeta = {
23
24
  };
24
25
 
25
26
  export const propsMeta: WsComponentPropsMeta = {
26
- props,
27
+ props: {
28
+ ...props,
29
+ href: {
30
+ type: "string",
31
+ control: "url",
32
+ required: false,
33
+ },
34
+ },
27
35
  initialProps: ["href", "target", "prefetch"],
28
36
  };
@@ -1,8 +1,9 @@
1
1
  import { ListItemIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/list-item.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
6
+ category: "typography",
6
7
  type: "rich-text",
7
8
  label: "List Item",
8
9
  Icon: ListItemIcon,
@@ -1,5 +1,5 @@
1
1
  import { ListIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/list.props";
4
4
 
5
5
  const presetStyle = {
@@ -18,6 +18,7 @@ const presetStyle = {
18
18
  } as const;
19
19
 
20
20
  export const meta: WsComponentMeta = {
21
+ category: "typography",
21
22
  type: "container",
22
23
  label: "List",
23
24
  Icon: ListIcon,
@@ -1,8 +1,9 @@
1
1
  import { TextAlignLeftIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/paragraph.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
6
+ category: "typography",
6
7
  type: "rich-text",
7
8
  label: "Paragraph",
8
9
  Icon: TextAlignLeftIcon,
@@ -1,14 +1,19 @@
1
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
1
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
2
2
  import { props } from "./__generated__/rich-text-link.props";
3
- import { meta as linkMeta, propsMeta as propsLinkMeta } from "./link.ws";
3
+ import { meta as linkMeta, propsMeta as linkPropsMeta } from "./link.ws";
4
+
5
+ const { category, ...linkMetaRest } = linkMeta;
4
6
 
5
7
  export const meta: WsComponentMeta = {
6
- ...linkMeta,
8
+ ...linkMetaRest,
7
9
  type: "rich-text-child",
8
10
  children: [],
9
11
  };
10
12
 
11
13
  export const propsMeta: WsComponentPropsMeta = {
12
- ...propsLinkMeta,
13
- props,
14
+ initialProps: linkPropsMeta.initialProps,
15
+ props: {
16
+ ...props,
17
+ href: linkPropsMeta.props.href,
18
+ },
14
19
  };
@@ -1,5 +1,5 @@
1
1
  import { DashIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/separator.props";
4
4
 
5
5
  const presetStyle = {
@@ -18,6 +18,7 @@ const presetStyle = {
18
18
  } as const;
19
19
 
20
20
  export const meta: WsComponentMeta = {
21
+ category: "general",
21
22
  type: "embed",
22
23
  label: "Separator",
23
24
  Icon: DashIcon,
@@ -0,0 +1,16 @@
1
+ import type { ComponentStory, ComponentMeta } from "@storybook/react";
2
+ import { Slot as SlotPrimitive } from "./slot";
3
+
4
+ export default {
5
+ title: "Components/Slot",
6
+ component: SlotPrimitive,
7
+ } as ComponentMeta<typeof SlotPrimitive>;
8
+
9
+ const Template: ComponentStory<typeof SlotPrimitive> = (args) => (
10
+ <SlotPrimitive {...args} />
11
+ );
12
+
13
+ export const Slot = Template.bind({});
14
+ Slot.args = {
15
+ children: "Slot",
16
+ };
@@ -0,0 +1,17 @@
1
+ import { forwardRef, type ElementRef, type ReactNode } from "react";
2
+
3
+ type Props = {
4
+ children?: ReactNode;
5
+ };
6
+
7
+ export const Slot = forwardRef<ElementRef<"div">, Props>((props, ref) => {
8
+ return (
9
+ <div
10
+ {...props}
11
+ ref={ref}
12
+ style={{ display: props.children ? "contents" : "block" }}
13
+ />
14
+ );
15
+ });
16
+
17
+ Slot.displayName = "Slot";
@@ -0,0 +1,13 @@
1
+ import { SlotComponentIcon } from "@webstudio-is/icons";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
+
4
+ export const meta: WsComponentMeta = {
5
+ category: "general",
6
+ type: "container",
7
+ label: "Slot",
8
+ Icon: SlotComponentIcon,
9
+ };
10
+
11
+ export const propsMeta: WsComponentPropsMeta = {
12
+ props: {},
13
+ };
@@ -1,5 +1,5 @@
1
1
  import { BrushIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/span.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
@@ -1,5 +1,5 @@
1
1
  import { SubscriptIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/subscript.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
@@ -1,5 +1,5 @@
1
1
  import { SuperscriptIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/superscript.props";
4
4
 
5
5
  export const meta: WsComponentMeta = {
@@ -1,5 +1,5 @@
1
1
  import { TextIcon } from "@webstudio-is/icons";
2
- import type { WsComponentMeta, WsComponentPropsMeta } from "./component-type";
2
+ import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
3
3
  import { props } from "./__generated__/text-block.props";
4
4
 
5
5
  const presetStyle = {
@@ -11,6 +11,7 @@ const presetStyle = {
11
11
  } as const;
12
12
 
13
13
  export const meta: WsComponentMeta = {
14
+ category: "typography",
14
15
  type: "rich-text",
15
16
  label: "Text Block",
16
17
  Icon: TextIcon,