@webstudio-is/react-sdk 0.63.0 → 0.65.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/app/custom-components/__generated__/form.props.js +1 -2
- package/lib/app/custom-components/form.js +13 -2
- package/lib/app/custom-components/form.ws.js +1 -1
- package/lib/cjs/app/custom-components/__generated__/form.props.js +1 -2
- package/lib/cjs/app/custom-components/form.js +19 -8
- package/lib/cjs/app/custom-components/form.ws.js +1 -1
- package/lib/cjs/components/button.ws.js +1 -1
- package/lib/cjs/components/checkbox-field.ws.js +2 -1
- package/lib/cjs/components/checkbox.ws.js +1 -1
- package/lib/cjs/components/form.ws.js +1 -1
- package/lib/cjs/components/input.ws.js +1 -1
- package/lib/cjs/components/radio-button-field.ws.js +2 -1
- package/lib/cjs/components/radio-button.ws.js +1 -1
- package/lib/cjs/css/normalize.js +1 -1
- package/lib/cjs/css/presets.js +1 -19
- package/lib/cjs/embed-template.js +2 -0
- package/lib/components/button.ws.js +1 -1
- package/lib/components/checkbox-field.ws.js +2 -1
- package/lib/components/checkbox.ws.js +1 -1
- package/lib/components/form.ws.js +1 -1
- package/lib/components/input.ws.js +1 -1
- package/lib/components/radio-button-field.ws.js +2 -1
- package/lib/components/radio-button.ws.js +1 -1
- package/lib/css/normalize.js +2 -2
- package/lib/css/presets.js +1 -19
- package/lib/embed-template.js +2 -0
- package/lib/types/app/custom-components/form.d.ts +1 -1
- package/lib/types/app/custom-components/index.d.ts +1 -1
- package/lib/types/css/presets.d.ts +0 -1
- package/lib/types/embed-template.d.ts +1 -0
- package/package.json +12 -11
- package/src/app/custom-components/__generated__/form.props.ts +1 -2
- package/src/app/custom-components/form.tsx +27 -10
- package/src/app/custom-components/form.ws.tsx +1 -1
- package/src/components/button.ws.tsx +1 -1
- package/src/components/checkbox-field.ws.tsx +2 -1
- package/src/components/checkbox.ws.tsx +1 -1
- package/src/components/form.ws.tsx +1 -1
- package/src/components/input.ws.tsx +1 -1
- package/src/components/radio-button-field.ws.tsx +2 -1
- package/src/components/radio-button.ws.tsx +1 -1
- package/src/css/normalize.ts +2 -2
- package/src/css/presets.ts +0 -18
- package/src/embed-template.ts +3 -0
|
@@ -3,10 +3,8 @@ const props = {
|
|
|
3
3
|
style: { required: false, control: "text", type: "string" },
|
|
4
4
|
title: { required: false, control: "text", type: "string" },
|
|
5
5
|
acceptCharset: { required: false, control: "text", type: "string" },
|
|
6
|
-
action: { required: false, control: "text", type: "string" },
|
|
7
6
|
autoComplete: { required: false, control: "text", type: "string" },
|
|
8
7
|
encType: { required: false, control: "text", type: "string" },
|
|
9
|
-
method: { required: false, control: "text", type: "string" },
|
|
10
8
|
name: { required: false, control: "text", type: "string" },
|
|
11
9
|
noValidate: { required: false, control: "boolean", type: "boolean" },
|
|
12
10
|
target: { required: false, control: "text", type: "string" },
|
|
@@ -404,6 +402,7 @@ const props = {
|
|
|
404
402
|
required: false,
|
|
405
403
|
control: "radio",
|
|
406
404
|
type: "string",
|
|
405
|
+
defaultValue: "initial",
|
|
407
406
|
options: ["initial", "success", "error"]
|
|
408
407
|
}
|
|
409
408
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFetcher } from "@remix-run/react";
|
|
3
|
+
import { formIdFieldName } from "@webstudio-is/form-handlers";
|
|
2
4
|
import {
|
|
3
5
|
Children,
|
|
4
6
|
cloneElement,
|
|
5
7
|
forwardRef
|
|
6
8
|
} from "react";
|
|
9
|
+
import { getInstanceIdFromComponentProps } from "../../props";
|
|
7
10
|
const defaultTag = "form";
|
|
8
11
|
const isComponentNode = (component, node) => "props" in node && node.props.instance?.component === component;
|
|
9
12
|
const onlyErrorMessage = (children) => Children.map(children, (child) => {
|
|
@@ -46,7 +49,15 @@ const withoutMessages = (children) => Children.map(children, (child) => {
|
|
|
46
49
|
}
|
|
47
50
|
return withoutMessages(child);
|
|
48
51
|
});
|
|
49
|
-
const Form = forwardRef(({ children, initialState = "initial", ...props }, ref) =>
|
|
52
|
+
const Form = forwardRef(({ children, initialState = "initial", ...props }, ref) => {
|
|
53
|
+
const fetcher = useFetcher();
|
|
54
|
+
const state = fetcher.type === "done" ? fetcher.data?.success === true ? "success" : "error" : initialState;
|
|
55
|
+
const instanceId = getInstanceIdFromComponentProps(props);
|
|
56
|
+
return /* @__PURE__ */ jsxs(fetcher.Form, { ...props, method: "post", "data-state": state, ref, children: [
|
|
57
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: formIdFieldName, value: instanceId }),
|
|
58
|
+
state === "success" ? onlySuccessMessage(children) : state === "error" ? onlyErrorMessage(children) : withoutMessages(children)
|
|
59
|
+
] });
|
|
60
|
+
});
|
|
50
61
|
Form.displayName = "Form";
|
|
51
62
|
export {
|
|
52
63
|
Form,
|
|
@@ -26,10 +26,8 @@ const props = {
|
|
|
26
26
|
style: { required: false, control: "text", type: "string" },
|
|
27
27
|
title: { required: false, control: "text", type: "string" },
|
|
28
28
|
acceptCharset: { required: false, control: "text", type: "string" },
|
|
29
|
-
action: { required: false, control: "text", type: "string" },
|
|
30
29
|
autoComplete: { required: false, control: "text", type: "string" },
|
|
31
30
|
encType: { required: false, control: "text", type: "string" },
|
|
32
|
-
method: { required: false, control: "text", type: "string" },
|
|
33
31
|
name: { required: false, control: "text", type: "string" },
|
|
34
32
|
noValidate: { required: false, control: "boolean", type: "boolean" },
|
|
35
33
|
target: { required: false, control: "text", type: "string" },
|
|
@@ -427,6 +425,7 @@ const props = {
|
|
|
427
425
|
required: false,
|
|
428
426
|
control: "radio",
|
|
429
427
|
type: "string",
|
|
428
|
+
defaultValue: "initial",
|
|
430
429
|
options: ["initial", "success", "error"]
|
|
431
430
|
}
|
|
432
431
|
};
|
|
@@ -23,10 +23,13 @@ __export(form_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(form_exports);
|
|
25
25
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
-
var import_react = require("react");
|
|
26
|
+
var import_react = require("@remix-run/react");
|
|
27
|
+
var import_form_handlers = require("@webstudio-is/form-handlers");
|
|
28
|
+
var import_react2 = require("react");
|
|
29
|
+
var import_props = require("../../props");
|
|
27
30
|
const defaultTag = "form";
|
|
28
31
|
const isComponentNode = (component, node) => "props" in node && node.props.instance?.component === component;
|
|
29
|
-
const onlyErrorMessage = (children) =>
|
|
32
|
+
const onlyErrorMessage = (children) => import_react2.Children.map(children, (child) => {
|
|
30
33
|
if (typeof child !== "object" || child === null) {
|
|
31
34
|
return null;
|
|
32
35
|
}
|
|
@@ -35,11 +38,11 @@ const onlyErrorMessage = (children) => import_react.Children.map(children, (chil
|
|
|
35
38
|
}
|
|
36
39
|
if ("props" in child) {
|
|
37
40
|
const newChildren = onlyErrorMessage(child.props.children);
|
|
38
|
-
return
|
|
41
|
+
return import_react2.Children.toArray(newChildren).some((child2) => child2 !== null) ? (0, import_react2.cloneElement)(child, { children: newChildren }) : null;
|
|
39
42
|
}
|
|
40
43
|
return onlyErrorMessage(child);
|
|
41
44
|
});
|
|
42
|
-
const onlySuccessMessage = (children) =>
|
|
45
|
+
const onlySuccessMessage = (children) => import_react2.Children.map(children, (child) => {
|
|
43
46
|
if (typeof child !== "object" || child === null) {
|
|
44
47
|
return null;
|
|
45
48
|
}
|
|
@@ -48,11 +51,11 @@ const onlySuccessMessage = (children) => import_react.Children.map(children, (ch
|
|
|
48
51
|
}
|
|
49
52
|
if ("props" in child) {
|
|
50
53
|
const newChildren = onlySuccessMessage(child.props.children);
|
|
51
|
-
return
|
|
54
|
+
return import_react2.Children.toArray(newChildren).some((child2) => child2 !== null) ? (0, import_react2.cloneElement)(child, { children: newChildren }) : null;
|
|
52
55
|
}
|
|
53
56
|
return onlySuccessMessage(child);
|
|
54
57
|
});
|
|
55
|
-
const withoutMessages = (children) =>
|
|
58
|
+
const withoutMessages = (children) => import_react2.Children.map(children, (child) => {
|
|
56
59
|
if (typeof child !== "object" || child === null) {
|
|
57
60
|
return child;
|
|
58
61
|
}
|
|
@@ -60,11 +63,19 @@ const withoutMessages = (children) => import_react.Children.map(children, (child
|
|
|
60
63
|
return null;
|
|
61
64
|
}
|
|
62
65
|
if ("props" in child) {
|
|
63
|
-
return (0,
|
|
66
|
+
return (0, import_react2.cloneElement)(child, {
|
|
64
67
|
children: withoutMessages(child.props.children)
|
|
65
68
|
});
|
|
66
69
|
}
|
|
67
70
|
return withoutMessages(child);
|
|
68
71
|
});
|
|
69
|
-
const Form = (0,
|
|
72
|
+
const Form = (0, import_react2.forwardRef)(({ children, initialState = "initial", ...props }, ref) => {
|
|
73
|
+
const fetcher = (0, import_react.useFetcher)();
|
|
74
|
+
const state = fetcher.type === "done" ? fetcher.data?.success === true ? "success" : "error" : initialState;
|
|
75
|
+
const instanceId = (0, import_props.getInstanceIdFromComponentProps)(props);
|
|
76
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(fetcher.Form, { ...props, method: "post", "data-state": state, ref, children: [
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "hidden", name: import_form_handlers.formIdFieldName, value: instanceId }),
|
|
78
|
+
state === "success" ? onlySuccessMessage(children) : state === "error" ? onlyErrorMessage(children) : withoutMessages(children)
|
|
79
|
+
] });
|
|
80
|
+
});
|
|
70
81
|
Form.displayName = "Form";
|
|
@@ -35,7 +35,7 @@ const presetStyle = {
|
|
|
35
35
|
const meta = {
|
|
36
36
|
category: "forms",
|
|
37
37
|
type: "container",
|
|
38
|
-
label: "Checkbox
|
|
38
|
+
label: "Checkbox",
|
|
39
39
|
Icon: import_icons.CheckboxCheckedIcon,
|
|
40
40
|
states: import_component_meta.defaultStates,
|
|
41
41
|
presetStyle,
|
|
@@ -44,6 +44,7 @@ const meta = {
|
|
|
44
44
|
{
|
|
45
45
|
type: "instance",
|
|
46
46
|
component: "TextBlock",
|
|
47
|
+
label: "Checkbox Label",
|
|
47
48
|
props: [],
|
|
48
49
|
children: [{ type: "text", value: "Checkbox" }]
|
|
49
50
|
}
|
|
@@ -35,7 +35,7 @@ const presetStyle = {
|
|
|
35
35
|
const meta = {
|
|
36
36
|
category: "forms",
|
|
37
37
|
type: "container",
|
|
38
|
-
label: "Radio
|
|
38
|
+
label: "Radio",
|
|
39
39
|
Icon: import_icons.RadioCheckedIcon,
|
|
40
40
|
states: import_component_meta.defaultStates,
|
|
41
41
|
presetStyle,
|
|
@@ -44,6 +44,7 @@ const meta = {
|
|
|
44
44
|
{
|
|
45
45
|
type: "instance",
|
|
46
46
|
component: "TextBlock",
|
|
47
|
+
label: "Radio Label",
|
|
47
48
|
props: [],
|
|
48
49
|
children: [{ type: "text", value: "Radio" }]
|
|
49
50
|
}
|
package/lib/cjs/css/normalize.js
CHANGED
|
@@ -93,7 +93,7 @@ const h5 = baseStyle;
|
|
|
93
93
|
const h6 = baseStyle;
|
|
94
94
|
const i = baseStyle;
|
|
95
95
|
const img = baseStyle;
|
|
96
|
-
const a =
|
|
96
|
+
const a = baseStyle;
|
|
97
97
|
const li = baseStyle;
|
|
98
98
|
const ul = baseStyle;
|
|
99
99
|
const ol = baseStyle;
|
package/lib/cjs/css/presets.js
CHANGED
|
@@ -18,8 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var presets_exports = {};
|
|
20
20
|
__export(presets_exports, {
|
|
21
|
-
borders: () => borders
|
|
22
|
-
linkColors: () => linkColors
|
|
21
|
+
borders: () => borders
|
|
23
22
|
});
|
|
24
23
|
module.exports = __toCommonJS(presets_exports);
|
|
25
24
|
const borders = [
|
|
@@ -40,20 +39,3 @@ const borders = [
|
|
|
40
39
|
value: { type: "unit", value: 1, unit: "px" }
|
|
41
40
|
}
|
|
42
41
|
];
|
|
43
|
-
const linkColors = [
|
|
44
|
-
{
|
|
45
|
-
property: "color",
|
|
46
|
-
value: { type: "rgb", r: 0, g: 0, b: 238, alpha: 1 }
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
state: ":active",
|
|
50
|
-
property: "color",
|
|
51
|
-
// chrome and safari use rgb(255, 0, 0)
|
|
52
|
-
value: { type: "rgb", r: 238, g: 0, b: 0, alpha: 1 }
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
state: ":visited",
|
|
56
|
-
property: "color",
|
|
57
|
-
value: { type: "rgb", r: 85, g: 26, b: 139, alpha: 1 }
|
|
58
|
-
}
|
|
59
|
-
];
|
|
@@ -62,6 +62,7 @@ const EmbedTemplateInstance = import_zod.z.lazy(
|
|
|
62
62
|
() => import_zod.z.object({
|
|
63
63
|
type: import_zod.z.literal("instance"),
|
|
64
64
|
component: import_zod.z.string(),
|
|
65
|
+
label: import_zod.z.optional(import_zod.z.string()),
|
|
65
66
|
props: import_zod.z.optional(import_zod.z.array(EmbedTemplateProp)),
|
|
66
67
|
styles: import_zod.z.optional(import_zod.z.array(EmbedTemplateStyleDecl)),
|
|
67
68
|
children: WsEmbedTemplate
|
|
@@ -107,6 +108,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, styleSource
|
|
|
107
108
|
const instance = {
|
|
108
109
|
type: "instance",
|
|
109
110
|
id: instanceId,
|
|
111
|
+
label: item.label,
|
|
110
112
|
component: item.component,
|
|
111
113
|
children: []
|
|
112
114
|
};
|
|
@@ -13,7 +13,7 @@ const presetStyle = {
|
|
|
13
13
|
const meta = {
|
|
14
14
|
category: "forms",
|
|
15
15
|
type: "container",
|
|
16
|
-
label: "Checkbox
|
|
16
|
+
label: "Checkbox",
|
|
17
17
|
Icon: CheckboxCheckedIcon,
|
|
18
18
|
states: defaultStates,
|
|
19
19
|
presetStyle,
|
|
@@ -22,6 +22,7 @@ const meta = {
|
|
|
22
22
|
{
|
|
23
23
|
type: "instance",
|
|
24
24
|
component: "TextBlock",
|
|
25
|
+
label: "Checkbox Label",
|
|
25
26
|
props: [],
|
|
26
27
|
children: [{ type: "text", value: "Checkbox" }]
|
|
27
28
|
}
|
|
@@ -13,7 +13,7 @@ const presetStyle = {
|
|
|
13
13
|
const meta = {
|
|
14
14
|
category: "forms",
|
|
15
15
|
type: "container",
|
|
16
|
-
label: "Radio
|
|
16
|
+
label: "Radio",
|
|
17
17
|
Icon: RadioCheckedIcon,
|
|
18
18
|
states: defaultStates,
|
|
19
19
|
presetStyle,
|
|
@@ -22,6 +22,7 @@ const meta = {
|
|
|
22
22
|
{
|
|
23
23
|
type: "instance",
|
|
24
24
|
component: "TextBlock",
|
|
25
|
+
label: "Radio Label",
|
|
25
26
|
props: [],
|
|
26
27
|
children: [{ type: "text", value: "Radio" }]
|
|
27
28
|
}
|
package/lib/css/normalize.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { borders
|
|
1
|
+
import { borders } from "./presets";
|
|
2
2
|
const boxSizing = {
|
|
3
3
|
property: "boxSizing",
|
|
4
4
|
value: { type: "keyword", value: "border-box" }
|
|
@@ -24,7 +24,7 @@ const h5 = baseStyle;
|
|
|
24
24
|
const h6 = baseStyle;
|
|
25
25
|
const i = baseStyle;
|
|
26
26
|
const img = baseStyle;
|
|
27
|
-
const a =
|
|
27
|
+
const a = baseStyle;
|
|
28
28
|
const li = baseStyle;
|
|
29
29
|
const ul = baseStyle;
|
|
30
30
|
const ol = baseStyle;
|
package/lib/css/presets.js
CHANGED
|
@@ -16,24 +16,6 @@ const borders = [
|
|
|
16
16
|
value: { type: "unit", value: 1, unit: "px" }
|
|
17
17
|
}
|
|
18
18
|
];
|
|
19
|
-
const linkColors = [
|
|
20
|
-
{
|
|
21
|
-
property: "color",
|
|
22
|
-
value: { type: "rgb", r: 0, g: 0, b: 238, alpha: 1 }
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
state: ":active",
|
|
26
|
-
property: "color",
|
|
27
|
-
// chrome and safari use rgb(255, 0, 0)
|
|
28
|
-
value: { type: "rgb", r: 238, g: 0, b: 0, alpha: 1 }
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
state: ":visited",
|
|
32
|
-
property: "color",
|
|
33
|
-
value: { type: "rgb", r: 85, g: 26, b: 139, alpha: 1 }
|
|
34
|
-
}
|
|
35
|
-
];
|
|
36
19
|
export {
|
|
37
|
-
borders
|
|
38
|
-
linkColors
|
|
20
|
+
borders
|
|
39
21
|
};
|
package/lib/embed-template.js
CHANGED
|
@@ -36,6 +36,7 @@ const EmbedTemplateInstance = z.lazy(
|
|
|
36
36
|
() => z.object({
|
|
37
37
|
type: z.literal("instance"),
|
|
38
38
|
component: z.string(),
|
|
39
|
+
label: z.optional(z.string()),
|
|
39
40
|
props: z.optional(z.array(EmbedTemplateProp)),
|
|
40
41
|
styles: z.optional(z.array(EmbedTemplateStyleDecl)),
|
|
41
42
|
children: WsEmbedTemplate
|
|
@@ -81,6 +82,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, styleSource
|
|
|
81
82
|
const instance = {
|
|
82
83
|
type: "instance",
|
|
83
84
|
id: instanceId,
|
|
85
|
+
label: item.label,
|
|
84
86
|
component: item.component,
|
|
85
87
|
children: []
|
|
86
88
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
export declare const defaultTag = "form";
|
|
3
|
-
export declare const Form: import("react").ForwardRefExoticComponent<Omit<import("react").
|
|
3
|
+
export declare const Form: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "action" | "method"> & {
|
|
4
4
|
initialState?: "error" | "initial" | "success" | undefined;
|
|
5
5
|
}, "ref"> & import("react").RefAttributes<HTMLFormElement>>;
|
|
@@ -21,7 +21,7 @@ export declare const customComponents: {
|
|
|
21
21
|
target?: "_self" | "_blank" | "_parent" | "_top" | undefined;
|
|
22
22
|
prefetch?: "none" | "intent" | "render" | undefined;
|
|
23
23
|
}, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
|
|
24
|
-
Form: import("react").ForwardRefExoticComponent<Omit<import("react").
|
|
24
|
+
Form: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "action" | "method"> & {
|
|
25
25
|
initialState?: "error" | "initial" | "success" | undefined;
|
|
26
26
|
}, "ref"> & import("react").RefAttributes<HTMLFormElement>>;
|
|
27
27
|
};
|
|
@@ -1436,6 +1436,7 @@ export type EmbedTemplateStyleDecl = z.infer<typeof EmbedTemplateStyleDecl>;
|
|
|
1436
1436
|
export type EmbedTemplateInstance = {
|
|
1437
1437
|
type: "instance";
|
|
1438
1438
|
component: string;
|
|
1439
|
+
label?: string;
|
|
1439
1440
|
props?: EmbedTemplateProp[];
|
|
1440
1441
|
styles?: EmbedTemplateStyleDecl[];
|
|
1441
1442
|
children: Array<EmbedTemplateInstance | EmbedTemplateText>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/react-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.65.0",
|
|
4
4
|
"description": "Webstudio JavaScript / TypeScript API",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -35,16 +35,17 @@
|
|
|
35
35
|
"nanoevents": "^7.0.1",
|
|
36
36
|
"nanoid": "^3.2.0",
|
|
37
37
|
"nanostores": "^0.7.1",
|
|
38
|
-
"@webstudio-is/asset-uploader": "^0.
|
|
39
|
-
"@webstudio-is/css-data": "^0.
|
|
40
|
-
"@webstudio-is/css-engine": "^0.
|
|
41
|
-
"@webstudio-is/css-vars": "^0.
|
|
42
|
-
"@webstudio-is/fonts": "^0.
|
|
43
|
-
"@webstudio-is/generate-arg-types": "^0.
|
|
44
|
-
"@webstudio-is/icons": "^0.
|
|
45
|
-
"@webstudio-is/image": "^0.
|
|
46
|
-
"@webstudio-is/prisma-client": "^0.
|
|
47
|
-
"@webstudio-is/project-build": "^0.
|
|
38
|
+
"@webstudio-is/asset-uploader": "^0.65.0",
|
|
39
|
+
"@webstudio-is/css-data": "^0.65.0",
|
|
40
|
+
"@webstudio-is/css-engine": "^0.65.0",
|
|
41
|
+
"@webstudio-is/css-vars": "^0.65.0",
|
|
42
|
+
"@webstudio-is/fonts": "^0.65.0",
|
|
43
|
+
"@webstudio-is/generate-arg-types": "^0.65.0",
|
|
44
|
+
"@webstudio-is/icons": "^0.65.0",
|
|
45
|
+
"@webstudio-is/image": "^0.65.0",
|
|
46
|
+
"@webstudio-is/prisma-client": "^0.65.0",
|
|
47
|
+
"@webstudio-is/project-build": "^0.65.0",
|
|
48
|
+
"@webstudio-is/form-handlers": "^0.65.0"
|
|
48
49
|
},
|
|
49
50
|
"exports": {
|
|
50
51
|
".": {
|
|
@@ -5,10 +5,8 @@ export const props: Record<string, PropMeta> = {
|
|
|
5
5
|
style: { required: false, control: "text", type: "string" },
|
|
6
6
|
title: { required: false, control: "text", type: "string" },
|
|
7
7
|
acceptCharset: { required: false, control: "text", type: "string" },
|
|
8
|
-
action: { required: false, control: "text", type: "string" },
|
|
9
8
|
autoComplete: { required: false, control: "text", type: "string" },
|
|
10
9
|
encType: { required: false, control: "text", type: "string" },
|
|
11
|
-
method: { required: false, control: "text", type: "string" },
|
|
12
10
|
name: { required: false, control: "text", type: "string" },
|
|
13
11
|
noValidate: { required: false, control: "boolean", type: "boolean" },
|
|
14
12
|
target: { required: false, control: "text", type: "string" },
|
|
@@ -452,6 +450,7 @@ export const props: Record<string, PropMeta> = {
|
|
|
452
450
|
required: false,
|
|
453
451
|
control: "radio",
|
|
454
452
|
type: "string",
|
|
453
|
+
defaultValue: "initial",
|
|
455
454
|
options: ["initial", "success", "error"],
|
|
456
455
|
},
|
|
457
456
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useFetcher } from "@remix-run/react";
|
|
2
|
+
import { formIdFieldName } from "@webstudio-is/form-handlers";
|
|
1
3
|
import {
|
|
2
4
|
Children,
|
|
3
5
|
cloneElement,
|
|
@@ -6,6 +8,7 @@ import {
|
|
|
6
8
|
type ElementRef,
|
|
7
9
|
type ComponentProps,
|
|
8
10
|
} from "react";
|
|
11
|
+
import { getInstanceIdFromComponentProps } from "../../props";
|
|
9
12
|
|
|
10
13
|
export const defaultTag = "form";
|
|
11
14
|
|
|
@@ -78,17 +81,31 @@ const withoutMessages = (children: ReactNode) =>
|
|
|
78
81
|
|
|
79
82
|
export const Form = forwardRef<
|
|
80
83
|
ElementRef<typeof defaultTag>,
|
|
81
|
-
ComponentProps<typeof defaultTag> & {
|
|
84
|
+
Omit<ComponentProps<typeof defaultTag>, "method" | "action"> & {
|
|
82
85
|
initialState?: "initial" | "success" | "error";
|
|
83
86
|
}
|
|
84
|
-
>(({ children, initialState = "initial", ...props }, ref) =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
?
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
>(({ children, initialState = "initial", ...props }, ref) => {
|
|
88
|
+
const fetcher = useFetcher();
|
|
89
|
+
|
|
90
|
+
const state =
|
|
91
|
+
fetcher.type === "done"
|
|
92
|
+
? fetcher.data?.success === true
|
|
93
|
+
? "success"
|
|
94
|
+
: "error"
|
|
95
|
+
: initialState;
|
|
96
|
+
|
|
97
|
+
const instanceId = getInstanceIdFromComponentProps(props);
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<fetcher.Form {...props} method="post" data-state={state} ref={ref}>
|
|
101
|
+
<input type="hidden" name={formIdFieldName} value={instanceId} />
|
|
102
|
+
{state === "success"
|
|
103
|
+
? onlySuccessMessage(children)
|
|
104
|
+
: state === "error"
|
|
105
|
+
? onlyErrorMessage(children)
|
|
106
|
+
: withoutMessages(children)}
|
|
107
|
+
</fetcher.Form>
|
|
108
|
+
);
|
|
109
|
+
});
|
|
93
110
|
|
|
94
111
|
Form.displayName = "Form";
|
|
@@ -19,7 +19,7 @@ const presetStyle = {
|
|
|
19
19
|
export const meta: WsComponentMeta = {
|
|
20
20
|
category: "forms",
|
|
21
21
|
type: "container",
|
|
22
|
-
label: "Checkbox
|
|
22
|
+
label: "Checkbox",
|
|
23
23
|
Icon: CheckboxCheckedIcon,
|
|
24
24
|
states: defaultStates,
|
|
25
25
|
presetStyle,
|
|
@@ -28,6 +28,7 @@ export const meta: WsComponentMeta = {
|
|
|
28
28
|
{
|
|
29
29
|
type: "instance",
|
|
30
30
|
component: "TextBlock",
|
|
31
|
+
label: "Checkbox Label",
|
|
31
32
|
props: [],
|
|
32
33
|
children: [{ type: "text", value: "Checkbox" }],
|
|
33
34
|
},
|
|
@@ -19,7 +19,7 @@ const presetStyle = {
|
|
|
19
19
|
export const meta: WsComponentMeta = {
|
|
20
20
|
category: "forms",
|
|
21
21
|
type: "container",
|
|
22
|
-
label: "Radio
|
|
22
|
+
label: "Radio",
|
|
23
23
|
Icon: RadioCheckedIcon,
|
|
24
24
|
states: defaultStates,
|
|
25
25
|
presetStyle,
|
|
@@ -28,6 +28,7 @@ export const meta: WsComponentMeta = {
|
|
|
28
28
|
{
|
|
29
29
|
type: "instance",
|
|
30
30
|
component: "TextBlock",
|
|
31
|
+
label: "Radio Label",
|
|
31
32
|
props: [],
|
|
32
33
|
children: [{ type: "text", value: "Radio" }],
|
|
33
34
|
},
|
package/src/css/normalize.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
// webstudio custom opinionated presets
|
|
19
|
-
import { borders
|
|
19
|
+
import { borders } from "./presets";
|
|
20
20
|
import type { EmbedTemplateStyleDecl } from "../embed-template";
|
|
21
21
|
|
|
22
22
|
export type Styles = EmbedTemplateStyleDecl[];
|
|
@@ -63,7 +63,7 @@ export const i = baseStyle;
|
|
|
63
63
|
|
|
64
64
|
export const img = baseStyle;
|
|
65
65
|
|
|
66
|
-
export const a =
|
|
66
|
+
export const a = baseStyle;
|
|
67
67
|
export const li = baseStyle;
|
|
68
68
|
export const ul = baseStyle;
|
|
69
69
|
export const ol = baseStyle;
|
package/src/css/presets.ts
CHANGED
|
@@ -18,21 +18,3 @@ export const borders: Styles = [
|
|
|
18
18
|
value: { type: "unit", value: 1, unit: "px" },
|
|
19
19
|
},
|
|
20
20
|
];
|
|
21
|
-
|
|
22
|
-
export const linkColors: Styles = [
|
|
23
|
-
{
|
|
24
|
-
property: "color",
|
|
25
|
-
value: { type: "rgb", r: 0, g: 0, b: 238, alpha: 1 },
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
state: ":active",
|
|
29
|
-
property: "color",
|
|
30
|
-
// chrome and safari use rgb(255, 0, 0)
|
|
31
|
-
value: { type: "rgb", r: 238, g: 0, b: 0, alpha: 1 },
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
state: ":visited",
|
|
35
|
-
property: "color",
|
|
36
|
-
value: { type: "rgb", r: 85, g: 26, b: 139, alpha: 1 },
|
|
37
|
-
},
|
|
38
|
-
];
|
package/src/embed-template.ts
CHANGED
|
@@ -54,6 +54,7 @@ export type EmbedTemplateStyleDecl = z.infer<typeof EmbedTemplateStyleDecl>;
|
|
|
54
54
|
export type EmbedTemplateInstance = {
|
|
55
55
|
type: "instance";
|
|
56
56
|
component: string;
|
|
57
|
+
label?: string;
|
|
57
58
|
props?: EmbedTemplateProp[];
|
|
58
59
|
styles?: EmbedTemplateStyleDecl[];
|
|
59
60
|
children: Array<EmbedTemplateInstance | EmbedTemplateText>;
|
|
@@ -64,6 +65,7 @@ export const EmbedTemplateInstance: z.ZodType<EmbedTemplateInstance> = z.lazy(
|
|
|
64
65
|
z.object({
|
|
65
66
|
type: z.literal("instance"),
|
|
66
67
|
component: z.string(),
|
|
68
|
+
label: z.optional(z.string()),
|
|
67
69
|
props: z.optional(z.array(EmbedTemplateProp)),
|
|
68
70
|
styles: z.optional(z.array(EmbedTemplateStyleDecl)),
|
|
69
71
|
children: WsEmbedTemplate,
|
|
@@ -127,6 +129,7 @@ const createInstancesFromTemplate = (
|
|
|
127
129
|
const instance: Instance = {
|
|
128
130
|
type: "instance",
|
|
129
131
|
id: instanceId,
|
|
132
|
+
label: item.label,
|
|
130
133
|
component: item.component,
|
|
131
134
|
children: [],
|
|
132
135
|
};
|