@webstudio-is/react-sdk 0.68.0 → 0.69.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.
- package/lib/cjs/components/__generated__/image.props.js +6 -3
- package/lib/cjs/components/__generated__/text-block.props.js +7 -0
- package/lib/cjs/components/blockquote.ws.js +9 -2
- package/lib/cjs/components/box.ws.js +2 -1
- package/lib/cjs/components/button.ws.js +3 -1
- package/lib/cjs/components/checkbox-field.ws.js +12 -6
- package/lib/cjs/components/checkbox.ws.js +1 -0
- package/lib/cjs/components/code-text.ws.js +8 -1
- package/lib/cjs/components/component-meta.js +6 -3
- package/lib/cjs/components/components-utils.js +0 -28
- package/lib/cjs/components/form.ws.js +32 -25
- package/lib/cjs/components/fragment.ws.js +2 -1
- package/lib/cjs/components/heading.ws.js +10 -3
- package/lib/cjs/components/html-embed.ws.js +3 -1
- package/lib/cjs/components/image.js +27 -19
- package/lib/cjs/components/image.ws.js +4 -2
- package/lib/cjs/components/index.js +1 -29
- package/lib/cjs/components/input.ws.js +1 -0
- package/lib/cjs/components/label.ws.js +8 -1
- package/lib/cjs/components/link-block.ws.js +2 -1
- package/lib/cjs/components/link.ws.js +8 -1
- package/lib/cjs/components/list-item.ws.js +11 -4
- package/lib/cjs/components/list.ws.js +2 -2
- package/lib/cjs/components/paragraph.ws.js +10 -3
- package/lib/cjs/components/radio-button-field.ws.js +12 -6
- package/lib/cjs/components/radio-button.ws.js +1 -0
- package/lib/cjs/components/rich-text-link.ws.js +1 -1
- package/lib/cjs/components/separator.ws.js +1 -1
- package/lib/cjs/components/slot.ws.js +3 -1
- package/lib/cjs/components/text-block.js +5 -2
- package/lib/cjs/components/text-block.ws.js +11 -3
- package/lib/cjs/components/textarea.ws.js +1 -0
- package/lib/cjs/embed-template.js +2 -1
- package/lib/cjs/index.js +4 -5
- package/lib/cjs/tree/create-elements-tree.js +8 -8
- package/lib/cjs/tree/root.js +2 -6
- package/lib/cjs/tree/webstudio-component.js +2 -2
- package/lib/components/__generated__/image.props.js +6 -3
- package/lib/components/__generated__/text-block.props.js +7 -0
- package/lib/components/blockquote.ws.js +9 -2
- package/lib/components/box.ws.js +2 -1
- package/lib/components/button.ws.js +3 -1
- package/lib/components/checkbox-field.ws.js +12 -6
- package/lib/components/checkbox.ws.js +1 -0
- package/lib/components/code-text.ws.js +8 -1
- package/lib/components/component-meta.js +6 -3
- package/lib/components/components-utils.js +0 -14
- package/lib/components/form.ws.js +32 -25
- package/lib/components/fragment.ws.js +2 -1
- package/lib/components/heading.ws.js +10 -3
- package/lib/components/html-embed.ws.js +3 -1
- package/lib/components/image.js +34 -20
- package/lib/components/image.ws.js +4 -2
- package/lib/components/index.js +1 -29
- package/lib/components/input.ws.js +1 -0
- package/lib/components/label.ws.js +8 -1
- package/lib/components/link-block.ws.js +2 -1
- package/lib/components/link.ws.js +8 -1
- package/lib/components/list-item.ws.js +11 -4
- package/lib/components/list.ws.js +2 -2
- package/lib/components/paragraph.ws.js +10 -3
- package/lib/components/radio-button-field.ws.js +12 -6
- package/lib/components/radio-button.ws.js +1 -0
- package/lib/components/rich-text-link.ws.js +1 -1
- package/lib/components/separator.ws.js +1 -1
- package/lib/components/slot.ws.js +3 -1
- package/lib/components/text-block.js +9 -3
- package/lib/components/text-block.ws.js +11 -3
- package/lib/components/textarea.ws.js +1 -0
- package/lib/embed-template.js +2 -1
- package/lib/index.js +4 -9
- package/lib/tree/create-elements-tree.js +8 -8
- package/lib/tree/root.js +2 -6
- package/lib/tree/webstudio-component.js +2 -2
- package/lib/types/components/component-meta.d.ts +363 -1356
- package/lib/types/components/components-utils.d.ts +2 -17
- package/lib/types/components/image.d.ts +5 -1
- package/lib/types/components/image.stories.d.ts +10 -2
- package/lib/types/components/index.d.ts +0 -15
- package/lib/types/components/text-block.d.ts +6 -2
- package/lib/types/components/text-block.stories.d.ts +6 -2
- package/lib/types/css/css.d.ts +14 -4
- package/lib/types/css/global-rules.d.ts +14 -4
- package/lib/types/css/normalize.d.ts +611 -611
- package/lib/types/css/style-rules.d.ts +2 -187
- package/lib/types/embed-template.d.ts +543 -167
- package/lib/types/index.d.ts +2 -2
- package/lib/types/props.d.ts +44 -18
- package/lib/types/tree/create-elements-tree.d.ts +4 -4
- package/lib/types/tree/root.d.ts +3 -5
- package/lib/types/tree/webstudio-component.d.ts +3 -3
- package/package.json +24 -13
- package/src/components/__generated__/image.props.ts +5 -2
- package/src/components/__generated__/text-block.props.ts +7 -0
- package/src/components/blockquote.ws.tsx +9 -2
- package/src/components/box.tsx +1 -1
- package/src/components/box.ws.ts +1 -0
- package/src/components/button.ws.tsx +2 -0
- package/src/components/checkbox-field.ws.tsx +12 -6
- package/src/components/checkbox.ws.tsx +1 -0
- package/src/components/code-text.ws.tsx +8 -1
- package/src/components/component-meta.ts +6 -3
- package/src/components/components-utils.ts +2 -31
- package/src/components/form.ws.tsx +32 -25
- package/src/components/fragment.ws.ts +1 -0
- package/src/components/heading.tsx +1 -1
- package/src/components/heading.ws.tsx +9 -2
- package/src/components/html-embed.ws.ts +2 -0
- package/src/components/image.tsx +54 -26
- package/src/components/image.ws.tsx +5 -1
- package/src/components/index.ts +0 -48
- package/src/components/input.ws.tsx +1 -0
- package/src/components/label.ws.tsx +8 -1
- package/src/components/link-block.ws.tsx +1 -0
- package/src/components/link.ws.tsx +8 -1
- package/src/components/list-item.ws.tsx +10 -3
- package/src/components/list.ws.tsx +2 -2
- package/src/components/paragraph.ws.tsx +9 -2
- package/src/components/radio-button-field.ws.tsx +12 -6
- package/src/components/radio-button.ws.tsx +1 -0
- package/src/components/rich-text-link.ws.tsx +1 -1
- package/src/components/separator.ws.tsx +1 -1
- package/src/components/slot.ws.ts +2 -0
- package/src/components/text-block.tsx +16 -5
- package/src/components/text-block.ws.tsx +10 -2
- package/src/components/textarea.ws.tsx +1 -0
- package/src/embed-template.ts +11 -3
- package/src/index.ts +2 -5
- package/src/props.test.ts +0 -1
- package/src/tree/create-elements-tree.tsx +12 -12
- package/src/tree/root.ts +4 -9
- package/src/tree/webstudio-component.tsx +4 -4
- package/lib/app/custom-components/__generated__/form.props.js +0 -411
- package/lib/app/custom-components/__generated__/image.props.js +0 -442
- package/lib/app/custom-components/__generated__/link-block.props.js +0 -432
- package/lib/app/custom-components/__generated__/link.props.js +0 -432
- package/lib/app/custom-components/__generated__/rich-text-link.props.js +0 -432
- package/lib/app/custom-components/form.js +0 -65
- package/lib/app/custom-components/form.ws.js +0 -81
- package/lib/app/custom-components/image.js +0 -40
- package/lib/app/custom-components/index.js +0 -29
- package/lib/app/custom-components/link-block.js +0 -6
- package/lib/app/custom-components/link.js +0 -6
- package/lib/app/custom-components/rich-text-link.js +0 -6
- package/lib/app/custom-components/shared/remix-link.js +0 -22
- package/lib/cjs/app/custom-components/__generated__/form.props.js +0 -431
- package/lib/cjs/app/custom-components/__generated__/image.props.js +0 -462
- package/lib/cjs/app/custom-components/__generated__/link-block.props.js +0 -452
- package/lib/cjs/app/custom-components/__generated__/link.props.js +0 -452
- package/lib/cjs/app/custom-components/__generated__/rich-text-link.props.js +0 -452
- package/lib/cjs/app/custom-components/form.js +0 -81
- package/lib/cjs/app/custom-components/form.ws.js +0 -101
- package/lib/cjs/app/custom-components/image.js +0 -54
- package/lib/cjs/app/custom-components/index.js +0 -49
- package/lib/cjs/app/custom-components/link-block.js +0 -26
- package/lib/cjs/app/custom-components/link.js +0 -26
- package/lib/cjs/app/custom-components/rich-text-link.js +0 -26
- package/lib/cjs/app/custom-components/shared/remix-link.js +0 -42
- package/lib/types/app/custom-components/__generated__/form.props.d.ts +0 -2
- package/lib/types/app/custom-components/__generated__/image.props.d.ts +0 -2
- package/lib/types/app/custom-components/__generated__/link-block.props.d.ts +0 -2
- package/lib/types/app/custom-components/__generated__/link.props.d.ts +0 -2
- package/lib/types/app/custom-components/__generated__/rich-text-link.props.d.ts +0 -2
- package/lib/types/app/custom-components/form.d.ts +0 -5
- package/lib/types/app/custom-components/form.ws.d.ts +0 -3
- package/lib/types/app/custom-components/image.d.ts +0 -6
- package/lib/types/app/custom-components/index.d.ts +0 -31
- package/lib/types/app/custom-components/link-block.d.ts +0 -6
- package/lib/types/app/custom-components/link.d.ts +0 -6
- package/lib/types/app/custom-components/rich-text-link.d.ts +0 -6
- package/lib/types/app/custom-components/shared/remix-link.d.ts +0 -10
- package/src/app/custom-components/__generated__/form.props.ts +0 -456
- package/src/app/custom-components/__generated__/image.props.ts +0 -487
- package/src/app/custom-components/__generated__/link-block.props.ts +0 -477
- package/src/app/custom-components/__generated__/link.props.ts +0 -477
- package/src/app/custom-components/__generated__/rich-text-link.props.ts +0 -477
- package/src/app/custom-components/form.tsx +0 -111
- package/src/app/custom-components/form.ws.tsx +0 -86
- package/src/app/custom-components/image.tsx +0 -55
- package/src/app/custom-components/index.ts +0 -28
- package/src/app/custom-components/link-block.tsx +0 -4
- package/src/app/custom-components/link.tsx +0 -4
- package/src/app/custom-components/rich-text-link.tsx +0 -4
- package/src/app/custom-components/shared/remix-link.tsx +0 -28
package/src/components/image.tsx
CHANGED
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ElementRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
useMemo,
|
|
6
|
+
} from "react";
|
|
7
|
+
import {
|
|
8
|
+
Image as WebstudioImage,
|
|
9
|
+
createImageLoader,
|
|
10
|
+
} from "@webstudio-is/image";
|
|
11
|
+
import { usePropAsset, getInstanceIdFromComponentProps } from "../props";
|
|
12
|
+
import { getParams } from "../app/params";
|
|
2
13
|
|
|
3
14
|
export const defaultTag = "img";
|
|
4
15
|
|
|
5
|
-
// quality and optimize can be overwritten and used by asset transform
|
|
6
|
-
// Or we need and additional way to pass them upper level
|
|
7
|
-
type ImageProps = ComponentProps<typeof defaultTag>;
|
|
8
|
-
|
|
9
|
-
export const Image = forwardRef<ElementRef<typeof defaultTag>, ImageProps>(
|
|
10
|
-
(imageProps, ref) => {
|
|
11
|
-
return (
|
|
12
|
-
<img
|
|
13
|
-
{...imageProps}
|
|
14
|
-
src={imageProps.src || imagePlaceholderSvg}
|
|
15
|
-
ref={ref}
|
|
16
|
-
/>
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
Image.defaultProps = {
|
|
22
|
-
src: "",
|
|
23
|
-
width: "",
|
|
24
|
-
height: "",
|
|
25
|
-
alt: "",
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
Image.displayName = "Image";
|
|
29
|
-
|
|
30
16
|
const imagePlaceholderSvg = `data:image/svg+xml;base64,${btoa(`<svg
|
|
31
17
|
width="140"
|
|
32
18
|
height="140"
|
|
@@ -50,3 +36,45 @@ const imagePlaceholderSvg = `data:image/svg+xml;base64,${btoa(`<svg
|
|
|
50
36
|
fill="#A2A2A2"
|
|
51
37
|
/>
|
|
52
38
|
</svg>`)}`;
|
|
39
|
+
|
|
40
|
+
type Props = ComponentPropsWithoutRef<typeof WebstudioImage>;
|
|
41
|
+
|
|
42
|
+
export const Image = forwardRef<ElementRef<typeof defaultTag>, Props>(
|
|
43
|
+
(props, ref) => {
|
|
44
|
+
const asset = usePropAsset(getInstanceIdFromComponentProps(props), "src");
|
|
45
|
+
|
|
46
|
+
const loader = useMemo(() => {
|
|
47
|
+
const params = getParams();
|
|
48
|
+
return createImageLoader({ imageBaseUrl: params.imageBaseUrl });
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const src = asset?.name ?? props.src;
|
|
52
|
+
|
|
53
|
+
if (asset == null || loader == null) {
|
|
54
|
+
return (
|
|
55
|
+
<img key={src} {...props} src={src || imagePlaceholderSvg} ref={ref} />
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<WebstudioImage
|
|
61
|
+
/**
|
|
62
|
+
* `key` is needed to recreate the image in case of asset change in builder,
|
|
63
|
+
* this gives immediate feedback when an asset is changed.
|
|
64
|
+
* Also, it visually fixes image distortion when another asset has a seriously different aspectRatio
|
|
65
|
+
* (we change aspectRatio CSS prop on asset change)
|
|
66
|
+
*
|
|
67
|
+
* In non-builder mode, key on images are usually also a good idea,
|
|
68
|
+
* prevents showing outdated images on route change.
|
|
69
|
+
**/
|
|
70
|
+
key={src}
|
|
71
|
+
{...props}
|
|
72
|
+
loader={loader}
|
|
73
|
+
src={src}
|
|
74
|
+
ref={ref}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
Image.displayName = "Image";
|
|
@@ -34,11 +34,15 @@ export const meta: WsComponentMeta = {
|
|
|
34
34
|
icon: ImageIcon,
|
|
35
35
|
states: defaultStates,
|
|
36
36
|
presetStyle,
|
|
37
|
+
order: 0,
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
// "loader" is our internal prop not intended to show up in the props panel
|
|
41
|
+
const { loader, ...publicProps } = props;
|
|
42
|
+
|
|
39
43
|
export const propsMeta: WsComponentPropsMeta = {
|
|
40
44
|
props: {
|
|
41
|
-
...
|
|
45
|
+
...publicProps,
|
|
42
46
|
src: {
|
|
43
47
|
type: "string",
|
|
44
48
|
control: "file",
|
package/src/components/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
|
2
|
-
import type { ComponentName } from "./components-utils";
|
|
3
2
|
import { meta as SlotMeta } from "./slot.ws";
|
|
4
3
|
import { meta as FragmentMeta } from "./fragment.ws";
|
|
5
4
|
import { meta as HtmlEmbedMeta } from "./html-embed.ws";
|
|
@@ -106,22 +105,6 @@ export const defaultMetas: Record<string, WsComponentMeta> = {
|
|
|
106
105
|
Checkbox: CheckboxMeta,
|
|
107
106
|
};
|
|
108
107
|
|
|
109
|
-
let currentMetas = defaultMetas;
|
|
110
|
-
|
|
111
|
-
export const getComponentMeta = (name: string): WsComponentMeta | undefined => {
|
|
112
|
-
return currentMetas[name];
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export const registerComponentMetas = (
|
|
116
|
-
overrides: Record<string, Partial<WsComponentMeta>>
|
|
117
|
-
) => {
|
|
118
|
-
const result: typeof currentMetas = {};
|
|
119
|
-
for (const name of Object.keys(defaultMetas)) {
|
|
120
|
-
result[name] = { ...defaultMetas[name], ...overrides[name] };
|
|
121
|
-
}
|
|
122
|
-
currentMetas = result;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
108
|
// @todo this list should not be hardcoded!
|
|
126
109
|
export const defaultPropsMetas: Record<string, WsComponentPropsMeta> = {
|
|
127
110
|
Slot: SlotMetaPropsMeta,
|
|
@@ -158,34 +141,3 @@ export const defaultPropsMetas: Record<string, WsComponentPropsMeta> = {
|
|
|
158
141
|
CheckboxField: CheckboxFieldPropsMeta,
|
|
159
142
|
Checkbox: CheckboxPropsMeta,
|
|
160
143
|
};
|
|
161
|
-
|
|
162
|
-
type RegisteredComponents = Partial<{
|
|
163
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
164
|
-
[name in ComponentName]: {};
|
|
165
|
-
}>;
|
|
166
|
-
|
|
167
|
-
export let registeredComponents: RegisteredComponents | undefined;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @todo: Allow register any component.
|
|
171
|
-
* Now we can register only existings Components, as all our type system would
|
|
172
|
-
* break otherwise, see getComponent etc. So its overwriteComponent now
|
|
173
|
-
**/
|
|
174
|
-
export const registerComponents = (components: RegisteredComponents) => {
|
|
175
|
-
registeredComponents = components;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export const canAcceptComponent = (
|
|
179
|
-
parentComponent: string,
|
|
180
|
-
childComponent: string
|
|
181
|
-
) => {
|
|
182
|
-
const parentMeta = getComponentMeta(parentComponent);
|
|
183
|
-
const childMeta = getComponentMeta(childComponent);
|
|
184
|
-
if (parentMeta?.type !== "container" || childMeta === undefined) {
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
return (
|
|
188
|
-
childMeta.acceptedParents === undefined ||
|
|
189
|
-
childMeta.acceptedParents.includes(parentComponent)
|
|
190
|
-
);
|
|
191
|
-
};
|
|
@@ -23,7 +23,14 @@ export const meta: WsComponentMeta = {
|
|
|
23
23
|
icon: TextBlockIcon,
|
|
24
24
|
states: defaultStates,
|
|
25
25
|
presetStyle,
|
|
26
|
-
|
|
26
|
+
order: 2,
|
|
27
|
+
template: [
|
|
28
|
+
{
|
|
29
|
+
type: "instance",
|
|
30
|
+
component: "Label",
|
|
31
|
+
children: [{ type: "text", value: "Form Label" }],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
export const propsMeta: WsComponentPropsMeta = {
|
|
@@ -29,6 +29,7 @@ export const meta: WsComponentMeta = {
|
|
|
29
29
|
label: "Link Text",
|
|
30
30
|
icon: LinkIcon,
|
|
31
31
|
presetStyle,
|
|
32
|
+
order: 1,
|
|
32
33
|
states: [
|
|
33
34
|
...defaultStates,
|
|
34
35
|
{
|
|
@@ -41,7 +42,13 @@ export const meta: WsComponentMeta = {
|
|
|
41
42
|
label: "Current page",
|
|
42
43
|
},
|
|
43
44
|
],
|
|
44
|
-
|
|
45
|
+
template: [
|
|
46
|
+
{
|
|
47
|
+
type: "instance",
|
|
48
|
+
component: "Link",
|
|
49
|
+
children: [{ type: "text", value: "Link text you can edit" }],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
45
52
|
};
|
|
46
53
|
|
|
47
54
|
export const propsMeta: WsComponentPropsMeta = {
|
|
@@ -14,14 +14,21 @@ const presetStyle = {
|
|
|
14
14
|
} satisfies PresetStyle<typeof defaultTag>;
|
|
15
15
|
|
|
16
16
|
export const meta: WsComponentMeta = {
|
|
17
|
-
category: "
|
|
17
|
+
category: "general",
|
|
18
18
|
type: "rich-text",
|
|
19
|
-
|
|
19
|
+
requiredAncestors: ["List"],
|
|
20
20
|
label: "List Item",
|
|
21
21
|
icon: ListItemIcon,
|
|
22
|
-
children: [{ type: "text", value: "List Item you can edit" }],
|
|
23
22
|
states: defaultStates,
|
|
24
23
|
presetStyle,
|
|
24
|
+
template: [
|
|
25
|
+
{
|
|
26
|
+
type: "instance",
|
|
27
|
+
component: "ListItem",
|
|
28
|
+
children: [{ type: "text", value: "List Item you can edit" }],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
order: 4,
|
|
25
32
|
};
|
|
26
33
|
|
|
27
34
|
export const propsMeta: WsComponentPropsMeta = {
|
|
@@ -43,13 +43,13 @@ const presetStyle = {
|
|
|
43
43
|
} satisfies PresetStyle<ListTag>;
|
|
44
44
|
|
|
45
45
|
export const meta: WsComponentMeta = {
|
|
46
|
-
category: "
|
|
46
|
+
category: "general",
|
|
47
47
|
type: "container",
|
|
48
48
|
label: "List",
|
|
49
49
|
icon: ListIcon,
|
|
50
50
|
states: defaultStates,
|
|
51
51
|
presetStyle,
|
|
52
|
-
|
|
52
|
+
order: 3,
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
export const propsMeta: WsComponentPropsMeta = {
|
|
@@ -14,13 +14,20 @@ const presetStyle = {
|
|
|
14
14
|
} satisfies PresetStyle<typeof defaultTag>;
|
|
15
15
|
|
|
16
16
|
export const meta: WsComponentMeta = {
|
|
17
|
-
category: "
|
|
17
|
+
category: "text",
|
|
18
18
|
type: "rich-text",
|
|
19
19
|
label: "Paragraph",
|
|
20
20
|
icon: TextAlignLeftIcon,
|
|
21
|
-
children: [{ type: "text", value: "Pragraph you can edit" }],
|
|
22
21
|
states: defaultStates,
|
|
23
22
|
presetStyle,
|
|
23
|
+
template: [
|
|
24
|
+
{
|
|
25
|
+
type: "instance",
|
|
26
|
+
component: "Paragraph",
|
|
27
|
+
children: [{ type: "text", value: "Pragraph you can edit" }],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
order: 2,
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
export const propsMeta: WsComponentPropsMeta = {
|
|
@@ -23,14 +23,20 @@ export const meta: WsComponentMeta = {
|
|
|
23
23
|
icon: RadioCheckedIcon,
|
|
24
24
|
states: defaultStates,
|
|
25
25
|
presetStyle,
|
|
26
|
-
|
|
27
|
-
{ type: "instance", component: "RadioButton", props: [], children: [] },
|
|
26
|
+
template: [
|
|
28
27
|
{
|
|
29
28
|
type: "instance",
|
|
30
|
-
component: "
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
component: "RadioButtonField",
|
|
30
|
+
children: [
|
|
31
|
+
{ type: "instance", component: "RadioButton", props: [], children: [] },
|
|
32
|
+
{
|
|
33
|
+
type: "instance",
|
|
34
|
+
component: "TextBlock",
|
|
35
|
+
label: "Radio Label",
|
|
36
|
+
props: [],
|
|
37
|
+
children: [{ type: "text", value: "Radio" }],
|
|
38
|
+
},
|
|
39
|
+
],
|
|
34
40
|
},
|
|
35
41
|
],
|
|
36
42
|
};
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createElement,
|
|
3
|
+
forwardRef,
|
|
4
|
+
type ElementRef,
|
|
5
|
+
type ComponentProps,
|
|
6
|
+
} from "react";
|
|
2
7
|
|
|
3
8
|
export const defaultTag = "div";
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
// We don't want to enable all tags because Box is usually a container and we have specific components for many tags.
|
|
11
|
+
type Props = ComponentProps<typeof defaultTag> & {
|
|
12
|
+
tag?: "div" | "span" | "figcaption";
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const TextBlock = forwardRef<ElementRef<typeof defaultTag>, Props>(
|
|
16
|
+
({ tag = defaultTag, ...props }, ref) => {
|
|
17
|
+
return createElement(tag, { ...props, ref });
|
|
18
|
+
}
|
|
19
|
+
);
|
|
9
20
|
|
|
10
21
|
TextBlock.displayName = "TextBlock";
|
|
@@ -20,15 +20,23 @@ const presetStyle = {
|
|
|
20
20
|
} satisfies PresetStyle<typeof defaultTag>;
|
|
21
21
|
|
|
22
22
|
export const meta: WsComponentMeta = {
|
|
23
|
-
category: "
|
|
23
|
+
category: "text",
|
|
24
24
|
type: "rich-text",
|
|
25
25
|
label: "Text Block",
|
|
26
26
|
icon: TextBlockIcon,
|
|
27
27
|
states: defaultStates,
|
|
28
28
|
presetStyle,
|
|
29
|
-
|
|
29
|
+
template: [
|
|
30
|
+
{
|
|
31
|
+
type: "instance",
|
|
32
|
+
component: "TextBlock",
|
|
33
|
+
children: [{ type: "text", value: "Block of text you can edit" }],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
order: 0,
|
|
30
37
|
};
|
|
31
38
|
|
|
32
39
|
export const propsMeta: WsComponentPropsMeta = {
|
|
33
40
|
props,
|
|
41
|
+
initialProps: ["tag"],
|
|
34
42
|
};
|
package/src/embed-template.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
Breakpoint,
|
|
11
11
|
} from "@webstudio-is/project-build";
|
|
12
12
|
import { StyleValue, type StyleProperty } from "@webstudio-is/css-data";
|
|
13
|
+
import type { Simplify } from "type-fest";
|
|
13
14
|
|
|
14
15
|
const EmbedTemplateText = z.object({
|
|
15
16
|
type: z.literal("text"),
|
|
@@ -43,13 +44,20 @@ const EmbedTemplateProp = z.union([
|
|
|
43
44
|
|
|
44
45
|
type EmbedTemplateProp = z.infer<typeof EmbedTemplateProp>;
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
const EmbedTemplateStyleDeclRaw = z.object({
|
|
47
48
|
state: z.optional(z.string()),
|
|
48
|
-
property: z.string()
|
|
49
|
+
property: z.string(),
|
|
49
50
|
value: StyleValue,
|
|
50
51
|
});
|
|
51
52
|
|
|
52
|
-
export type EmbedTemplateStyleDecl =
|
|
53
|
+
export type EmbedTemplateStyleDecl = Simplify<
|
|
54
|
+
Omit<z.infer<typeof EmbedTemplateStyleDeclRaw>, "property"> & {
|
|
55
|
+
property: StyleProperty;
|
|
56
|
+
}
|
|
57
|
+
>;
|
|
58
|
+
|
|
59
|
+
export const EmbedTemplateStyleDecl =
|
|
60
|
+
EmbedTemplateStyleDeclRaw as z.ZodType<EmbedTemplateStyleDecl>;
|
|
53
61
|
|
|
54
62
|
export type EmbedTemplateInstance = {
|
|
55
63
|
type: "instance";
|
package/src/index.ts
CHANGED
|
@@ -5,16 +5,13 @@ export * from "./pubsub";
|
|
|
5
5
|
export * from "./app";
|
|
6
6
|
export * from "./components/components";
|
|
7
7
|
export * from "./components/components-utils";
|
|
8
|
-
export {
|
|
9
|
-
customComponents,
|
|
10
|
-
customComponentMetas,
|
|
11
|
-
customComponentPropsMetas,
|
|
12
|
-
} from "./app/custom-components";
|
|
13
8
|
export {
|
|
14
9
|
type WsComponentPropsMeta,
|
|
15
10
|
type WsComponentMeta,
|
|
16
11
|
type ComponentState,
|
|
12
|
+
type PresetStyle,
|
|
17
13
|
componentCategories,
|
|
18
14
|
stateCategories,
|
|
19
15
|
} from "./components/component-meta";
|
|
20
16
|
export * from "./embed-template";
|
|
17
|
+
export { usePropUrl, getInstanceIdFromComponentProps } from "./props";
|
package/src/props.test.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ReadableAtom } from "nanostores";
|
|
|
3
3
|
import { Scripts, ScrollRestoration } from "@remix-run/react";
|
|
4
4
|
import type { Assets } from "@webstudio-is/asset-uploader";
|
|
5
5
|
import type { Instance, Instances } from "@webstudio-is/project-build";
|
|
6
|
-
import type {
|
|
6
|
+
import type { Components } from "../components/components-utils";
|
|
7
7
|
import { ReactSdkContext } from "../context";
|
|
8
8
|
import type { Pages, PropsByInstanceId } from "../props";
|
|
9
9
|
import type { WebstudioComponent } from "./webstudio-component";
|
|
@@ -18,7 +18,7 @@ export const createElementsTree = ({
|
|
|
18
18
|
assetsStore,
|
|
19
19
|
pagesStore,
|
|
20
20
|
Component,
|
|
21
|
-
|
|
21
|
+
components,
|
|
22
22
|
}: {
|
|
23
23
|
renderer?: "canvas";
|
|
24
24
|
instances: Instances;
|
|
@@ -27,7 +27,7 @@ export const createElementsTree = ({
|
|
|
27
27
|
assetsStore: ReadableAtom<Assets>;
|
|
28
28
|
pagesStore: ReadableAtom<Pages>;
|
|
29
29
|
Component: (props: ComponentProps<typeof WebstudioComponent>) => JSX.Element;
|
|
30
|
-
|
|
30
|
+
components: Components;
|
|
31
31
|
}) => {
|
|
32
32
|
const rootInstance = instances.get(rootInstanceId);
|
|
33
33
|
if (rootInstance === undefined) {
|
|
@@ -40,7 +40,7 @@ export const createElementsTree = ({
|
|
|
40
40
|
instanceSelector: rootInstanceSelector,
|
|
41
41
|
Component,
|
|
42
42
|
children: rootInstance.children,
|
|
43
|
-
|
|
43
|
+
components,
|
|
44
44
|
});
|
|
45
45
|
const root = createInstanceElement({
|
|
46
46
|
Component,
|
|
@@ -53,7 +53,7 @@ export const createElementsTree = ({
|
|
|
53
53
|
<Scripts />
|
|
54
54
|
</Fragment>,
|
|
55
55
|
],
|
|
56
|
-
|
|
56
|
+
components,
|
|
57
57
|
});
|
|
58
58
|
return (
|
|
59
59
|
<ReactSdkContext.Provider
|
|
@@ -69,13 +69,13 @@ const createInstanceChildrenElements = ({
|
|
|
69
69
|
instanceSelector,
|
|
70
70
|
children,
|
|
71
71
|
Component,
|
|
72
|
-
|
|
72
|
+
components,
|
|
73
73
|
}: {
|
|
74
74
|
instances: Instances;
|
|
75
75
|
instanceSelector: InstanceSelector;
|
|
76
76
|
children: Instance["children"];
|
|
77
77
|
Component: (props: ComponentProps<typeof WebstudioComponent>) => JSX.Element;
|
|
78
|
-
|
|
78
|
+
components: Components;
|
|
79
79
|
}) => {
|
|
80
80
|
const elements = [];
|
|
81
81
|
for (const child of children) {
|
|
@@ -93,14 +93,14 @@ const createInstanceChildrenElements = ({
|
|
|
93
93
|
instanceSelector: childInstanceSelector,
|
|
94
94
|
children: childInstance.children,
|
|
95
95
|
Component,
|
|
96
|
-
|
|
96
|
+
components,
|
|
97
97
|
});
|
|
98
98
|
const element = createInstanceElement({
|
|
99
99
|
instance: childInstance,
|
|
100
100
|
instanceSelector: childInstanceSelector,
|
|
101
101
|
Component,
|
|
102
102
|
children,
|
|
103
|
-
|
|
103
|
+
components,
|
|
104
104
|
});
|
|
105
105
|
elements.push(element);
|
|
106
106
|
}
|
|
@@ -112,20 +112,20 @@ const createInstanceElement = ({
|
|
|
112
112
|
instance,
|
|
113
113
|
instanceSelector,
|
|
114
114
|
children = [],
|
|
115
|
-
|
|
115
|
+
components,
|
|
116
116
|
}: {
|
|
117
117
|
instance: Instance;
|
|
118
118
|
instanceSelector: InstanceSelector;
|
|
119
119
|
Component: (props: ComponentProps<typeof WebstudioComponent>) => JSX.Element;
|
|
120
120
|
children?: Array<JSX.Element | string>;
|
|
121
|
-
|
|
121
|
+
components: Components;
|
|
122
122
|
}) => {
|
|
123
123
|
return (
|
|
124
124
|
<Component
|
|
125
125
|
key={instance.id}
|
|
126
126
|
instance={instance}
|
|
127
127
|
instanceSelector={instanceSelector}
|
|
128
|
-
|
|
128
|
+
components={components}
|
|
129
129
|
>
|
|
130
130
|
{children}
|
|
131
131
|
</Component>
|
package/src/tree/root.ts
CHANGED
|
@@ -4,11 +4,9 @@ import type { Build, Page } from "@webstudio-is/project-build";
|
|
|
4
4
|
import type { Asset } from "@webstudio-is/asset-uploader";
|
|
5
5
|
import { createElementsTree } from "./create-elements-tree";
|
|
6
6
|
import { WebstudioComponent } from "./webstudio-component";
|
|
7
|
-
import { registerComponents } from "../components";
|
|
8
|
-
import { customComponents as defaultCustomComponents } from "../app/custom-components";
|
|
9
7
|
import { setParams, type Params } from "../app/params";
|
|
10
8
|
import { getPropsByInstanceId } from "../props";
|
|
11
|
-
import type {
|
|
9
|
+
import type { Components } from "../components/components-utils";
|
|
12
10
|
|
|
13
11
|
export type Data = {
|
|
14
12
|
page: Page;
|
|
@@ -25,18 +23,15 @@ export type RootPropsData = Omit<Data, "build"> & {
|
|
|
25
23
|
type RootProps = {
|
|
26
24
|
data: RootPropsData;
|
|
27
25
|
Component?: (props: ComponentProps<typeof WebstudioComponent>) => JSX.Element;
|
|
28
|
-
|
|
29
|
-
getComponent: GetComponent;
|
|
26
|
+
components: Components;
|
|
30
27
|
};
|
|
31
28
|
|
|
32
29
|
export const InstanceRoot = ({
|
|
33
30
|
data,
|
|
34
31
|
Component,
|
|
35
|
-
|
|
36
|
-
getComponent,
|
|
32
|
+
components,
|
|
37
33
|
}: RootProps): JSX.Element | null => {
|
|
38
34
|
setParams(data.params);
|
|
39
|
-
registerComponents(customComponents);
|
|
40
35
|
return createElementsTree({
|
|
41
36
|
instances: new Map(data.build.instances),
|
|
42
37
|
rootInstanceId: data.page.rootInstanceId,
|
|
@@ -46,6 +41,6 @@ export const InstanceRoot = ({
|
|
|
46
41
|
assetsStore: atom(new Map(data.assets.map((asset) => [asset.id, asset]))),
|
|
47
42
|
pagesStore: atom(new Map(data.pages.map((page) => [page.id, page]))),
|
|
48
43
|
Component: Component ?? WebstudioComponent,
|
|
49
|
-
|
|
44
|
+
components,
|
|
50
45
|
});
|
|
51
46
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment } from "react";
|
|
2
2
|
import type { Instance } from "@webstudio-is/project-build";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Components } from "../components/components-utils";
|
|
4
4
|
import { useInstanceProps } from "../props";
|
|
5
5
|
|
|
6
6
|
const renderText = (text: string): Array<JSX.Element> => {
|
|
@@ -30,14 +30,14 @@ type WebstudioComponentProps = {
|
|
|
30
30
|
instance: Instance;
|
|
31
31
|
instanceSelector: Instance["id"][];
|
|
32
32
|
children: Array<JSX.Element | string>;
|
|
33
|
-
|
|
33
|
+
components: Components;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export const WebstudioComponent = ({
|
|
37
37
|
instance,
|
|
38
38
|
instanceSelector,
|
|
39
39
|
children,
|
|
40
|
-
|
|
40
|
+
components,
|
|
41
41
|
...rest
|
|
42
42
|
}: WebstudioComponentProps) => {
|
|
43
43
|
const instanceProps = useInstanceProps(instance.id);
|
|
@@ -47,7 +47,7 @@ export const WebstudioComponent = ({
|
|
|
47
47
|
[idAttribute]: instance.id,
|
|
48
48
|
[componentAttribute]: instance.component,
|
|
49
49
|
};
|
|
50
|
-
const Component =
|
|
50
|
+
const Component = components.get(instance.component);
|
|
51
51
|
if (Component === undefined) {
|
|
52
52
|
return <></>;
|
|
53
53
|
}
|