@plastic-js/tsumiki 0.1.27 → 0.1.28

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.
@@ -1,11 +1,9 @@
1
1
  import { insert, jsx, mergeProps, setProp, template } from "@plastic-js/plastic/jsx-runtime";
2
2
  import { css } from "@emotion/css";
3
- import { mergeProps as mergeProps$1, splitProps } from "@plastic-js/plastic";
3
+ import { Field } from "@plastic-js/ark";
4
+ import { mergeProps as mergeProps$2, splitProps } from "@plastic-js/plastic";
4
5
  //#region src/components/Field.jsx
5
- var _tmpl4 = template("<p></p>");
6
- var _tmpl3 = template("<div></div>");
7
- var _tmpl2 = template("<span>*</span>");
8
- var _tmpl = template("<span><!><!></span>");
6
+ var _tmpl = template("<div></div>");
9
7
  var rootClass = css({
10
8
  display: "flex",
11
9
  flexDirection: "column",
@@ -51,8 +49,8 @@ var helperTextClass = css({
51
49
  flexBasis: "100%"
52
50
  });
53
51
  var read = (v) => typeof v === "function" ? v() : v;
54
- var Field = (props = {}) => {
55
- const [local, rest] = splitProps(mergeProps$1({
52
+ var Field$1 = (props = {}) => {
53
+ const [local, rest] = splitProps(mergeProps$2({
56
54
  label: "",
57
55
  error: "",
58
56
  helper: "",
@@ -64,6 +62,9 @@ var Field = (props = {}) => {
64
62
  "helper",
65
63
  "required",
66
64
  "compact",
65
+ "invalid",
66
+ "disabled",
67
+ "readOnly",
67
68
  "className",
68
69
  "children"
69
70
  ]);
@@ -72,52 +73,61 @@ var Field = (props = {}) => {
72
73
  const hasError = () => !!error();
73
74
  const hasHelper = () => !!helper();
74
75
  const isCompact = () => read(local.compact);
75
- return jsx("div", mergeProps(rest, {
76
- className: () => [isCompact() ? compactRootClass : rootClass, local.className].filter(Boolean).join(" "),
77
- get "data-invalid"() {
78
- return hasError() ? "" : void 0;
76
+ const required = () => read(local.required);
77
+ const invalid = () => {
78
+ if (hasError()) return true;
79
+ return local.invalid === void 0 ? void 0 : read(local.invalid);
80
+ };
81
+ const disabled = () => local.disabled === void 0 ? void 0 : read(local.disabled);
82
+ const readOnly = () => local.readOnly === void 0 ? void 0 : read(local.readOnly);
83
+ return jsx(Field.Root, mergeProps(rest, {
84
+ get invalid() {
85
+ return invalid();
86
+ },
87
+ get disabled() {
88
+ return disabled();
89
+ },
90
+ get readOnly() {
91
+ return readOnly();
79
92
  },
93
+ get required() {
94
+ return required();
95
+ },
96
+ className: () => [isCompact() ? compactRootClass : rootClass, local.className].filter(Boolean).join(" "),
80
97
  children: [
81
- () => {
82
- const label = read(local.label);
83
- if (!label) return null;
84
- return () => {
85
- const _el0 = _tmpl.cloneNode(true);
86
- const _el1 = _el0.firstChild;
87
- const _el2 = _el0.firstChild.nextSibling;
88
- insert(_el0, () => label, _el1);
89
- insert(_el0, () => read(local.required) && (() => {
90
- const _el0 = _tmpl2.cloneNode(true);
91
- setProp(_el0, "className", () => requiredClass);
92
- return _el0;
93
- })(), _el2);
94
- setProp(_el0, "className", () => [labelClass, isCompact() && compactLabelClass].filter(Boolean).join(" "));
95
- return _el0;
96
- };
97
- },
98
+ () => read(local.label) ? jsx(Field.Label, mergeProps({
99
+ className: () => [labelClass, isCompact() && compactLabelClass].filter(Boolean).join(" "),
100
+ children: [() => read(local.label), () => required() && jsx(Field.RequiredIndicator, mergeProps({
101
+ className: requiredClass,
102
+ children: "*"
103
+ }))]
104
+ })) : null,
98
105
  () => isCompact() ? () => {
99
- const _el0 = _tmpl3.cloneNode(true);
106
+ const _el0 = _tmpl.cloneNode(true);
100
107
  insert(_el0, () => local.children);
101
108
  setProp(_el0, "className", () => inputWrapClass);
102
109
  return _el0;
103
110
  } : local.children,
104
- () => {
105
- if (hasError()) return () => {
106
- const _el0 = _tmpl4.cloneNode(true);
107
- insert(_el0, () => error());
108
- setProp(_el0, "className", () => errorTextClass);
109
- return _el0;
110
- };
111
- if (hasHelper()) return () => {
112
- const _el0 = _tmpl4.cloneNode(true);
113
- insert(_el0, () => helper());
114
- setProp(_el0, "className", () => helperTextClass);
115
- return _el0;
116
- };
117
- return null;
118
- }
111
+ () => hasError() ? jsx(Field.ErrorText, mergeProps({
112
+ className: errorTextClass,
113
+ children: () => error()
114
+ })) : hasHelper() ? jsx(Field.HelperText, mergeProps({
115
+ className: helperTextClass,
116
+ children: () => helper()
117
+ })) : null
119
118
  ]
120
119
  }));
121
120
  };
121
+ Field$1.origin = {
122
+ Root: Field.Root,
123
+ Label: Field.Label,
124
+ Input: Field.Input,
125
+ Textarea: Field.Textarea,
126
+ Select: Field.Select,
127
+ HelperText: Field.HelperText,
128
+ ErrorText: Field.ErrorText,
129
+ RequiredIndicator: Field.RequiredIndicator,
130
+ Item: Field.Item
131
+ };
122
132
  //#endregion
123
- export { Field as default };
133
+ export { Field$1 as default };
@@ -1,9 +1,8 @@
1
- import { insert, jsx, mergeProps, setProp, template } from "@plastic-js/plastic/jsx-runtime";
1
+ import { jsx, mergeProps } from "@plastic-js/plastic/jsx-runtime";
2
2
  import { css } from "@emotion/css";
3
- import { mergeProps as mergeProps$1, splitProps } from "@plastic-js/plastic";
3
+ import { Fieldset } from "@plastic-js/ark";
4
+ import { mergeProps as mergeProps$2, splitProps } from "@plastic-js/plastic";
4
5
  //#region src/components/Fieldset.jsx
5
- var _tmpl2 = template("<p></p>");
6
- var _tmpl = template("<div></div>");
7
6
  var rootClass = css({
8
7
  display: "flex",
9
8
  flexDirection: "column",
@@ -25,8 +24,8 @@ var helperClass = css({
25
24
  margin: 0
26
25
  });
27
26
  var read = (v) => typeof v === "function" ? v() : v;
28
- var Fieldset = (props = {}) => {
29
- const [local, rest] = splitProps(mergeProps$1({
27
+ var Fieldset$1 = (props = {}) => {
28
+ const [local, rest] = splitProps(mergeProps$2({
30
29
  legend: "",
31
30
  helper: ""
32
31
  }, props), [
@@ -35,32 +34,26 @@ var Fieldset = (props = {}) => {
35
34
  "className",
36
35
  "children"
37
36
  ]);
38
- return jsx("div", mergeProps(rest, {
37
+ return jsx(Fieldset.Root, mergeProps(rest, {
39
38
  className: () => [rootClass, local.className].filter(Boolean).join(" "),
40
39
  children: [
41
- () => {
42
- const legend = read(local.legend);
43
- if (!legend) return null;
44
- return () => {
45
- const _el0 = _tmpl.cloneNode(true);
46
- insert(_el0, () => legend);
47
- setProp(_el0, "className", () => legendClass);
48
- return _el0;
49
- };
50
- },
40
+ () => read(local.legend) ? jsx(Fieldset.Legend, mergeProps({
41
+ className: legendClass,
42
+ children: () => read(local.legend)
43
+ })) : null,
51
44
  () => local.children,
52
- () => {
53
- const helper = read(local.helper);
54
- if (!helper) return null;
55
- return () => {
56
- const _el0 = _tmpl2.cloneNode(true);
57
- insert(_el0, () => helper);
58
- setProp(_el0, "className", () => helperClass);
59
- return _el0;
60
- };
61
- }
45
+ () => read(local.helper) ? jsx(Fieldset.HelperText, mergeProps({
46
+ className: helperClass,
47
+ children: () => read(local.helper)
48
+ })) : null
62
49
  ]
63
50
  }));
64
51
  };
52
+ Fieldset$1.origin = {
53
+ Root: Fieldset.Root,
54
+ Legend: Fieldset.Legend,
55
+ HelperText: Fieldset.HelperText,
56
+ ErrorText: Fieldset.ErrorText
57
+ };
65
58
  //#endregion
66
- export { Fieldset as default };
59
+ export { Fieldset$1 as default };
@@ -1,7 +1,8 @@
1
1
  import { insert, jsx, mergeProps, setProp, template } from "@plastic-js/plastic/jsx-runtime";
2
2
  import { css } from "@emotion/css";
3
- import { createSignal, mergeProps as mergeProps$1, splitProps } from "@plastic-js/plastic";
4
- import { ark } from "@plastic-js/ark/factory";
3
+ import { useFieldContext } from "@plastic-js/ark";
4
+ import { createSignal, mergeProps as mergeProps$2, splitProps } from "@plastic-js/plastic";
5
+ import { ark as ark$1 } from "@plastic-js/ark/factory";
5
6
  //#region src/components/Input.jsx
6
7
  var _tmpl5 = template("<svg fill=\"none\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" viewBox=\"0 0 24 24\"><path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle></svg>");
7
8
  var _tmpl4 = template("<svg fill=\"none\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" viewBox=\"0 0 24 24\"><path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"></path><path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line></svg>");
@@ -128,7 +129,7 @@ var eyeButtonClass = css({
128
129
  });
129
130
  var read = (v) => typeof v === "function" ? v() : v;
130
131
  var Input = (props = {}) => {
131
- const [local, rest] = splitProps(mergeProps$1({
132
+ const [local, rest] = splitProps(mergeProps$2({
132
133
  solid: false,
133
134
  size: "md",
134
135
  disabled: false,
@@ -147,12 +148,17 @@ var Input = (props = {}) => {
147
148
  ]);
148
149
  const showPassword = createSignal(false);
149
150
  const isPassword = read(local.type) === "password";
151
+ const field = useFieldContext();
152
+ const fieldInvalid = () => field?.invalid?.() ?? false;
153
+ const fieldDisabled = () => field?.disabled?.() ?? false;
154
+ const effectiveInvalid = () => read(local.invalid) || fieldInvalid();
155
+ const effectiveDisabled = () => read(local.disabled) || fieldDisabled();
150
156
  const wrapperClassName = () => [
151
157
  wrapperClass,
152
158
  sizeClasses[read(local.size)],
153
159
  read(local.solid) ? variantClasses.solid : variantClasses.outline,
154
- read(local.invalid) && errorClass,
155
- read(local.disabled) && disabledClass,
160
+ effectiveInvalid() && errorClass,
161
+ effectiveDisabled() && disabledClass,
156
162
  read(local.className)
157
163
  ].filter(Boolean).join(" ");
158
164
  const inputType = () => {
@@ -178,11 +184,13 @@ var Input = (props = {}) => {
178
184
  if (p == null) return null;
179
185
  return renderAffix(p);
180
186
  }, _el1);
181
- insert(_el0, () => jsx(ark.input, mergeProps({ get ref() {
187
+ insert(_el0, () => jsx(ark$1.input, mergeProps({ get ref() {
182
188
  return local.ref;
183
- } }, rest, {
189
+ } }, () => field ? field.getInputProps() : {}, rest, {
184
190
  type: inputType,
185
- disabled: () => read(local.disabled),
191
+ "aria-invalid": () => effectiveInvalid() ? "true" : "false",
192
+ "data-invalid": () => effectiveInvalid() ? "" : void 0,
193
+ disabled: () => effectiveDisabled(),
186
194
  className: () => [inputClass, read(local.inputClassName)].filter(Boolean).join(" ")
187
195
  })), _el2);
188
196
  insert(_el0, () => {
@@ -206,6 +214,6 @@ var Input = (props = {}) => {
206
214
  return _el0;
207
215
  };
208
216
  };
209
- Input.origin = { Root: ark.input };
217
+ Input.origin = { Root: ark$1.input };
210
218
  //#endregion
211
219
  export { Input as default };
package/docs/api.md CHANGED
@@ -52,9 +52,9 @@ The shared `size` prop accepts: `xs | sm | md | lg | xl | xxl` (default `md`).
52
52
 
53
53
  ### Field
54
54
 
55
- A labeled field wrapper combining a label, an error message and helper text.
55
+ A labeled field wrapper combining a label, an error message and helper text, backed by `ArkField`.
56
56
 
57
- **Exports:** `Field`
57
+ **Exports:** `Field` · Escape hatch: `Field.origin.{Root, Label, Input, Textarea, Select, HelperText, ErrorText, RequiredIndicator, Item}`
58
58
 
59
59
  | Prop | Type | Default | Description |
60
60
  |---|---|---|---|
@@ -63,13 +63,18 @@ A labeled field wrapper combining a label, an error message and helper text.
63
63
  | `helper` | `string` | `''` | Helper text below the control. |
64
64
  | `required` | `boolean` | `false` | Marks the label with a required indicator. |
65
65
  | `compact` | `boolean` | `false` | Renders in a compact (smaller) layout. |
66
+ | `invalid` | `boolean` | `false` | Error state (also implied by a non-empty `error`). |
67
+ | `disabled` | `boolean` | — | Disables the control; inherits from an enclosing `Fieldset`. |
68
+ | `readOnly` | `boolean` | — | Read-only state. |
66
69
  | `children` | `node` | — | The input control (e.g. `<Input />`). |
67
70
 
71
+ Passthrough: Ark `Field.Root` props (`id`, `ids`, …).
72
+
68
73
  ### Fieldset
69
74
 
70
- Groups several `Field`s with a legend.
75
+ Groups several `Field`s with a legend, backed by `ArkFieldset` (native `<fieldset>`).
71
76
 
72
- **Exports:** `Fieldset`
77
+ **Exports:** `Fieldset` · Escape hatch: `Fieldset.origin.{Root, Legend, HelperText, ErrorText}`
73
78
 
74
79
  | Prop | Type | Default | Description |
75
80
  |---|---|---|---|
@@ -77,6 +82,8 @@ Groups several `Field`s with a legend.
77
82
  | `helper` | `string` | `''` | Helper text below the fields. |
78
83
  | `children` | `node` | — | `Field` components to group. |
79
84
 
85
+ Passthrough: Ark `Fieldset.Root` props (`disabled`, `invalid`, …).
86
+
80
87
  ### Input
81
88
 
82
89
  **Exports:** `Input` · Escape hatch: `Input.origin.Root`
@@ -28,7 +28,7 @@ Whether the component is built on top of a same-named Ark primitive, or implemen
28
28
 
29
29
  ### Component Matrix
30
30
 
31
- #### Completed · Ark-Backed (30)
31
+ #### Completed · Ark-Backed (32)
32
32
 
33
33
  | Component | Ark Primitive |
34
34
  |-----------|---------------|
@@ -39,6 +39,8 @@ Whether the component is built on top of a same-named Ark primitive, or implemen
39
39
  | ColorPicker | `ArkColorPicker` |
40
40
  | Dialog | `ArkDialog` |
41
41
  | Drawer | `ArkDrawer` |
42
+ | Field | `ArkField` |
43
+ | Fieldset | `ArkFieldset` |
42
44
  | FileUpload | `ArkFileUpload` |
43
45
  | FocusTrap | `ArkFocusTrap` |
44
46
  | Input | `ark("input")` via factory |
@@ -63,7 +65,7 @@ Whether the component is built on top of a same-named Ark primitive, or implemen
63
65
  | Toggle | `ArkToggle` |
64
66
  | ToggleGroup | `ArkToggleGroup` |
65
67
 
66
- #### Completed · Custom-Built (15)
68
+ #### Completed · Custom-Built (13)
67
69
 
68
70
  | Component | Built With |
69
71
  |-----------|------------|
@@ -73,8 +75,6 @@ Whether the component is built on top of a same-named Ark primitive, or implemen
73
75
  | CloseButton | `@emotion/css` |
74
76
  | ConfirmDialog | Composes `Dialog` |
75
77
  | DateInput | `DateWheel` utility |
76
- | Field | `@emotion/css` |
77
- | Fieldset | `@emotion/css` |
78
78
  | Icon | `@emotion/css` |
79
79
  | MoneyInput | Composes `Input` |
80
80
  | SearchInput | Composes `Input` |
@@ -103,11 +103,11 @@ Whether the component is built on top of a same-named Ark primitive, or implemen
103
103
  ```
104
104
  Ark-Backed Custom-Built
105
105
  ┌─────────────────┬─────────────────┐
106
- Completed │ 3015 │ 45
106
+ Completed │ 3213 │ 45
107
107
  ├─────────────────┼─────────────────┤
108
108
  In Development │ 6 │ 0 │ 6
109
109
  └─────────────────┴─────────────────┘
110
- 36 15 51
110
+ 38 13 51
111
111
  ```
112
112
 
113
113
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plastic-js/tsumiki",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "A UI component library for Plastic JS.",
5
5
  "license": "MIT",
6
6
  "author": "tigre",