@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.
Files changed (44) hide show
  1. package/lib/app/custom-components/__generated__/form.props.js +1 -2
  2. package/lib/app/custom-components/form.js +13 -2
  3. package/lib/app/custom-components/form.ws.js +1 -1
  4. package/lib/cjs/app/custom-components/__generated__/form.props.js +1 -2
  5. package/lib/cjs/app/custom-components/form.js +19 -8
  6. package/lib/cjs/app/custom-components/form.ws.js +1 -1
  7. package/lib/cjs/components/button.ws.js +1 -1
  8. package/lib/cjs/components/checkbox-field.ws.js +2 -1
  9. package/lib/cjs/components/checkbox.ws.js +1 -1
  10. package/lib/cjs/components/form.ws.js +1 -1
  11. package/lib/cjs/components/input.ws.js +1 -1
  12. package/lib/cjs/components/radio-button-field.ws.js +2 -1
  13. package/lib/cjs/components/radio-button.ws.js +1 -1
  14. package/lib/cjs/css/normalize.js +1 -1
  15. package/lib/cjs/css/presets.js +1 -19
  16. package/lib/cjs/embed-template.js +2 -0
  17. package/lib/components/button.ws.js +1 -1
  18. package/lib/components/checkbox-field.ws.js +2 -1
  19. package/lib/components/checkbox.ws.js +1 -1
  20. package/lib/components/form.ws.js +1 -1
  21. package/lib/components/input.ws.js +1 -1
  22. package/lib/components/radio-button-field.ws.js +2 -1
  23. package/lib/components/radio-button.ws.js +1 -1
  24. package/lib/css/normalize.js +2 -2
  25. package/lib/css/presets.js +1 -19
  26. package/lib/embed-template.js +2 -0
  27. package/lib/types/app/custom-components/form.d.ts +1 -1
  28. package/lib/types/app/custom-components/index.d.ts +1 -1
  29. package/lib/types/css/presets.d.ts +0 -1
  30. package/lib/types/embed-template.d.ts +1 -0
  31. package/package.json +12 -11
  32. package/src/app/custom-components/__generated__/form.props.ts +1 -2
  33. package/src/app/custom-components/form.tsx +27 -10
  34. package/src/app/custom-components/form.ws.tsx +1 -1
  35. package/src/components/button.ws.tsx +1 -1
  36. package/src/components/checkbox-field.ws.tsx +2 -1
  37. package/src/components/checkbox.ws.tsx +1 -1
  38. package/src/components/form.ws.tsx +1 -1
  39. package/src/components/input.ws.tsx +1 -1
  40. package/src/components/radio-button-field.ws.tsx +2 -1
  41. package/src/components/radio-button.ws.tsx +1 -1
  42. package/src/css/normalize.ts +2 -2
  43. package/src/css/presets.ts +0 -18
  44. 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) => /* @__PURE__ */ jsx("form", { ...props, "data-state": initialState, ref, children: initialState === "success" ? onlySuccessMessage(children) : initialState === "error" ? onlyErrorMessage(children) : withoutMessages(children) }));
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,
@@ -37,7 +37,7 @@ const meta = {
37
37
  {
38
38
  type: "instance",
39
39
  component: "Input",
40
- props: [{ type: "string", name: "email", value: "email" }],
40
+ props: [{ type: "string", name: "name", value: "email" }],
41
41
  children: []
42
42
  },
43
43
  {
@@ -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) => import_react.Children.map(children, (child) => {
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 import_react.Children.toArray(newChildren).some((child2) => child2 !== null) ? (0, import_react.cloneElement)(child, { children: newChildren }) : null;
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) => import_react.Children.map(children, (child) => {
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 import_react.Children.toArray(newChildren).some((child2) => child2 !== null) ? (0, import_react.cloneElement)(child, { children: newChildren }) : null;
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) => import_react.Children.map(children, (child) => {
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, import_react.cloneElement)(child, {
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, import_react.forwardRef)(({ children, initialState = "initial", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("form", { ...props, "data-state": initialState, ref, children: initialState === "success" ? onlySuccessMessage(children) : initialState === "error" ? onlyErrorMessage(children) : withoutMessages(children) }));
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";
@@ -61,7 +61,7 @@ const meta = {
61
61
  {
62
62
  type: "instance",
63
63
  component: "Input",
64
- props: [{ type: "string", name: "email", value: "email" }],
64
+ props: [{ type: "string", name: "name", value: "email" }],
65
65
  children: []
66
66
  },
67
67
  {
@@ -30,7 +30,7 @@ const presetStyle = {
30
30
  button: import_normalize.button
31
31
  };
32
32
  const meta = {
33
- category: "general",
33
+ category: "forms",
34
34
  type: "container",
35
35
  label: "Button",
36
36
  Icon: import_icons.ButtonElementIcon,
@@ -35,7 +35,7 @@ const presetStyle = {
35
35
  const meta = {
36
36
  category: "forms",
37
37
  type: "container",
38
- label: "Checkbox Field",
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
  }
@@ -37,7 +37,7 @@ const presetStyle = {
37
37
  };
38
38
  const meta = {
39
39
  type: "control",
40
- label: "Checkbox",
40
+ label: "Checkbox Input",
41
41
  Icon: import_icons.CheckboxCheckedIcon,
42
42
  presetStyle,
43
43
  states: [
@@ -59,7 +59,7 @@ const meta = {
59
59
  {
60
60
  type: "instance",
61
61
  component: "Input",
62
- props: [{ type: "string", name: "email", value: "email" }],
62
+ props: [{ type: "string", name: "name", value: "email" }],
63
63
  children: []
64
64
  },
65
65
  {
@@ -32,7 +32,7 @@ const presetStyle = {
32
32
  const meta = {
33
33
  category: "forms",
34
34
  type: "control",
35
- label: "Text Field",
35
+ label: "Text Input",
36
36
  Icon: import_icons.FormTextFieldIcon,
37
37
  presetStyle,
38
38
  states: [
@@ -35,7 +35,7 @@ const presetStyle = {
35
35
  const meta = {
36
36
  category: "forms",
37
37
  type: "container",
38
- label: "Radio Button Field",
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
  }
@@ -37,7 +37,7 @@ const presetStyle = {
37
37
  };
38
38
  const meta = {
39
39
  type: "control",
40
- label: "Radio Button",
40
+ label: "Radio Input",
41
41
  Icon: import_icons.RadioCheckedIcon,
42
42
  presetStyle,
43
43
  states: [
@@ -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 = [boxSizing, ...import_presets.borders, ...import_presets.linkColors];
96
+ const a = baseStyle;
97
97
  const li = baseStyle;
98
98
  const ul = baseStyle;
99
99
  const ol = baseStyle;
@@ -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
  };
@@ -8,7 +8,7 @@ const presetStyle = {
8
8
  button
9
9
  };
10
10
  const meta = {
11
- category: "general",
11
+ category: "forms",
12
12
  type: "container",
13
13
  label: "Button",
14
14
  Icon: ButtonElementIcon,
@@ -13,7 +13,7 @@ const presetStyle = {
13
13
  const meta = {
14
14
  category: "forms",
15
15
  type: "container",
16
- label: "Checkbox Field",
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
  }
@@ -15,7 +15,7 @@ const presetStyle = {
15
15
  };
16
16
  const meta = {
17
17
  type: "control",
18
- label: "Checkbox",
18
+ label: "Checkbox Input",
19
19
  Icon: CheckboxCheckedIcon,
20
20
  presetStyle,
21
21
  states: [
@@ -37,7 +37,7 @@ const meta = {
37
37
  {
38
38
  type: "instance",
39
39
  component: "Input",
40
- props: [{ type: "string", name: "email", value: "email" }],
40
+ props: [{ type: "string", name: "name", value: "email" }],
41
41
  children: []
42
42
  },
43
43
  {
@@ -10,7 +10,7 @@ const presetStyle = {
10
10
  const meta = {
11
11
  category: "forms",
12
12
  type: "control",
13
- label: "Text Field",
13
+ label: "Text Input",
14
14
  Icon: FormTextFieldIcon,
15
15
  presetStyle,
16
16
  states: [
@@ -13,7 +13,7 @@ const presetStyle = {
13
13
  const meta = {
14
14
  category: "forms",
15
15
  type: "container",
16
- label: "Radio Button Field",
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
  }
@@ -15,7 +15,7 @@ const presetStyle = {
15
15
  };
16
16
  const meta = {
17
17
  type: "control",
18
- label: "Radio Button",
18
+ label: "Radio Input",
19
19
  Icon: RadioCheckedIcon,
20
20
  presetStyle,
21
21
  states: [
@@ -1,4 +1,4 @@
1
- import { borders, linkColors } from "./presets";
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 = [boxSizing, ...borders, ...linkColors];
27
+ const a = baseStyle;
28
28
  const li = baseStyle;
29
29
  const ul = baseStyle;
30
30
  const ol = baseStyle;
@@ -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
  };
@@ -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").ClassAttributes<HTMLFormElement> & import("react").FormHTMLAttributes<HTMLFormElement> & {
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").ClassAttributes<HTMLFormElement> & import("react").FormHTMLAttributes<HTMLFormElement> & {
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
  };
@@ -1,3 +1,2 @@
1
1
  import type { Styles } from "./normalize";
2
2
  export declare const borders: Styles;
3
- export declare const linkColors: Styles;
@@ -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.63.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.63.0",
39
- "@webstudio-is/css-data": "^0.63.0",
40
- "@webstudio-is/css-engine": "^0.63.0",
41
- "@webstudio-is/css-vars": "^0.63.0",
42
- "@webstudio-is/fonts": "^0.63.0",
43
- "@webstudio-is/generate-arg-types": "^0.63.0",
44
- "@webstudio-is/icons": "^0.63.0",
45
- "@webstudio-is/image": "^0.63.0",
46
- "@webstudio-is/prisma-client": "^0.63.0",
47
- "@webstudio-is/project-build": "^0.63.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
- <form {...props} data-state={initialState} ref={ref}>
86
- {initialState === "success"
87
- ? onlySuccessMessage(children)
88
- : initialState === "error"
89
- ? onlyErrorMessage(children)
90
- : withoutMessages(children)}
91
- </form>
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";
@@ -45,7 +45,7 @@ export const meta: WsComponentMeta = {
45
45
  {
46
46
  type: "instance",
47
47
  component: "Input",
48
- props: [{ type: "string", name: "email", value: "email" }],
48
+ props: [{ type: "string", name: "name", value: "email" }],
49
49
  children: [],
50
50
  },
51
51
  {
@@ -14,7 +14,7 @@ const presetStyle = {
14
14
  } satisfies PresetStyle<typeof defaultTag>;
15
15
 
16
16
  export const meta: WsComponentMeta = {
17
- category: "general",
17
+ category: "forms",
18
18
  type: "container",
19
19
  label: "Button",
20
20
  Icon: ButtonElementIcon,
@@ -19,7 +19,7 @@ const presetStyle = {
19
19
  export const meta: WsComponentMeta = {
20
20
  category: "forms",
21
21
  type: "container",
22
- label: "Checkbox Field",
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
  },
@@ -21,7 +21,7 @@ const presetStyle = {
21
21
 
22
22
  export const meta: WsComponentMeta = {
23
23
  type: "control",
24
- label: "Checkbox",
24
+ label: "Checkbox Input",
25
25
  Icon: CheckboxCheckedIcon,
26
26
  presetStyle,
27
27
  states: [
@@ -43,7 +43,7 @@ export const meta: WsComponentMeta = {
43
43
  {
44
44
  type: "instance",
45
45
  component: "Input",
46
- props: [{ type: "string", name: "email", value: "email" }],
46
+ props: [{ type: "string", name: "name", value: "email" }],
47
47
  children: [],
48
48
  },
49
49
  {
@@ -16,7 +16,7 @@ const presetStyle = {
16
16
  export const meta: WsComponentMeta = {
17
17
  category: "forms",
18
18
  type: "control",
19
- label: "Text Field",
19
+ label: "Text Input",
20
20
  Icon: FormTextFieldIcon,
21
21
  presetStyle,
22
22
  states: [
@@ -19,7 +19,7 @@ const presetStyle = {
19
19
  export const meta: WsComponentMeta = {
20
20
  category: "forms",
21
21
  type: "container",
22
- label: "Radio Button Field",
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
  },
@@ -21,7 +21,7 @@ const presetStyle = {
21
21
 
22
22
  export const meta: WsComponentMeta = {
23
23
  type: "control",
24
- label: "Radio Button",
24
+ label: "Radio Input",
25
25
  Icon: RadioCheckedIcon,
26
26
  presetStyle,
27
27
  states: [
@@ -16,7 +16,7 @@
16
16
  */
17
17
 
18
18
  // webstudio custom opinionated presets
19
- import { borders, linkColors } from "./presets";
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 = [boxSizing, ...borders, ...linkColors];
66
+ export const a = baseStyle;
67
67
  export const li = baseStyle;
68
68
  export const ul = baseStyle;
69
69
  export const ol = baseStyle;
@@ -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
- ];
@@ -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
  };