@webstudio-is/react-sdk 0.83.0 → 0.85.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 (54) hide show
  1. package/lib/cjs/component-renderer.js +125 -0
  2. package/lib/cjs/components/component-meta.js +5 -0
  3. package/lib/cjs/context.js +2 -1
  4. package/lib/cjs/css/style-rules.js +1 -1
  5. package/lib/cjs/embed-template.js +101 -55
  6. package/lib/cjs/hook.js +34 -0
  7. package/lib/cjs/index.js +6 -0
  8. package/lib/cjs/instance-utils.js +65 -0
  9. package/lib/cjs/props.js +12 -2
  10. package/lib/cjs/tree/create-elements-tree.js +5 -4
  11. package/lib/cjs/tree/root.js +6 -2
  12. package/lib/cjs/tree/webstudio-component.js +2 -0
  13. package/lib/component-renderer.js +111 -0
  14. package/lib/components/component-meta.js +5 -0
  15. package/lib/context.js +2 -1
  16. package/lib/css/style-rules.js +1 -1
  17. package/lib/embed-template.js +101 -55
  18. package/lib/hook.js +14 -0
  19. package/lib/index.js +8 -1
  20. package/lib/instance-utils.js +45 -0
  21. package/lib/props.js +13 -3
  22. package/lib/tree/create-elements-tree.js +5 -4
  23. package/lib/tree/root.js +6 -2
  24. package/lib/tree/webstudio-component.js +2 -0
  25. package/lib/types/component-renderer.d.ts +8 -0
  26. package/lib/types/components/component-meta.d.ts +9 -6
  27. package/lib/types/context.d.ts +2 -0
  28. package/lib/types/css/css.d.ts +19 -19
  29. package/lib/types/css/global-rules.d.ts +19 -19
  30. package/lib/types/css/normalize.d.ts +47 -47
  31. package/lib/types/embed-template.d.ts +291 -181
  32. package/lib/types/hook.d.ts +31 -0
  33. package/lib/types/index.d.ts +4 -1
  34. package/lib/types/instance-utils.d.ts +16 -0
  35. package/lib/types/instance-utils.test.d.ts +1 -0
  36. package/lib/types/props.d.ts +47 -46
  37. package/lib/types/tree/create-elements-tree.d.ts +5 -2
  38. package/lib/types/tree/root.d.ts +5 -2
  39. package/lib/types/tree/webstudio-component.d.ts +1 -0
  40. package/package.json +11 -11
  41. package/src/component-renderer.tsx +117 -0
  42. package/src/components/component-meta.ts +5 -0
  43. package/src/context.tsx +3 -0
  44. package/src/css/style-rules.ts +1 -1
  45. package/src/embed-template.test.ts +81 -70
  46. package/src/embed-template.ts +116 -56
  47. package/src/hook.ts +42 -0
  48. package/src/index.ts +4 -0
  49. package/src/instance-utils.test.ts +89 -0
  50. package/src/instance-utils.ts +65 -0
  51. package/src/props.ts +13 -1
  52. package/src/tree/create-elements-tree.tsx +8 -3
  53. package/src/tree/root.ts +8 -0
  54. package/src/tree/webstudio-component.tsx +1 -0
package/src/props.ts CHANGED
@@ -4,7 +4,7 @@ import { useStore } from "@nanostores/react";
4
4
  import type { Instance, Page, Prop, Props } from "@webstudio-is/project-build";
5
5
  import type { Asset, Assets } from "@webstudio-is/asset-uploader";
6
6
  import { ReactSdkContext } from "./context";
7
- import { idAttribute } from "./tree/webstudio-component";
7
+ import { idAttribute, indexAttribute } from "./tree/webstudio-component";
8
8
 
9
9
  export type PropsByInstanceId = Map<Instance["id"], Prop[]>;
10
10
 
@@ -32,12 +32,17 @@ export const useInstanceProps = (instanceId: Instance["id"]) => {
32
32
  executeEffectfulExpression,
33
33
  setDataSourceValues,
34
34
  renderer,
35
+ indexesWithinAncestors,
35
36
  } = useContext(ReactSdkContext);
37
+ const index = indexesWithinAncestors.get(instanceId);
36
38
  const instancePropsObjectStore = useMemo(() => {
37
39
  return computed(
38
40
  [propsByInstanceIdStore, dataSourceValuesStore],
39
41
  (propsByInstanceId, dataSourceValues) => {
40
42
  const instancePropsObject: Record<Prop["name"], unknown> = {};
43
+ if (index !== undefined) {
44
+ instancePropsObject[indexAttribute] = index.toString();
45
+ }
41
46
  const instanceProps = propsByInstanceId.get(instanceId);
42
47
  if (instanceProps === undefined) {
43
48
  return instancePropsObject;
@@ -89,6 +94,7 @@ export const useInstanceProps = (instanceId: Instance["id"]) => {
89
94
  renderer,
90
95
  executeEffectfulExpression,
91
96
  setDataSourceValues,
97
+ index,
92
98
  ]);
93
99
  const instancePropsObject = useStore(instancePropsObjectStore);
94
100
  return instancePropsObject;
@@ -213,3 +219,9 @@ export const getInstanceIdFromComponentProps = (
213
219
  ) => {
214
220
  return props[idAttribute] as string;
215
221
  };
222
+
223
+ export const getIndexWithinAncestorFromComponentProps = (
224
+ props: Record<string, unknown>
225
+ ) => {
226
+ return props[indexAttribute] as string | undefined;
227
+ };
@@ -2,9 +2,9 @@ import {
2
2
  Fragment,
3
3
  type ForwardRefExoticComponent,
4
4
  type RefAttributes,
5
+ type ReactNode,
5
6
  } from "react";
6
7
  import type { ReadableAtom } from "nanostores";
7
- import { Scripts, ScrollRestoration } from "@remix-run/react";
8
8
  import type { Assets } from "@webstudio-is/asset-uploader";
9
9
  import type { Instance, Instances } from "@webstudio-is/project-build";
10
10
  import type { Components } from "../components/components-utils";
@@ -15,6 +15,7 @@ import {
15
15
  } from "../context";
16
16
  import type { Pages, PropsByInstanceId } from "../props";
17
17
  import type { WebstudioComponentProps } from "./webstudio-component";
18
+ import type { IndexesWithinAncestors } from "../instance-utils";
18
19
 
19
20
  type InstanceSelector = Instance["id"][];
20
21
 
@@ -30,8 +31,10 @@ export const createElementsTree = ({
30
31
  dataSourceValuesStore,
31
32
  executeEffectfulExpression,
32
33
  onDataSourceUpdate,
34
+ indexesWithinAncestors,
33
35
  Component,
34
36
  components,
37
+ scripts,
35
38
  }: Params & {
36
39
  instances: Instances;
37
40
  rootInstanceId: Instance["id"];
@@ -45,11 +48,13 @@ export const createElementsTree = ({
45
48
  ) => DataSourceValues;
46
49
  dataSourceValuesStore: ReadableAtom<DataSourceValues>;
47
50
  onDataSourceUpdate: (newValues: DataSourceValues) => void;
51
+ indexesWithinAncestors: IndexesWithinAncestors;
48
52
 
49
53
  Component: ForwardRefExoticComponent<
50
54
  WebstudioComponentProps & RefAttributes<HTMLElement>
51
55
  >;
52
56
  components: Components;
57
+ scripts?: ReactNode;
53
58
  }) => {
54
59
  const rootInstance = instances.get(rootInstanceId);
55
60
  if (rootInstance === undefined) {
@@ -71,8 +76,7 @@ export const createElementsTree = ({
71
76
  children: [
72
77
  <Fragment key="children">
73
78
  {children}
74
- <ScrollRestoration />
75
- <Scripts />
79
+ {scripts}
76
80
  </Fragment>,
77
81
  ],
78
82
  components,
@@ -87,6 +91,7 @@ export const createElementsTree = ({
87
91
  renderer,
88
92
  imageBaseUrl,
89
93
  assetBaseUrl,
94
+ indexesWithinAncestors,
90
95
  executeEffectfulExpression,
91
96
  setDataSourceValues: onDataSourceUpdate,
92
97
  setBoundDataSourceValue: (instanceId, propName, value) => {
package/src/tree/root.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  useCallback,
4
4
  type ForwardRefExoticComponent,
5
5
  type RefAttributes,
6
+ type ReactNode,
6
7
  } from "react";
7
8
  import {
8
9
  atom,
@@ -20,6 +21,7 @@ import {
20
21
  import { getPropsByInstanceId } from "../props";
21
22
  import type { Components } from "../components/components-utils";
22
23
  import type { Params, DataSourceValues } from "../context";
24
+ import type { IndexesWithinAncestors } from "../instance-utils";
23
25
 
24
26
  export type Data = {
25
27
  page: Page;
@@ -35,6 +37,7 @@ export type RootPropsData = Omit<Data, "build"> & {
35
37
 
36
38
  type RootProps = {
37
39
  data: RootPropsData;
40
+ indexesWithinAncestors: IndexesWithinAncestors;
38
41
  executeComputingExpressions: (values: DataSourceValues) => DataSourceValues;
39
42
  executeEffectfulExpression: (
40
43
  expression: string,
@@ -45,14 +48,17 @@ type RootProps = {
45
48
  WebstudioComponentProps & RefAttributes<HTMLElement>
46
49
  >;
47
50
  components: Components;
51
+ scripts?: ReactNode;
48
52
  };
49
53
 
50
54
  export const InstanceRoot = ({
51
55
  data,
56
+ indexesWithinAncestors,
52
57
  executeComputingExpressions,
53
58
  executeEffectfulExpression,
54
59
  Component,
55
60
  components,
61
+ scripts,
56
62
  }: RootProps): JSX.Element | null => {
57
63
  const dataSourceVariablesStoreRef = useRef<
58
64
  undefined | WritableAtom<DataSourceValues>
@@ -117,10 +123,12 @@ export const InstanceRoot = ({
117
123
  ),
118
124
  assetsStore: atom(new Map(data.assets.map((asset) => [asset.id, asset]))),
119
125
  pagesStore: atom(new Map(data.pages.map((page) => [page.id, page]))),
126
+ indexesWithinAncestors,
120
127
  executeEffectfulExpression,
121
128
  dataSourceValuesStore,
122
129
  onDataSourceUpdate,
123
130
  Component: Component ?? WebstudioComponent,
124
131
  components,
132
+ scripts,
125
133
  });
126
134
  };
@@ -65,6 +65,7 @@ export const idAttribute = "data-ws-id" as const;
65
65
  export const selectorIdAttribute = "data-ws-selector" as const;
66
66
  export const componentAttribute = "data-ws-component" as const;
67
67
  export const showAttribute = "data-ws-show" as const;
68
+ export const indexAttribute = "data-ws-index" as const;
68
69
  export const collapsedAttribute = "data-ws-collapsed" as const;
69
70
 
70
71
  export type WebstudioAttributes = {