@webstudio-is/react-sdk 0.22.0 → 0.23.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 (47) hide show
  1. package/lib/app/custom-components/image.js +3 -3
  2. package/lib/cjs/app/custom-components/image.cjs +3 -3
  3. package/lib/cjs/components/index.cjs +15 -9
  4. package/lib/cjs/index.cjs +3 -3
  5. package/lib/cjs/props.cjs +80 -0
  6. package/lib/cjs/tree/root.cjs +3 -2
  7. package/lib/cjs/tree/wrapper-component.cjs +7 -4
  8. package/lib/components/index.js +15 -9
  9. package/lib/index.js +3 -3
  10. package/lib/props.js +60 -0
  11. package/lib/tree/root.js +3 -2
  12. package/lib/tree/wrapper-component.js +10 -7
  13. package/package.json +11 -11
  14. package/src/app/custom-components/image.tsx +3 -3
  15. package/src/components/index.ts +26 -17
  16. package/src/index.ts +2 -3
  17. package/src/props.ts +69 -0
  18. package/src/tree/create-elements-tree.tsx +2 -2
  19. package/src/tree/root.ts +9 -9
  20. package/src/tree/wrapper-component.tsx +8 -5
  21. package/lib/cjs/db/index.cjs +0 -20
  22. package/lib/cjs/db/instance.cjs +0 -59
  23. package/lib/cjs/db/style.cjs +0 -67
  24. package/lib/cjs/db/types.cjs +0 -16
  25. package/lib/cjs/user-props/all-user-props.cjs +0 -40
  26. package/lib/cjs/user-props/index.cjs +0 -20
  27. package/lib/cjs/user-props/schema.cjs +0 -54
  28. package/lib/cjs/user-props/use-user-props-asset.cjs +0 -43
  29. package/lib/cjs/user-props/use-user-props.cjs +0 -42
  30. package/lib/db/index.js +0 -3
  31. package/lib/db/instance.js +0 -39
  32. package/lib/db/style.js +0 -50
  33. package/lib/db/types.js +0 -0
  34. package/lib/user-props/all-user-props.js +0 -20
  35. package/lib/user-props/index.js +0 -3
  36. package/lib/user-props/schema.js +0 -34
  37. package/lib/user-props/use-user-props-asset.js +0 -23
  38. package/lib/user-props/use-user-props.js +0 -22
  39. package/src/db/index.ts +0 -3
  40. package/src/db/instance.ts +0 -56
  41. package/src/db/style.ts +0 -63
  42. package/src/db/types.ts +0 -22
  43. package/src/user-props/all-user-props.ts +0 -26
  44. package/src/user-props/index.ts +0 -3
  45. package/src/user-props/schema.ts +0 -35
  46. package/src/user-props/use-user-props-asset.ts +0 -35
  47. package/src/user-props/use-user-props.ts +0 -32
@@ -5,17 +5,17 @@ import {
5
5
  } from "react";
6
6
  import { Image as WebstudioImage, loaders } from "@webstudio-is/image";
7
7
  import { Image as SdkImage } from "../../components/image";
8
- import { useUserPropsAsset } from "../../user-props/use-user-props-asset";
8
+ import { usePropAsset } from "../../props";
9
9
  import { idAttribute } from "../../tree/wrapper-component";
10
10
  import { getParams } from "../params";
11
11
  const defaultTag = "img";
12
12
  const Image = forwardRef(
13
13
  (props, ref) => {
14
14
  const componentId = props[idAttribute];
15
- const asset = useUserPropsAsset(componentId, "src");
15
+ const asset = usePropAsset(componentId, "src");
16
16
  const params = getParams();
17
17
  const loader = useMemo(() => {
18
- if (asset == null) {
18
+ if (asset === void 0) {
19
19
  return null;
20
20
  }
21
21
  if (asset.location === "REMOTE") {
@@ -25,17 +25,17 @@ var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_react = require("react");
26
26
  var import_image = require("@webstudio-is/image");
27
27
  var import_image2 = require("../../components/image");
28
- var import_use_user_props_asset = require("../../user-props/use-user-props-asset");
28
+ var import_props = require("../../props");
29
29
  var import_wrapper_component = require("../../tree/wrapper-component");
30
30
  var import_params = require("../params");
31
31
  const defaultTag = "img";
32
32
  const Image = (0, import_react.forwardRef)(
33
33
  (props, ref) => {
34
34
  const componentId = props[import_wrapper_component.idAttribute];
35
- const asset = (0, import_use_user_props_asset.useUserPropsAsset)(componentId, "src");
35
+ const asset = (0, import_props.usePropAsset)(componentId, "src");
36
36
  const params = (0, import_params.getParams)();
37
37
  const loader = (0, import_react.useMemo)(() => {
38
- if (asset == null) {
38
+ if (asset === void 0) {
39
39
  return null;
40
40
  }
41
41
  if (asset.location === "REMOTE") {
@@ -111,32 +111,38 @@ const getComponentNames = () => {
111
111
  return [...uniqueNames.values()];
112
112
  };
113
113
  const getComponentMeta = (name) => {
114
+ const componentMeta = meta[name];
114
115
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
115
- return { ...meta[name], ...registeredComponentsMeta[name] };
116
+ return {
117
+ ...componentMeta,
118
+ ...registeredComponentsMeta[name]
119
+ };
116
120
  }
117
- return meta[name];
121
+ return componentMeta;
118
122
  };
119
123
  const getComponent = (name) => {
120
124
  return registeredComponents != null && name in registeredComponents ? registeredComponents[name] : components[name];
121
125
  };
122
126
  const getComponentMetaProps = (name) => {
127
+ const componentMeta = meta[name];
123
128
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
129
+ const registeredComponentMeta = registeredComponentsMeta[name];
124
130
  const allMetaPropKeys = /* @__PURE__ */ new Set([
125
- ...Object.keys(meta[name]?.props ?? {}),
126
- ...Object.keys(registeredComponentsMeta[name].props)
131
+ ...Object.keys(componentMeta?.props ?? {}),
132
+ ...Object.keys(registeredComponentMeta.props)
127
133
  ]);
128
134
  const props = {};
129
135
  for (const key of allMetaPropKeys.values()) {
130
136
  props[key] = {
131
- ...meta[name]?.props[key],
132
- ...registeredComponentsMeta[name]?.props?.[key],
133
- defaultValue: registeredComponentsMeta[name]?.props?.[key]?.defaultValue ?? meta[name]?.props[key]?.defaultValue ?? null,
134
- required: registeredComponentsMeta[name]?.props?.[key]?.required || meta[name]?.props[key]?.required
137
+ ...componentMeta?.props[key],
138
+ ...registeredComponentMeta?.props?.[key],
139
+ defaultValue: registeredComponentMeta?.props?.[key]?.defaultValue ?? componentMeta?.props[key]?.defaultValue ?? null,
140
+ required: registeredComponentMeta?.props?.[key]?.required || componentMeta?.props[key]?.required
135
141
  };
136
142
  }
137
143
  return props;
138
144
  }
139
- return meta[name].props;
145
+ return componentMeta?.props;
140
146
  };
141
147
  const registerComponents = (components2) => {
142
148
  registeredComponents = components2;
package/lib/cjs/index.cjs CHANGED
@@ -20,14 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var src_exports = {};
21
21
  __export(src_exports, {
22
22
  customComponents: () => import_custom_components.customComponents,
23
- customComponentsMeta: () => import_custom_components.customComponentsMeta
23
+ customComponentsMeta: () => import_custom_components.customComponentsMeta,
24
+ setPropsByInstanceIdStore: () => import_props.setPropsByInstanceIdStore
24
25
  });
25
26
  module.exports = __toCommonJS(src_exports);
26
27
  __reExport(src_exports, require("./css"), module.exports);
27
28
  __reExport(src_exports, require("./tree"), module.exports);
28
29
  __reExport(src_exports, require("./components"), module.exports);
29
- __reExport(src_exports, require("./user-props"), module.exports);
30
30
  __reExport(src_exports, require("./pubsub"), module.exports);
31
- __reExport(src_exports, require("./db"), module.exports);
32
31
  __reExport(src_exports, require("./app"), module.exports);
33
32
  var import_custom_components = require("./app/custom-components");
33
+ var import_props = require("./props");
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var props_exports = {};
20
+ __export(props_exports, {
21
+ getPropsByInstanceId: () => getPropsByInstanceId,
22
+ getPropsByInstanceIdStore: () => getPropsByInstanceIdStore,
23
+ setPropsByInstanceIdStore: () => setPropsByInstanceIdStore,
24
+ useInstanceProps: () => useInstanceProps,
25
+ usePropAsset: () => usePropAsset
26
+ });
27
+ module.exports = __toCommonJS(props_exports);
28
+ var import_react = require("react");
29
+ var import_nanostores = require("nanostores");
30
+ var import_react2 = require("@nanostores/react");
31
+ let propsByInstanceIdStore = (0, import_nanostores.atom)(/* @__PURE__ */ new Map());
32
+ const setPropsByInstanceIdStore = (store) => {
33
+ propsByInstanceIdStore = store;
34
+ };
35
+ const getPropsByInstanceIdStore = () => {
36
+ return propsByInstanceIdStore;
37
+ };
38
+ const getPropsByInstanceId = (props) => {
39
+ const propsByInstanceId = /* @__PURE__ */ new Map();
40
+ for (const prop of props) {
41
+ let instanceProps = propsByInstanceId.get(prop.instanceId);
42
+ if (instanceProps === void 0) {
43
+ instanceProps = [];
44
+ propsByInstanceId.set(prop.instanceId, instanceProps);
45
+ }
46
+ instanceProps.push(prop);
47
+ }
48
+ return propsByInstanceId;
49
+ };
50
+ const useInstanceProps = (instanceId) => {
51
+ const propsByInstanceId = (0, import_react2.useStore)(propsByInstanceIdStore);
52
+ const instanceProps = propsByInstanceId.get(instanceId);
53
+ const instancePropsObject = {};
54
+ if (instanceProps) {
55
+ for (const prop of instanceProps) {
56
+ if (prop.type !== "asset") {
57
+ instancePropsObject[prop.name] = prop.value;
58
+ }
59
+ }
60
+ }
61
+ return instancePropsObject;
62
+ };
63
+ const usePropAsset = (instanceId, name) => {
64
+ const assetStore = (0, import_react.useMemo)(() => {
65
+ return (0, import_nanostores.computed)(propsByInstanceIdStore, (propsByInstanceId) => {
66
+ const instanceProps = propsByInstanceId.get(instanceId);
67
+ let asset2 = void 0;
68
+ if (instanceProps) {
69
+ for (const prop of instanceProps) {
70
+ if (prop.type === "asset" && prop.name === name) {
71
+ asset2 = prop.value;
72
+ }
73
+ }
74
+ }
75
+ return asset2;
76
+ });
77
+ }, [instanceId, name]);
78
+ const asset = (0, import_react2.useStore)(assetStore);
79
+ return asset;
80
+ };
@@ -21,12 +21,13 @@ __export(root_exports, {
21
21
  InstanceRoot: () => InstanceRoot
22
22
  });
23
23
  module.exports = __toCommonJS(root_exports);
24
- var import_user_props = require("../user-props/");
24
+ var import_nanostores = require("nanostores");
25
25
  var import_create_elements_tree = require("./create-elements-tree");
26
26
  var import_wrapper_component = require("./wrapper-component");
27
27
  var import_components = require("../components");
28
28
  var import_custom_components = require("../app/custom-components");
29
29
  var import_params = require("../app/params");
30
+ var import_props = require("../props");
30
31
  const InstanceRoot = ({
31
32
  data,
32
33
  Component,
@@ -35,7 +36,7 @@ const InstanceRoot = ({
35
36
  if (data.tree === null) {
36
37
  throw new Error("Tree is null");
37
38
  }
38
- (0, import_user_props.useAllUserProps)(data.props);
39
+ (0, import_props.setPropsByInstanceIdStore)((0, import_nanostores.atom)((0, import_props.getPropsByInstanceId)(data.tree.props)));
39
40
  (0, import_params.setParams)(data.params ?? null);
40
41
  (0, import_components.registerComponents)(customComponents);
41
42
  return (0, import_create_elements_tree.createElementsTree)({
@@ -27,7 +27,7 @@ module.exports = __toCommonJS(wrapper_component_exports);
27
27
  var import_jsx_runtime = require("react/jsx-runtime");
28
28
  var import_react = require("react");
29
29
  var import_components = require("../components");
30
- var import_use_user_props = require("../user-props/use-user-props");
30
+ var import_props = require("../props");
31
31
  const renderText = (text) => {
32
32
  const lines = text.split("\n");
33
33
  return lines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, {
@@ -51,14 +51,17 @@ const WrapperComponent = ({
51
51
  children,
52
52
  ...rest
53
53
  }) => {
54
- const Component = (0, import_components.getComponent)(instance.component);
55
- const userProps = (0, import_use_user_props.useUserProps)(instance.id);
54
+ const instanceProps = (0, import_props.useInstanceProps)(instance.id);
56
55
  const props = {
57
- ...userProps,
56
+ ...instanceProps,
58
57
  ...rest,
59
58
  [idAttribute]: instance.id,
60
59
  [componentAttribute]: instance.component
61
60
  };
61
+ const Component = (0, import_components.getComponent)(instance.component);
62
+ if (Component === void 0) {
63
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {});
64
+ }
62
65
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, {
63
66
  ...props,
64
67
  children: renderWrapperComponentChildren(children)
@@ -77,32 +77,38 @@ const getComponentNames = () => {
77
77
  return [...uniqueNames.values()];
78
78
  };
79
79
  const getComponentMeta = (name) => {
80
+ const componentMeta = meta[name];
80
81
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
81
- return { ...meta[name], ...registeredComponentsMeta[name] };
82
+ return {
83
+ ...componentMeta,
84
+ ...registeredComponentsMeta[name]
85
+ };
82
86
  }
83
- return meta[name];
87
+ return componentMeta;
84
88
  };
85
89
  const getComponent = (name) => {
86
90
  return registeredComponents != null && name in registeredComponents ? registeredComponents[name] : components[name];
87
91
  };
88
92
  const getComponentMetaProps = (name) => {
93
+ const componentMeta = meta[name];
89
94
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
95
+ const registeredComponentMeta = registeredComponentsMeta[name];
90
96
  const allMetaPropKeys = /* @__PURE__ */ new Set([
91
- ...Object.keys(meta[name]?.props ?? {}),
92
- ...Object.keys(registeredComponentsMeta[name].props)
97
+ ...Object.keys(componentMeta?.props ?? {}),
98
+ ...Object.keys(registeredComponentMeta.props)
93
99
  ]);
94
100
  const props = {};
95
101
  for (const key of allMetaPropKeys.values()) {
96
102
  props[key] = {
97
- ...meta[name]?.props[key],
98
- ...registeredComponentsMeta[name]?.props?.[key],
99
- defaultValue: registeredComponentsMeta[name]?.props?.[key]?.defaultValue ?? meta[name]?.props[key]?.defaultValue ?? null,
100
- required: registeredComponentsMeta[name]?.props?.[key]?.required || meta[name]?.props[key]?.required
103
+ ...componentMeta?.props[key],
104
+ ...registeredComponentMeta?.props?.[key],
105
+ defaultValue: registeredComponentMeta?.props?.[key]?.defaultValue ?? componentMeta?.props[key]?.defaultValue ?? null,
106
+ required: registeredComponentMeta?.props?.[key]?.required || componentMeta?.props[key]?.required
101
107
  };
102
108
  }
103
109
  return props;
104
110
  }
105
- return meta[name].props;
111
+ return componentMeta?.props;
106
112
  };
107
113
  const registerComponents = (components2) => {
108
114
  registeredComponents = components2;
package/lib/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  export * from "./css";
2
2
  export * from "./tree";
3
3
  export * from "./components";
4
- export * from "./user-props";
5
4
  export * from "./pubsub";
6
- export * from "./db";
7
5
  export * from "./app";
8
6
  import {
9
7
  customComponents,
10
8
  customComponentsMeta
11
9
  } from "./app/custom-components";
10
+ import { setPropsByInstanceIdStore } from "./props";
12
11
  export {
13
12
  customComponents,
14
- customComponentsMeta
13
+ customComponentsMeta,
14
+ setPropsByInstanceIdStore
15
15
  };
package/lib/props.js ADDED
@@ -0,0 +1,60 @@
1
+ import { useMemo } from "react";
2
+ import { atom, computed } from "nanostores";
3
+ import { useStore } from "@nanostores/react";
4
+ let propsByInstanceIdStore = atom(/* @__PURE__ */ new Map());
5
+ const setPropsByInstanceIdStore = (store) => {
6
+ propsByInstanceIdStore = store;
7
+ };
8
+ const getPropsByInstanceIdStore = () => {
9
+ return propsByInstanceIdStore;
10
+ };
11
+ const getPropsByInstanceId = (props) => {
12
+ const propsByInstanceId = /* @__PURE__ */ new Map();
13
+ for (const prop of props) {
14
+ let instanceProps = propsByInstanceId.get(prop.instanceId);
15
+ if (instanceProps === void 0) {
16
+ instanceProps = [];
17
+ propsByInstanceId.set(prop.instanceId, instanceProps);
18
+ }
19
+ instanceProps.push(prop);
20
+ }
21
+ return propsByInstanceId;
22
+ };
23
+ const useInstanceProps = (instanceId) => {
24
+ const propsByInstanceId = useStore(propsByInstanceIdStore);
25
+ const instanceProps = propsByInstanceId.get(instanceId);
26
+ const instancePropsObject = {};
27
+ if (instanceProps) {
28
+ for (const prop of instanceProps) {
29
+ if (prop.type !== "asset") {
30
+ instancePropsObject[prop.name] = prop.value;
31
+ }
32
+ }
33
+ }
34
+ return instancePropsObject;
35
+ };
36
+ const usePropAsset = (instanceId, name) => {
37
+ const assetStore = useMemo(() => {
38
+ return computed(propsByInstanceIdStore, (propsByInstanceId) => {
39
+ const instanceProps = propsByInstanceId.get(instanceId);
40
+ let asset2 = void 0;
41
+ if (instanceProps) {
42
+ for (const prop of instanceProps) {
43
+ if (prop.type === "asset" && prop.name === name) {
44
+ asset2 = prop.value;
45
+ }
46
+ }
47
+ }
48
+ return asset2;
49
+ });
50
+ }, [instanceId, name]);
51
+ const asset = useStore(assetStore);
52
+ return asset;
53
+ };
54
+ export {
55
+ getPropsByInstanceId,
56
+ getPropsByInstanceIdStore,
57
+ setPropsByInstanceIdStore,
58
+ useInstanceProps,
59
+ usePropAsset
60
+ };
package/lib/tree/root.js CHANGED
@@ -1,9 +1,10 @@
1
- import { useAllUserProps } from "../user-props/";
1
+ import { atom } from "nanostores";
2
2
  import { createElementsTree } from "./create-elements-tree";
3
3
  import { WrapperComponent } from "./wrapper-component";
4
4
  import { registerComponents } from "../components";
5
5
  import { customComponents as defaultCustomComponents } from "../app/custom-components";
6
6
  import { setParams } from "../app/params";
7
+ import { getPropsByInstanceId, setPropsByInstanceIdStore } from "../props";
7
8
  const InstanceRoot = ({
8
9
  data,
9
10
  Component,
@@ -12,7 +13,7 @@ const InstanceRoot = ({
12
13
  if (data.tree === null) {
13
14
  throw new Error("Tree is null");
14
15
  }
15
- useAllUserProps(data.props);
16
+ setPropsByInstanceIdStore(atom(getPropsByInstanceId(data.tree.props)));
16
17
  setParams(data.params ?? null);
17
18
  registerComponents(customComponents);
18
19
  return createElementsTree({
@@ -1,10 +1,10 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Fragment } from "react";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment as Fragment2 } from "react";
3
3
  import { getComponent } from "../components";
4
- import { useUserProps } from "../user-props/use-user-props";
4
+ import { useInstanceProps } from "../props";
5
5
  const renderText = (text) => {
6
6
  const lines = text.split("\n");
7
- return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment, {
7
+ return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment2, {
8
8
  children: [
9
9
  line,
10
10
  index < lines.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
@@ -25,14 +25,17 @@ const WrapperComponent = ({
25
25
  children,
26
26
  ...rest
27
27
  }) => {
28
- const Component = getComponent(instance.component);
29
- const userProps = useUserProps(instance.id);
28
+ const instanceProps = useInstanceProps(instance.id);
30
29
  const props = {
31
- ...userProps,
30
+ ...instanceProps,
32
31
  ...rest,
33
32
  [idAttribute]: instance.id,
34
33
  [componentAttribute]: instance.component
35
34
  };
35
+ const Component = getComponent(instance.component);
36
+ if (Component === void 0) {
37
+ return /* @__PURE__ */ jsx(Fragment, {});
38
+ }
36
39
  return /* @__PURE__ */ jsx(Component, {
37
40
  ...props,
38
41
  children: renderWrapperComponentChildren(children)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/react-sdk",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Webstudio JavaScript / TypeScript API",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -9,12 +9,12 @@
9
9
  "@babel/core": "^7.20.2",
10
10
  "@esbuild-kit/esm-loader": "^2.4.2",
11
11
  "@jest/globals": "^29.3.1",
12
- "@remix-run/node": "1.9.0",
13
- "@remix-run/react": "1.9.0",
14
- "@remix-run/server-runtime": "1.9.0",
12
+ "@remix-run/node": "1.12.0",
13
+ "@remix-run/react": "1.12.0",
14
+ "@remix-run/server-runtime": "1.12.0",
15
15
  "@storybook/react": "^6.5.14",
16
16
  "@storybook/testing-library": "^0.0.11",
17
- "@types/node": "^17.0.21",
17
+ "@types/node": "^18.11.18",
18
18
  "@types/react": "^17.0.24",
19
19
  "@types/react-dom": "^17.0.9",
20
20
  "babel-loader": "^8.2.5",
@@ -47,12 +47,12 @@
47
47
  "mitt": "^3.0.0",
48
48
  "nanostores": "^0.7.1",
49
49
  "warn-once": "^0.1.1",
50
- "@webstudio-is/asset-uploader": "^0.22.0",
51
- "@webstudio-is/css-data": "^0.22.0",
52
- "@webstudio-is/design-tokens": "^0.22.0",
53
- "@webstudio-is/icons": "^0.22.0",
54
- "@webstudio-is/image": "^0.22.0",
55
- "@webstudio-is/prisma-client": "^0.22.0"
50
+ "@webstudio-is/asset-uploader": "^0.23.0",
51
+ "@webstudio-is/css-data": "^0.23.0",
52
+ "@webstudio-is/icons": "^0.23.0",
53
+ "@webstudio-is/image": "^0.23.0",
54
+ "@webstudio-is/prisma-client": "^0.23.0",
55
+ "@webstudio-is/project-build": "^0.23.0"
56
56
  },
57
57
  "exports": {
58
58
  "import": "./lib/index.js",
@@ -6,7 +6,7 @@ import {
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 { useUserPropsAsset } from "../../user-props/use-user-props-asset";
9
+ import { usePropAsset } from "../../props";
10
10
  import { idAttribute } from "../../tree/wrapper-component";
11
11
  import { getParams } from "../params";
12
12
 
@@ -18,11 +18,11 @@ export const Image = forwardRef<ElementRef<typeof defaultTag>, Props>(
18
18
  (props, ref) => {
19
19
  const componentId = props[idAttribute] as string;
20
20
 
21
- const asset = useUserPropsAsset(componentId, "src");
21
+ const asset = usePropAsset(componentId, "src");
22
22
  const params = getParams();
23
23
 
24
24
  const loader = useMemo(() => {
25
- if (asset == null) {
25
+ if (asset === undefined) {
26
26
  return null;
27
27
  }
28
28
  if (asset.location === "REMOTE") {
@@ -96,28 +96,37 @@ export const getComponentNames = (): ComponentName[] => {
96
96
  return [...uniqueNames.values()] as ComponentName[];
97
97
  };
98
98
 
99
- export const getComponentMeta = (name: ComponentName): WsComponentMeta => {
99
+ export const getComponentMeta = (name: string): undefined | WsComponentMeta => {
100
+ const componentMeta = meta[name as ComponentName];
100
101
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
101
- return { ...meta[name], ...registeredComponentsMeta[name] };
102
+ return {
103
+ ...componentMeta,
104
+ ...registeredComponentsMeta[name as ComponentName],
105
+ };
102
106
  }
103
107
 
104
- return meta[name];
108
+ return componentMeta;
105
109
  };
106
110
 
107
111
  export const getComponent = (
108
- name: ComponentName
109
- ): typeof components[ComponentName] => {
112
+ name: string
113
+ ): undefined | typeof components[ComponentName] => {
110
114
  return registeredComponents != null && name in registeredComponents
111
- ? (registeredComponents[name] as typeof components[ComponentName])
112
- : components[name];
115
+ ? (registeredComponents[
116
+ name as ComponentName
117
+ ] as typeof components[ComponentName])
118
+ : components[name as ComponentName];
113
119
  };
114
120
 
115
- export const getComponentMetaProps = (name: ComponentName): MetaProps => {
121
+ export const getComponentMetaProps = (name: string): undefined | MetaProps => {
122
+ const componentMeta = meta[name as ComponentName];
116
123
  if (registeredComponentsMeta != null && name in registeredComponentsMeta) {
124
+ const registeredComponentMeta =
125
+ registeredComponentsMeta[name as ComponentName];
117
126
  const allMetaPropKeys = new Set([
118
- ...Object.keys(meta[name]?.props ?? {}),
127
+ ...Object.keys(componentMeta?.props ?? {}),
119
128
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
120
- ...Object.keys(registeredComponentsMeta[name]!.props!),
129
+ ...Object.keys(registeredComponentMeta!.props!),
121
130
  ]);
122
131
 
123
132
  const props: MetaProps = {};
@@ -126,21 +135,21 @@ export const getComponentMetaProps = (name: ComponentName): MetaProps => {
126
135
  **/
127
136
  for (const key of allMetaPropKeys.values()) {
128
137
  props[key] = {
129
- ...meta[name]?.props[key],
130
- ...registeredComponentsMeta[name]?.props?.[key],
138
+ ...componentMeta?.props[key],
139
+ ...registeredComponentMeta?.props?.[key],
131
140
  defaultValue:
132
- registeredComponentsMeta[name]?.props?.[key]?.defaultValue ??
133
- meta[name]?.props[key]?.defaultValue ??
141
+ registeredComponentMeta?.props?.[key]?.defaultValue ??
142
+ componentMeta?.props[key]?.defaultValue ??
134
143
  null,
135
144
  required:
136
- registeredComponentsMeta[name]?.props?.[key]?.required ||
137
- meta[name]?.props[key]?.required,
145
+ registeredComponentMeta?.props?.[key]?.required ||
146
+ componentMeta?.props[key]?.required,
138
147
  } as MetaProps[string];
139
148
  }
140
149
  return props;
141
150
  }
142
151
 
143
- return meta[name].props;
152
+ return componentMeta?.props;
144
153
  };
145
154
 
146
155
  /**
package/src/index.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  export * from "./css";
2
2
  export * from "./tree";
3
3
  export * from "./components";
4
- export * from "./user-props";
5
4
  export * from "./pubsub";
6
- export * from "./db";
7
5
  export * from "./app";
8
6
  export {
9
7
  customComponents,
10
8
  customComponentsMeta,
11
9
  } from "./app/custom-components";
12
- export type { MetaProps } from "./components/component-type";
10
+ export type { MetaProps, WsComponentMeta } from "./components/component-type";
11
+ export { setPropsByInstanceIdStore } from "./props";
package/src/props.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { useMemo } from "react";
2
+ import { atom, computed, type ReadableAtom } from "nanostores";
3
+ import { useStore } from "@nanostores/react";
4
+ import type { Instance, Props } from "@webstudio-is/project-build";
5
+ import type { Asset } from "@webstudio-is/asset-uploader";
6
+
7
+ type PropsByInstanceId = Map<Instance["id"], Props>;
8
+
9
+ type PropsByInstanceIdStore = ReadableAtom<PropsByInstanceId>;
10
+
11
+ let propsByInstanceIdStore: PropsByInstanceIdStore = atom(new Map());
12
+
13
+ export const setPropsByInstanceIdStore = (store: PropsByInstanceIdStore) => {
14
+ propsByInstanceIdStore = store;
15
+ };
16
+
17
+ export const getPropsByInstanceIdStore = () => {
18
+ return propsByInstanceIdStore;
19
+ };
20
+
21
+ export const getPropsByInstanceId = (props: Props) => {
22
+ const propsByInstanceId: PropsByInstanceId = new Map();
23
+ for (const prop of props) {
24
+ let instanceProps = propsByInstanceId.get(prop.instanceId);
25
+ if (instanceProps === undefined) {
26
+ instanceProps = [];
27
+ propsByInstanceId.set(prop.instanceId, instanceProps);
28
+ }
29
+ instanceProps.push(prop);
30
+ }
31
+ return propsByInstanceId;
32
+ };
33
+
34
+ // this utility is be used only for preview with static props
35
+ // so there is no need to use computed to optimize rerenders
36
+ export const useInstanceProps = (instanceId: Instance["id"]) => {
37
+ const propsByInstanceId = useStore(propsByInstanceIdStore);
38
+ const instanceProps = propsByInstanceId.get(instanceId);
39
+ const instancePropsObject: Record<string, number | string | boolean> = {};
40
+ if (instanceProps) {
41
+ for (const prop of instanceProps) {
42
+ if (prop.type !== "asset") {
43
+ instancePropsObject[prop.name] = prop.value;
44
+ }
45
+ }
46
+ }
47
+ return instancePropsObject;
48
+ };
49
+
50
+ // this utility is be used for image component in both designer and preview
51
+ // so need to optimize rerenders with computed
52
+ export const usePropAsset = (instanceId: Instance["id"], name: string) => {
53
+ const assetStore = useMemo(() => {
54
+ return computed(propsByInstanceIdStore, (propsByInstanceId) => {
55
+ const instanceProps = propsByInstanceId.get(instanceId);
56
+ let asset: undefined | Asset = undefined;
57
+ if (instanceProps) {
58
+ for (const prop of instanceProps) {
59
+ if (prop.type === "asset" && prop.name === name) {
60
+ asset = prop.value;
61
+ }
62
+ }
63
+ }
64
+ return asset;
65
+ });
66
+ }, [instanceId, name]);
67
+ const asset = useStore(assetStore);
68
+ return asset;
69
+ };