@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
@@ -1,6 +1,7 @@
1
1
  import { ListItemIcon } from "@webstudio-is/icons";
2
2
  import { props } from "./__generated__/list-item.props";
3
3
  const meta = {
4
+ category: "typography",
4
5
  type: "rich-text",
5
6
  label: "List Item",
6
7
  Icon: ListItemIcon,
@@ -15,6 +15,7 @@ const presetStyle = {
15
15
  }
16
16
  };
17
17
  const meta = {
18
+ category: "typography",
18
19
  type: "container",
19
20
  label: "List",
20
21
  Icon: ListIcon,
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  const defaultTag = "p";
4
- const Paragraph = forwardRef((props, ref) => /* @__PURE__ */ jsx("p", {
5
- ...props,
6
- ref
7
- }));
4
+ const Paragraph = forwardRef((props, ref) => /* @__PURE__ */ jsx("p", { ...props, ref }));
8
5
  Paragraph.displayName = "Paragraph";
9
6
  export {
10
7
  Paragraph
@@ -1,6 +1,7 @@
1
1
  import { TextAlignLeftIcon } from "@webstudio-is/icons";
2
2
  import { props } from "./__generated__/paragraph.props";
3
3
  const meta = {
4
+ category: "typography",
4
5
  type: "rich-text",
5
6
  label: "Paragraph",
6
7
  Icon: TextAlignLeftIcon,
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { Link } from "./link";
4
- const RichTextLink = forwardRef((props, ref) => /* @__PURE__ */ jsx(Link, {
5
- ...props,
6
- ref
7
- }));
4
+ const RichTextLink = forwardRef((props, ref) => /* @__PURE__ */ jsx(Link, { ...props, ref }));
8
5
  RichTextLink.displayName = "RichTextLink";
9
6
  export {
10
7
  RichTextLink
@@ -1,13 +1,17 @@
1
1
  import { props } from "./__generated__/rich-text-link.props";
2
- import { meta as linkMeta, propsMeta as propsLinkMeta } from "./link.ws";
2
+ import { meta as linkMeta, propsMeta as linkPropsMeta } from "./link.ws";
3
+ const { category, ...linkMetaRest } = linkMeta;
3
4
  const meta = {
4
- ...linkMeta,
5
+ ...linkMetaRest,
5
6
  type: "rich-text-child",
6
7
  children: []
7
8
  };
8
9
  const propsMeta = {
9
- ...propsLinkMeta,
10
- props
10
+ initialProps: linkPropsMeta.initialProps,
11
+ props: {
12
+ ...props,
13
+ href: linkPropsMeta.props.href
14
+ }
11
15
  };
12
16
  export {
13
17
  meta,
@@ -15,6 +15,7 @@ const presetStyle = {
15
15
  }
16
16
  };
17
17
  const meta = {
18
+ category: "general",
18
19
  type: "embed",
19
20
  label: "Separator",
20
21
  Icon: DashIcon,
@@ -0,0 +1,16 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ const Slot = forwardRef((props, ref) => {
4
+ return /* @__PURE__ */ jsx(
5
+ "div",
6
+ {
7
+ ...props,
8
+ ref,
9
+ style: { display: props.children ? "contents" : "block" }
10
+ }
11
+ );
12
+ });
13
+ Slot.displayName = "Slot";
14
+ export {
15
+ Slot
16
+ };
@@ -0,0 +1,14 @@
1
+ import { SlotComponentIcon } from "@webstudio-is/icons";
2
+ const meta = {
3
+ category: "general",
4
+ type: "container",
5
+ label: "Slot",
6
+ Icon: SlotComponentIcon
7
+ };
8
+ const propsMeta = {
9
+ props: {}
10
+ };
11
+ export {
12
+ meta,
13
+ propsMeta
14
+ };
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  const defaultTag = "span";
4
- const Span = forwardRef((props, ref) => /* @__PURE__ */ jsx("span", {
5
- ...props,
6
- ref
7
- }));
4
+ const Span = forwardRef((props, ref) => /* @__PURE__ */ jsx("span", { ...props, ref }));
8
5
  Span.displayName = "Span";
9
6
  export {
10
7
  Span
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  const defaultTag = "sub";
4
- const Subscript = forwardRef((props, ref) => /* @__PURE__ */ jsx("sub", {
5
- ...props,
6
- ref
7
- }));
4
+ const Subscript = forwardRef((props, ref) => /* @__PURE__ */ jsx("sub", { ...props, ref }));
8
5
  Subscript.displayName = "Subscript";
9
6
  export {
10
7
  Subscript
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  const defaultTag = "sup";
4
- const Superscript = forwardRef((props, ref) => /* @__PURE__ */ jsx("sup", {
5
- ...props,
6
- ref
7
- }));
4
+ const Superscript = forwardRef((props, ref) => /* @__PURE__ */ jsx("sup", { ...props, ref }));
8
5
  Superscript.displayName = "Bold";
9
6
  export {
10
7
  Superscript
@@ -1,10 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  const defaultTag = "div";
4
- const TextBlock = forwardRef((props, ref) => /* @__PURE__ */ jsx("div", {
5
- ...props,
6
- ref
7
- }));
4
+ const TextBlock = forwardRef((props, ref) => /* @__PURE__ */ jsx("div", { ...props, ref }));
8
5
  TextBlock.displayName = "TextBlock";
9
6
  export {
10
7
  TextBlock
@@ -8,6 +8,7 @@ const presetStyle = {
8
8
  }
9
9
  };
10
10
  const meta = {
11
+ category: "typography",
11
12
  type: "rich-text",
12
13
  label: "Text Block",
13
14
  Icon: TextIcon,
package/lib/context.js CHANGED
@@ -2,7 +2,8 @@ import { atom } from "nanostores";
2
2
  import { createContext } from "react";
3
3
  const ReactSdkContext = createContext({
4
4
  propsByInstanceIdStore: atom(/* @__PURE__ */ new Map()),
5
- assetsStore: atom(/* @__PURE__ */ new Map())
5
+ assetsStore: atom(/* @__PURE__ */ new Map()),
6
+ pagesStore: atom(/* @__PURE__ */ new Map())
6
7
  });
7
8
  export {
8
9
  ReactSdkContext
@@ -1,10 +1,13 @@
1
1
  const layout = [
2
2
  "display",
3
+ // Flex
3
4
  "flexDirection",
4
5
  "flexWrap",
6
+ // Flex or grid
5
7
  "alignItems",
6
8
  "justifyContent",
7
9
  "alignContent",
10
+ // Grid
8
11
  "justifyItems",
9
12
  "rowGap",
10
13
  "columnGap",
@@ -85,6 +88,7 @@ const typography = [
85
88
  "direction",
86
89
  "whiteSpace",
87
90
  "textShadow",
91
+ // More
88
92
  "fontSizeAdjust",
89
93
  "fontStretch",
90
94
  "fontVariant",
@@ -125,6 +129,7 @@ const borders = [
125
129
  "borderRightWidth",
126
130
  "borderBottomWidth",
127
131
  "borderLeftWidth",
132
+ // More
128
133
  "borderImageSlice",
129
134
  "borderImageWidth",
130
135
  "borderImageOutset",
@@ -143,6 +148,7 @@ const effects = [
143
148
  "filter",
144
149
  "backdropFilter",
145
150
  "cursor",
151
+ // More
146
152
  "animationDelay",
147
153
  "animationDirection",
148
154
  "animationDuration",
package/lib/index.js CHANGED
@@ -10,7 +10,11 @@ import {
10
10
  customComponentMetas,
11
11
  customComponentPropsMetas
12
12
  } from "./app/custom-components";
13
+ import {
14
+ componentCategories
15
+ } from "./components/component-meta";
13
16
  export {
17
+ componentCategories,
14
18
  customComponentMetas,
15
19
  customComponentPropsMetas,
16
20
  customComponents
package/lib/props.js CHANGED
@@ -2,6 +2,7 @@ import { useContext, useMemo } from "react";
2
2
  import { computed } from "nanostores";
3
3
  import { useStore } from "@nanostores/react";
4
4
  import { ReactSdkContext } from "./context";
5
+ import { idAttribute } from "./tree/webstudio-component";
5
6
  const getPropsByInstanceId = (props) => {
6
7
  const propsByInstanceId = /* @__PURE__ */ new Map();
7
8
  for (const prop of props.values()) {
@@ -36,7 +37,7 @@ const usePropAsset = (instanceId, name) => {
36
37
  (propsByInstanceId, assets) => {
37
38
  const instanceProps = propsByInstanceId.get(instanceId);
38
39
  if (instanceProps === void 0) {
39
- return void 0;
40
+ return;
40
41
  }
41
42
  for (const prop of instanceProps) {
42
43
  if (prop.type === "asset" && prop.name === name) {
@@ -50,8 +51,48 @@ const usePropAsset = (instanceId, name) => {
50
51
  const asset = useStore(assetStore);
51
52
  return asset;
52
53
  };
54
+ const resolveUrlProp = (instanceId, name, propsByInstanceId, pages) => {
55
+ const instanceProps = propsByInstanceId.get(instanceId);
56
+ if (instanceProps === void 0) {
57
+ return;
58
+ }
59
+ for (const prop of instanceProps) {
60
+ if (prop.name !== name) {
61
+ continue;
62
+ }
63
+ if (prop.type === "page") {
64
+ return pages.get(prop.value);
65
+ }
66
+ if (prop.type === "string") {
67
+ for (const page of pages.values()) {
68
+ if (page.path === prop.value) {
69
+ return page;
70
+ }
71
+ }
72
+ return prop.value;
73
+ }
74
+ return;
75
+ }
76
+ };
77
+ const usePropUrl = (instanceId, name) => {
78
+ const { propsByInstanceIdStore, pagesStore } = useContext(ReactSdkContext);
79
+ const pageStore = useMemo(
80
+ () => computed(
81
+ [propsByInstanceIdStore, pagesStore],
82
+ (propsByInstanceId, pages) => resolveUrlProp(instanceId, name, propsByInstanceId, pages)
83
+ ),
84
+ [propsByInstanceIdStore, pagesStore, instanceId, name]
85
+ );
86
+ return useStore(pageStore);
87
+ };
88
+ const getInstanceIdFromComponentProps = (props) => {
89
+ return props[idAttribute];
90
+ };
53
91
  export {
92
+ getInstanceIdFromComponentProps,
54
93
  getPropsByInstanceId,
94
+ resolveUrlProp,
55
95
  useInstanceProps,
56
- usePropAsset
96
+ usePropAsset,
97
+ usePropUrl
57
98
  };
@@ -14,10 +14,16 @@ const createPubsub = () => {
14
14
  );
15
15
  }
16
16
  return {
17
+ /**
18
+ * To publish a postMessage event on the current window and parent window from the iframe.
19
+ */
17
20
  publish(action) {
18
21
  window.parent.postMessage(action, "*");
19
22
  window.postMessage(action, "*");
20
23
  },
24
+ /**
25
+ * To publish a postMessage event on the iframe and parent window from the parent window.
26
+ */
21
27
  usePublish() {
22
28
  const iframeRef = useRef(null);
23
29
  const publishCallback = useCallback(
@@ -33,6 +39,9 @@ const createPubsub = () => {
33
39
  );
34
40
  return [publishCallback, iframeRef];
35
41
  },
42
+ /**
43
+ * To subscribe a message event on the current window.
44
+ */
36
45
  useSubscribe(type, onAction) {
37
46
  useEffect(() => {
38
47
  emitter.on(type, onAction);
@@ -8,35 +8,41 @@ const createElementsTree = ({
8
8
  instance,
9
9
  propsByInstanceIdStore,
10
10
  assetsStore,
11
+ pagesStore,
11
12
  Component,
12
13
  getComponent
13
14
  }) => {
15
+ const rootInstanceSelector = [instance.id];
14
16
  const children = createInstanceChildrenElements({
17
+ instanceSelector: rootInstanceSelector,
15
18
  Component,
16
19
  children: instance.children,
17
20
  getComponent
18
21
  });
19
- const body = createInstanceElement({
22
+ const root = createInstanceElement({
20
23
  Component,
21
24
  instance,
25
+ instanceSelector: rootInstanceSelector,
22
26
  children: [
23
- /* @__PURE__ */ jsxs(Fragment, {
24
- children: [
25
- children,
26
- sandbox && /* @__PURE__ */ jsx(SessionStoragePolyfill, {}),
27
- /* @__PURE__ */ jsx(ScrollRestoration, {}),
28
- /* @__PURE__ */ jsx(Scripts, {})
29
- ]
30
- }, "children")
27
+ /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ children,
29
+ sandbox && /* @__PURE__ */ jsx(SessionStoragePolyfill, {}),
30
+ /* @__PURE__ */ jsx(ScrollRestoration, {}),
31
+ /* @__PURE__ */ jsx(Scripts, {})
32
+ ] }, "children")
31
33
  ],
32
34
  getComponent
33
35
  });
34
- return /* @__PURE__ */ jsx(ReactSdkContext.Provider, {
35
- value: { propsByInstanceIdStore, assetsStore },
36
- children: body
37
- });
36
+ return /* @__PURE__ */ jsx(
37
+ ReactSdkContext.Provider,
38
+ {
39
+ value: { propsByInstanceIdStore, assetsStore, pagesStore },
40
+ children: root
41
+ }
42
+ );
38
43
  };
39
44
  const createInstanceChildrenElements = ({
45
+ instanceSelector,
40
46
  children,
41
47
  Component,
42
48
  getComponent
@@ -47,13 +53,16 @@ const createInstanceChildrenElements = ({
47
53
  elements.push(child.value);
48
54
  continue;
49
55
  }
56
+ const childInstanceSelector = [child.id, ...instanceSelector];
50
57
  const children2 = createInstanceChildrenElements({
58
+ instanceSelector: childInstanceSelector,
51
59
  children: child.children,
52
60
  Component,
53
61
  getComponent
54
62
  });
55
63
  const element = createInstanceElement({
56
64
  instance: child,
65
+ instanceSelector: childInstanceSelector,
57
66
  Component,
58
67
  children: children2,
59
68
  getComponent
@@ -65,18 +74,20 @@ const createInstanceChildrenElements = ({
65
74
  const createInstanceElement = ({
66
75
  Component,
67
76
  instance,
77
+ instanceSelector,
68
78
  children = [],
69
79
  getComponent
70
80
  }) => {
71
- const props = {
72
- instance,
73
- children,
74
- key: instance.id,
75
- getComponent
76
- };
77
- return /* @__PURE__ */ jsx(Component, {
78
- ...props
79
- });
81
+ return /* @__PURE__ */ jsx(
82
+ Component,
83
+ {
84
+ instance,
85
+ instanceSelector,
86
+ getComponent,
87
+ children
88
+ },
89
+ instance.id
90
+ );
80
91
  };
81
92
  export {
82
93
  createElementsTree
package/lib/tree/root.js CHANGED
@@ -52,6 +52,7 @@ const InstanceRoot = ({
52
52
  getPropsByInstanceId(new Map(data.build.props))
53
53
  ),
54
54
  assetsStore: atom(new Map(data.assets.map((asset) => [asset.id, asset]))),
55
+ pagesStore: atom(new Map(data.pages.map((page) => [page.id, page]))),
55
56
  Component: Component ?? WebstudioComponent,
56
57
  getComponent
57
58
  });
@@ -33,10 +33,13 @@ const polyfill = function() {
33
33
  });
34
34
  }
35
35
  }.toString();
36
- const SessionStoragePolyfill = () => /* @__PURE__ */ jsx("script", {
37
- dangerouslySetInnerHTML: { __html: `(${polyfill})()` },
38
- suppressHydrationWarning: true
39
- });
36
+ const SessionStoragePolyfill = () => /* @__PURE__ */ jsx(
37
+ "script",
38
+ {
39
+ dangerouslySetInnerHTML: { __html: `(${polyfill})()` },
40
+ suppressHydrationWarning: true
41
+ }
42
+ );
40
43
  export {
41
44
  SessionStoragePolyfill
42
45
  };
@@ -3,12 +3,10 @@ import { Fragment as Fragment2 } from "react";
3
3
  import { useInstanceProps } from "../props";
4
4
  const renderText = (text) => {
5
5
  const lines = text.split("\n");
6
- return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment2, {
7
- children: [
8
- line,
9
- index < lines.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
10
- ]
11
- }, index));
6
+ return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment2, { children: [
7
+ line,
8
+ index < lines.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
9
+ ] }, index));
12
10
  };
13
11
  const renderWebstudioComponentChildren = (children) => {
14
12
  if (children === void 0 || children.length === 0) {
@@ -35,10 +33,7 @@ const WebstudioComponent = ({
35
33
  if (Component === void 0) {
36
34
  return /* @__PURE__ */ jsx(Fragment, {});
37
35
  }
38
- return /* @__PURE__ */ jsx(Component, {
39
- ...props,
40
- children: renderWebstudioComponentChildren(children)
41
- });
36
+ return /* @__PURE__ */ jsx(Component, { ...props, children: renderWebstudioComponentChildren(children) });
42
37
  };
43
38
  const idAttribute = "data-ws-id";
44
39
  const componentAttribute = "data-ws-component";
package/package.json CHANGED
@@ -1,28 +1,24 @@
1
1
  {
2
2
  "name": "@webstudio-is/react-sdk",
3
- "version": "0.49.0",
3
+ "version": "0.51.0",
4
4
  "description": "Webstudio JavaScript / TypeScript API",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
7
7
  "type": "module",
8
8
  "devDependencies": {
9
9
  "@babel/core": "^7.21.0",
10
- "@esbuild-kit/esm-loader": "^2.4.2",
11
10
  "@jest/globals": "^29.3.1",
12
- "@remix-run/node": "1.12.0",
13
- "@remix-run/react": "1.12.0",
14
- "@remix-run/server-runtime": "1.12.0",
11
+ "@remix-run/node": "1.14.3",
12
+ "@remix-run/react": "1.14.3",
13
+ "@remix-run/server-runtime": "1.14.3",
15
14
  "@storybook/react": "^6.5.16",
16
15
  "@types/node": "^18.11.18",
17
16
  "@types/react": "^17.0.24",
18
17
  "@types/react-dom": "^17.0.9",
19
- "esbuild": "^0.14.25",
20
- "esbuild-node-externals": "^1.4.1",
21
18
  "jest": "^29.3.1",
22
19
  "react": "^17.0.2",
23
20
  "react-dom": "^17.0.2",
24
21
  "remix-utils": "^4.1.0",
25
- "tsx": "^3.9.0",
26
22
  "typescript": "4.9.5",
27
23
  "zod": "^3.19.1",
28
24
  "@webstudio-is/jest-config": "^1.0.2",
@@ -44,14 +40,14 @@
44
40
  "mitt": "^3.0.0",
45
41
  "nanostores": "^0.7.1",
46
42
  "warn-once": "^0.1.1",
47
- "@webstudio-is/asset-uploader": "^0.49.0",
48
- "@webstudio-is/css-data": "^0.49.0",
49
- "@webstudio-is/css-vars": "^0.49.0",
50
- "@webstudio-is/generate-arg-types": "^0.49.0",
51
- "@webstudio-is/icons": "^0.49.0",
52
- "@webstudio-is/image": "^0.49.0",
53
- "@webstudio-is/prisma-client": "^0.49.0",
54
- "@webstudio-is/project-build": "^0.49.0"
43
+ "@webstudio-is/asset-uploader": "^0.51.0",
44
+ "@webstudio-is/css-data": "^0.51.0",
45
+ "@webstudio-is/css-vars": "^0.51.0",
46
+ "@webstudio-is/generate-arg-types": "^0.51.0",
47
+ "@webstudio-is/icons": "^0.51.0",
48
+ "@webstudio-is/image": "^0.51.0",
49
+ "@webstudio-is/prisma-client": "^0.51.0",
50
+ "@webstudio-is/project-build": "^0.51.0"
55
51
  },
56
52
  "exports": {
57
53
  ".": {
@@ -1,24 +1,21 @@
1
1
  import {
2
2
  forwardRef,
3
3
  useMemo,
4
- type ComponentProps,
4
+ type ComponentPropsWithoutRef,
5
5
  type ElementRef,
6
6
  } from "react";
7
7
  import { Image as WebstudioImage, loaders } from "@webstudio-is/image";
8
8
  import { Image as SdkImage } from "../../components/image";
9
- import { usePropAsset } from "../../props";
10
- import { idAttribute } from "../../tree/webstudio-component";
9
+ import { usePropAsset, getInstanceIdFromComponentProps } from "../../props";
11
10
  import { getParams } from "../params";
12
11
 
13
12
  const defaultTag = "img";
14
13
 
15
- type Props = ComponentProps<typeof WebstudioImage> & { [idAttribute]: string };
14
+ type Props = ComponentPropsWithoutRef<typeof WebstudioImage>;
16
15
 
17
16
  export const Image = forwardRef<ElementRef<typeof defaultTag>, Props>(
18
17
  (props, ref) => {
19
- const componentId = props[idAttribute] as string;
20
-
21
- const asset = usePropAsset(componentId, "src");
18
+ const asset = usePropAsset(getInstanceIdFromComponentProps(props), "src");
22
19
  const params = getParams();
23
20
 
24
21
  const loader = useMemo(() => {
@@ -3,7 +3,7 @@ import { Link } from "./link";
3
3
  import { LinkBlock } from "./link-block";
4
4
  import { RichTextLink } from "./rich-text-link";
5
5
  import { imageProps } from "@webstudio-is/image";
6
- import type { WsComponentPropsMeta } from "../../components/component-type";
6
+ import type { WsComponentPropsMeta } from "../../components/component-meta";
7
7
 
8
8
  export const customComponents = {
9
9
  Image,
@@ -1,59 +1,23 @@
1
- import { Link } from "@remix-run/react";
2
- import type {
3
- ElementRef,
4
- ComponentProps,
5
- RefAttributes,
6
- ForwardRefExoticComponent,
7
- } from "react";
1
+ import { Link as RemixLink } from "@remix-run/react";
2
+ import type { ComponentPropsWithoutRef } from "react";
8
3
  import { forwardRef } from "react";
9
- import type { Link as BaseLink } from "../../../components/link";
4
+ import type { Link } from "../../../components/link";
5
+ import { usePropUrl, getInstanceIdFromComponentProps } from "../../../props";
10
6
 
11
- const isAbsoluteUrl = (href: string) => {
12
- try {
13
- new URL(href);
14
- return true;
15
- } catch {
16
- return false;
17
- }
18
- };
19
-
20
- // Remix's check for absolute URL copied from here:
21
- // https://github.com/remix-run/react-router/blob/react-router-dom%406.8.0/packages/react-router-dom/index.tsx#L423-L424
22
- const isAbsoluteUrlRemix = (href: string) =>
23
- /^[a-z+]+:\/\//i.test(href) || href.startsWith("//");
24
-
25
- type Props = ComponentProps<typeof BaseLink>;
26
-
27
- type Ref = ElementRef<"a">;
28
-
29
- export const wrapLinkComponent = (
30
- BaseLink: ForwardRefExoticComponent<Props & RefAttributes<Ref>>
31
- ) => {
32
- // We're not actually wrapping BaseLink (no way to wrap with Remix's Link),
33
- // but this is still useful because we're making sure that props/ref types are compatible
34
- const Component = forwardRef<Ref, Props>(({ href = "", ...props }, ref) => {
35
- const isAbsolute = isAbsoluteUrl(href);
7
+ type LinkComponent = typeof Link;
8
+ type LinkProps = ComponentPropsWithoutRef<LinkComponent>;
36
9
 
37
- // This is a workaround for a bug in Remix: https://github.com/remix-run/remix/issues/5440
38
- // It has a buggy absolute URL detection, which gives false positives on value like "//" or "http://"
39
- // and causes entire app to crash
40
- const willRemixTryToTreatAsAbsoluteAndCrash =
41
- isAbsolute === false && isAbsoluteUrlRemix(href);
10
+ export const wrapLinkComponent = (BaseLink: LinkComponent) => {
11
+ const Component: LinkComponent = forwardRef((props: LinkProps, ref) => {
12
+ const href = usePropUrl(getInstanceIdFromComponentProps(props), "href");
42
13
 
43
- if (isAbsolute || willRemixTryToTreatAsAbsoluteAndCrash) {
44
- return (
45
- <BaseLink
46
- {...props}
47
- href={willRemixTryToTreatAsAbsoluteAndCrash ? "" : href}
48
- ref={ref}
49
- />
50
- );
14
+ if (typeof href === "string" || href === undefined) {
15
+ return <BaseLink {...props} ref={ref} />;
51
16
  }
52
17
 
53
- return <Link {...props} to={href} ref={ref} />;
18
+ return <RemixLink {...props} to={href.path} ref={ref} />;
54
19
  });
55
20
 
56
- // This is the only part that we use from BaseLink at runtime
57
21
  Component.displayName = BaseLink.displayName;
58
22
 
59
23
  return Component;