@igne-agency/react-web-ui 0.2.1 → 0.3.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/README.md +39 -0
- package/dist/components/checkbox-field/tsf-checkbox-field.js +1 -1
- package/dist/components/checkbox-group-field/checkbox-group.d.ts +1 -1
- package/dist/components/checkbox-group-field/checkbox-group.js +1 -1
- package/dist/components/checkbox-group-field/tsf-checkbox-group-field.js +1 -1
- package/dist/components/combobox-field/tsf-combobox-field.js +2 -2
- package/dist/components/date-field/tsf-date-field.js +1 -1
- package/dist/components/date-range-field/tsf-date-range-field.js +1 -1
- package/dist/components/field/field-group-context.d.ts +21 -0
- package/dist/components/field/field-group-context.js +38 -0
- package/dist/components/field/field.css +27 -8
- package/dist/components/field/field.d.ts +6 -3
- package/dist/components/field/field.js +88 -45
- package/dist/components/field/field.module.js +12 -10
- package/dist/components/fieldset/field-group.d.ts +31 -0
- package/dist/components/fieldset/field-group.js +102 -0
- package/dist/components/fieldset/fieldset-root.d.ts +60 -0
- package/dist/components/fieldset/fieldset-root.js +285 -0
- package/dist/components/fieldset/fieldset.css +21 -0
- package/dist/components/fieldset/fieldset.d.ts +37 -0
- package/dist/components/fieldset/fieldset.js +127 -0
- package/dist/components/fieldset/fieldset.module.js +8 -0
- package/dist/components/fieldset/index.d.ts +4 -0
- package/dist/components/fieldset/index.js +4 -0
- package/dist/components/fieldset/tsf-field-group.d.ts +21 -0
- package/dist/components/fieldset/tsf-field-group.js +58 -0
- package/dist/components/file-field/tsf-file-field.js +1 -1
- package/dist/components/number-field/tsf-number-field.js +1 -1
- package/dist/components/otp-field/tsf-otp-field.js +1 -1
- package/dist/components/password-field/tsf-password-field.js +1 -1
- package/dist/components/photo-field/tsf-photo-field.js +1 -1
- package/dist/components/radio-group-field/radio-group.d.ts +1 -1
- package/dist/components/radio-group-field/radio-group.js +1 -1
- package/dist/components/radio-group-field/tsf-radio-group-field.js +1 -1
- package/dist/components/segmented-control-field/segmented-control.d.ts +1 -1
- package/dist/components/segmented-control-field/segmented-control.js +1 -1
- package/dist/components/segmented-control-field/tsf-segmented-control-field.js +1 -1
- package/dist/components/select-field/tsf-select-field.js +1 -1
- package/dist/components/switch-field/tsf-switch-field.js +1 -1
- package/dist/components/text-field/connect-text-preset.js +1 -1
- package/dist/components/text-field/text-field.css +28 -27
- package/dist/components/text-field/text-field.module.js +9 -9
- package/dist/components/text-field/tsf-text-field.js +1 -1
- package/dist/components/textarea-field/tsf-textarea-field.js +1 -1
- package/dist/components/time-field/tsf-time-field.js +1 -1
- package/dist/components/toggle-group-field/toggle-group.d.ts +1 -1
- package/dist/components/toggle-group-field/toggle-group.js +1 -1
- package/dist/components/toggle-group-field/tsf-toggle-group-field.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -2
- package/dist/lib/forms/create-app-form.d.ts +18 -9
- package/dist/lib/forms/create-app-form.js +17 -8
- package/dist/lib/forms/index.d.ts +1 -0
- package/dist/lib/forms/index.js +2 -1
- package/dist/lib/forms/use-connected-field.d.ts +10 -7
- package/dist/lib/forms/use-connected-field.js +54 -28
- package/package.json +5 -1
- package/dist/components/field/fieldset.d.ts +0 -22
- package/dist/components/field/fieldset.js +0 -130
package/README.md
CHANGED
|
@@ -184,6 +184,45 @@ const SignUp = () => {
|
|
|
184
184
|
};
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
+
Related fields, such as the parts of an address, share one legend and one error in a field group, which lines them up side by side. Register `TSFFieldGroup` as a form component and name the fields whose errors it shows:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import { TSFFieldGroup } from "@igne-agency/react-web-ui/fieldset";
|
|
191
|
+
import { TSFTextField } from "@igne-agency/react-web-ui/text-field";
|
|
192
|
+
|
|
193
|
+
export const { useAppForm, withForm, withFieldGroup } =
|
|
194
|
+
createAppForm(
|
|
195
|
+
{ TextField: TSFTextField },
|
|
196
|
+
{ FieldGroup: TSFFieldGroup },
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<form.FieldGroup
|
|
202
|
+
legend="Address"
|
|
203
|
+
optionalLabel="optional"
|
|
204
|
+
names={["postalCode", "houseNumber"]}>
|
|
205
|
+
<form.AppField name="postalCode">
|
|
206
|
+
{field => (
|
|
207
|
+
<field.TextField
|
|
208
|
+
label="Postal code"
|
|
209
|
+
requiredness="required"
|
|
210
|
+
optionalLabel="optional"
|
|
211
|
+
/>
|
|
212
|
+
)}
|
|
213
|
+
</form.AppField>
|
|
214
|
+
<form.AppField name="houseNumber">
|
|
215
|
+
{field => (
|
|
216
|
+
<field.TextField
|
|
217
|
+
label="House number"
|
|
218
|
+
requiredness="required"
|
|
219
|
+
optionalLabel="optional"
|
|
220
|
+
/>
|
|
221
|
+
)}
|
|
222
|
+
</form.AppField>
|
|
223
|
+
</form.FieldGroup>
|
|
224
|
+
```
|
|
225
|
+
|
|
187
226
|
Every field takes `requiredness` (`"required"`, `"optional"`, or left out to show neither mark) and `errors`, which accepts strings and anything with a string `message`, such as Standard Schema issues. Validation is the app's own, through Standard Schema; the kit ships no validators.
|
|
188
227
|
|
|
189
228
|
`Form.Root` reports unsaved changes to the page's leave guards (`useLeaveGuard`, or `useRouterLeaveGuard` from `./unsaved-changes/tanstack-router`) while its `leaveGuard` policy returns true for the form's live state. The default, `whenDirty`, guards while the values differ from their defaults and no submit is in flight. Pass `never` for a form whose edits need not survive leaving, or any `(state) => boolean`:
|
|
@@ -14,7 +14,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
14
14
|
*/
|
|
15
15
|
var TSFCheckboxField = (props) => {
|
|
16
16
|
const $ = c(7);
|
|
17
|
-
const { field, props: connected } = useConnectedField();
|
|
17
|
+
const { field, props: connected } = useConnectedField(props.label);
|
|
18
18
|
let t0;
|
|
19
19
|
if ($[0] !== field) {
|
|
20
20
|
t0 = (checked) => field.handleChange(checked);
|
|
@@ -3,7 +3,7 @@ import { Field as BaseField } from "@base-ui/react/field";
|
|
|
3
3
|
import type { ReactNode } from "react";
|
|
4
4
|
import { Checkbox } from "../checkbox-field/index.ts";
|
|
5
5
|
import { Field } from "../field/index.ts";
|
|
6
|
-
import { FieldsetLegend, FieldsetRoot, type FieldsetRootProps } from "../
|
|
6
|
+
import { FieldsetLegend, FieldsetRoot, type FieldsetRootProps } from "../fieldset/fieldset-root.tsx";
|
|
7
7
|
export type CheckboxGroupRootProps = FieldsetRootProps;
|
|
8
8
|
declare const CheckboxGroupGroup: ({ className, ...props }: BaseCheckboxGroup.Props) => ReactNode;
|
|
9
9
|
declare const CheckboxGroupItem: ({ className, ...props }: BaseField.Item.Props) => ReactNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Checkbox } from "../checkbox-field/checkbox.js";
|
|
2
2
|
import { Field as Field$1 } from "../field/field.js";
|
|
3
|
-
import { FieldsetLegend, FieldsetRoot } from "../
|
|
3
|
+
import { FieldsetLegend, FieldsetRoot } from "../fieldset/fieldset-root.js";
|
|
4
4
|
import checkbox_group_module_default from "./checkbox-group.module.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -15,7 +15,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
15
15
|
*/
|
|
16
16
|
var TSFCheckboxGroupField = (props) => {
|
|
17
17
|
const $ = c(7);
|
|
18
|
-
const { field, props: connected } = useConnectedField();
|
|
18
|
+
const { field, props: connected } = useConnectedField(props.label);
|
|
19
19
|
let t0;
|
|
20
20
|
if ($[0] !== field) {
|
|
21
21
|
t0 = (value) => field.handleChange(value);
|
|
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
var SingleField = (t0) => {
|
|
7
7
|
const $ = c(7);
|
|
8
8
|
const { props } = t0;
|
|
9
|
-
const { field, props: connected } = useConnectedField();
|
|
9
|
+
const { field, props: connected } = useConnectedField(props.label);
|
|
10
10
|
let t1;
|
|
11
11
|
if ($[0] !== field) {
|
|
12
12
|
t1 = (next) => field.handleChange(next);
|
|
@@ -32,7 +32,7 @@ var SingleField = (t0) => {
|
|
|
32
32
|
var MultipleField = (t0) => {
|
|
33
33
|
const $ = c(7);
|
|
34
34
|
const { props } = t0;
|
|
35
|
-
const { field, props: connected } = useConnectedField();
|
|
35
|
+
const { field, props: connected } = useConnectedField(props.label);
|
|
36
36
|
let t1;
|
|
37
37
|
if ($[0] !== field) {
|
|
38
38
|
t1 = (next) => field.handleChange(next);
|
|
@@ -14,7 +14,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
14
14
|
*/
|
|
15
15
|
var TSFDateField = (props) => {
|
|
16
16
|
const $ = c(7);
|
|
17
|
-
const { field, props: connected } = useConnectedField();
|
|
17
|
+
const { field, props: connected } = useConnectedField(props.label);
|
|
18
18
|
let t0;
|
|
19
19
|
if ($[0] !== field) {
|
|
20
20
|
t0 = (next) => field.handleChange(next);
|
|
@@ -15,7 +15,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
15
15
|
*/
|
|
16
16
|
var TSFDateRangeField = (props) => {
|
|
17
17
|
const $ = c(12);
|
|
18
|
-
const { field, props: t0 } = useConnectedField();
|
|
18
|
+
const { field, props: t0 } = useConnectedField(props.label);
|
|
19
19
|
let connected;
|
|
20
20
|
let name;
|
|
21
21
|
if ($[0] !== t0) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Context } from "react";
|
|
2
|
+
/** What a field group tells the fields it collects the errors of. */
|
|
3
|
+
export type FieldGroupContextValue = Readonly<{
|
|
4
|
+
/** The ids of the lines a field's errors show as in the group's error, or `undefined` for a field the group does not collect. */
|
|
5
|
+
lineIds: (name: string) => readonly string[] | undefined;
|
|
6
|
+
/** Tells the group a field's label, until the returned function takes it back. */
|
|
7
|
+
registerLabel: (name: string, label: string) => () => void;
|
|
8
|
+
}>;
|
|
9
|
+
/** The field group the fields inside it report to. */
|
|
10
|
+
export declare const FieldGroupContext: Context<FieldGroupContextValue | null>;
|
|
11
|
+
/** Whether a field root sits directly in a field group's row of fields. */
|
|
12
|
+
export declare const FieldRowContext: Context<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* The ids of the lines the enclosing field group shows this field's errors as,
|
|
15
|
+
* or `undefined` when no group collects it. A field is matched by the name of
|
|
16
|
+
* the TanStack Form field it renders in.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const lineIds = useFieldGroupLineIds(); // ["«r3»line0"]
|
|
20
|
+
*/
|
|
21
|
+
export declare const useFieldGroupLineIds: () => readonly string[] | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fieldContext } from "../../lib/forms/context.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
// src/components/field/field-group-context.ts
|
|
5
|
+
/** The field group the fields inside it report to. */
|
|
6
|
+
var FieldGroupContext = createContext(null);
|
|
7
|
+
/** Whether a field root sits directly in a field group's row of fields. */
|
|
8
|
+
var FieldRowContext = createContext(false);
|
|
9
|
+
/**
|
|
10
|
+
* The ids of the lines `group` shows the errors of `field` as, where there are
|
|
11
|
+
* both.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* groupLineIds(group, field); // ["«r3»line0"]
|
|
15
|
+
*/
|
|
16
|
+
var groupLineIds = (group, field) => group === null || field === null ? void 0 : group.lineIds(field.name);
|
|
17
|
+
/**
|
|
18
|
+
* The ids of the lines the enclosing field group shows this field's errors as,
|
|
19
|
+
* or `undefined` when no group collects it. A field is matched by the name of
|
|
20
|
+
* the TanStack Form field it renders in.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const lineIds = useFieldGroupLineIds(); // ["«r3»line0"]
|
|
24
|
+
*/
|
|
25
|
+
var useFieldGroupLineIds = () => {
|
|
26
|
+
const $ = c(3);
|
|
27
|
+
const t0 = useContext(FieldGroupContext);
|
|
28
|
+
const t1 = useContext(fieldContext);
|
|
29
|
+
let t2;
|
|
30
|
+
if ($[0] !== t0 || $[1] !== t1) {
|
|
31
|
+
t2 = groupLineIds(t0, t1);
|
|
32
|
+
$[0] = t0;
|
|
33
|
+
$[1] = t1;
|
|
34
|
+
$[2] = t2;
|
|
35
|
+
} else t2 = $[2];
|
|
36
|
+
return t2;
|
|
37
|
+
};
|
|
38
|
+
export { FieldGroupContext, FieldRowContext, useFieldGroupLineIds };
|
|
@@ -1,29 +1,48 @@
|
|
|
1
1
|
@layer kit.reset, kit.base, kit.components;
|
|
2
2
|
@layer kit.components {
|
|
3
|
-
.
|
|
3
|
+
._field_dzutr_3 {
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
6
|
gap: var(--field-gap, var(--sys-unit-4));
|
|
7
7
|
inline-size: 100%;
|
|
8
8
|
}
|
|
9
|
-
.
|
|
9
|
+
._field_dzutr_3[data-field-group-member] > * {
|
|
10
|
+
grid-row: extra;
|
|
11
|
+
margin-block-start: var(--field-gap, var(--sys-unit-4));
|
|
12
|
+
}
|
|
13
|
+
._field_dzutr_3[data-field-group-member] > ._label_dzutr_13 {
|
|
14
|
+
grid-row: label;
|
|
15
|
+
margin-block: 0 var(--field-gap, var(--sys-unit-4));
|
|
16
|
+
}
|
|
17
|
+
._field_dzutr_3[data-field-group-member] > :first-child:not(._label_dzutr_13),
|
|
18
|
+
._field_dzutr_3[data-field-group-member] > ._label_dzutr_13 + * {
|
|
19
|
+
grid-row: control;
|
|
20
|
+
margin-block-start: 0;
|
|
21
|
+
}
|
|
22
|
+
._field_dzutr_3[data-field-group-member] > ._description_dzutr_22 {
|
|
23
|
+
grid-row: description;
|
|
24
|
+
}
|
|
25
|
+
._field_dzutr_3[data-field-group-member] > ._error_dzutr_25 {
|
|
26
|
+
grid-row: error;
|
|
27
|
+
}
|
|
28
|
+
._label_dzutr_13 {
|
|
10
29
|
color: var(--sys-color-text);
|
|
11
30
|
font: var(--sys-font-label-medium);
|
|
12
31
|
cursor: default;
|
|
13
32
|
}
|
|
14
|
-
.
|
|
33
|
+
._optional_dzutr_33 {
|
|
15
34
|
vertical-align: middle;
|
|
16
35
|
color: var(--sys-color-text-muted);
|
|
17
36
|
font: var(--sys-font-body-small);
|
|
18
37
|
font-size: 0.75rem;
|
|
19
38
|
}
|
|
20
|
-
.
|
|
39
|
+
._inlineText_dzutr_39 {
|
|
21
40
|
grid-area: text;
|
|
22
41
|
}
|
|
23
|
-
.
|
|
42
|
+
._inlineOptional_dzutr_42 {
|
|
24
43
|
grid-area: optional;
|
|
25
44
|
}
|
|
26
|
-
.
|
|
45
|
+
._required_dzutr_45 {
|
|
27
46
|
display: inline-block;
|
|
28
47
|
vertical-align: middle;
|
|
29
48
|
translate: 0 -1px;
|
|
@@ -32,11 +51,11 @@
|
|
|
32
51
|
background-color: var(--field-required-fg, var(--sys-color-primary));
|
|
33
52
|
mask: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='16%2016%2032%2032'%20fill='currentColor'%3e%3cpath%20d='M45.475%2036.291c.377.162.549.477.523.943-.027.469-.35%201.223-.967%202.264-.617%201.072-1.121%201.725-1.51%201.967-.389.24-.744.24-1.066%200l-8.574-6.215%201.129%2010.508c.078.398-.096.707-.525.92-.428.215-1.262.322-2.495.322-1.236%200-2.066-.107-2.496-.322-.43-.213-.604-.521-.523-.92l1.127-10.508-8.533%206.215c-.322.24-.686.24-1.088%200-.402-.242-.912-.895-1.529-1.967-.617-1.041-.934-1.795-.945-2.264-.016-.467.168-.781.543-.943l9.701-4.29-9.701-4.252c-.375-.188-.559-.516-.543-.984.012-.467.328-1.223.945-2.264.617-1.045%201.127-1.686%201.529-1.926s.766-.24%201.088%200l8.533%206.176-1.127-10.467c-.08-.428.094-.748.523-.963s1.26-.321%202.496-.321c1.232%200%202.066.107%202.494.322.43.215.604.535.525.963l-1.129%2010.467%208.574-6.176c.322-.24.678-.24%201.066%200s.893.896%201.51%201.965c.617%201.018.939%201.758.967%202.225.025.469-.146.797-.523.984l-9.701%204.252%209.702%204.289'/%3e%3c/svg%3e") center/contain no-repeat;
|
|
34
53
|
}
|
|
35
|
-
.
|
|
54
|
+
._description_dzutr_22 {
|
|
36
55
|
color: var(--field-description-fg, var(--sys-color-text-muted));
|
|
37
56
|
font: var(--field-description-font, var(--sys-font-body-medium));
|
|
38
57
|
}
|
|
39
|
-
.
|
|
58
|
+
._pending_dzutr_58 {
|
|
40
59
|
display: inline-flex;
|
|
41
60
|
flex: none;
|
|
42
61
|
align-items: center;
|
|
@@ -72,11 +72,12 @@ export type FieldRootProps = BaseField.Root.Props & Readonly<{
|
|
|
72
72
|
}>;
|
|
73
73
|
/**
|
|
74
74
|
* The field frame: label, control, description and error stacked full width.
|
|
75
|
+
* In a field group's row its parts share the row's tracks with its neighbours.
|
|
75
76
|
*
|
|
76
77
|
* @example
|
|
77
78
|
* <Field.Root name="email" invalid={invalid}>…</Field.Root>
|
|
78
79
|
*/
|
|
79
|
-
declare const FieldRoot: ({ className, ...props }: FieldRootProps) => ReactNode;
|
|
80
|
+
declare const FieldRoot: ({ className, children, ...props }: FieldRootProps) => ReactNode;
|
|
80
81
|
export type FieldLabelProps = Omit<BaseField.Label.Props, "className"> & RequirednessProps & Readonly<{
|
|
81
82
|
className?: string;
|
|
82
83
|
}>;
|
|
@@ -113,7 +114,9 @@ export type FieldErrorProps = Omit<BaseField.Error.Props, "match" | "render" | "
|
|
|
113
114
|
* The one error part every control renders, after the description. Normalises
|
|
114
115
|
* its errors to lines with `normalizeFieldErrors` and renders nothing when
|
|
115
116
|
* there are none. It is the field's only live region, so a control must not
|
|
116
|
-
* announce the same message a second time.
|
|
117
|
+
* announce the same message a second time. In a field group that collects
|
|
118
|
+
* the field, the group's error shows the lines instead, and the control is
|
|
119
|
+
* described by them.
|
|
117
120
|
*
|
|
118
121
|
* @example
|
|
119
122
|
* <Field.Error>{errors}</Field.Error>
|
|
@@ -139,7 +142,7 @@ export type FieldIds = Readonly<{
|
|
|
139
142
|
errorId: string;
|
|
140
143
|
/** A stable id and name for the control. */
|
|
141
144
|
controlId: string;
|
|
142
|
-
/** The control's `aria-describedby`: the description and the error that are shown. */
|
|
145
|
+
/** The control's `aria-describedby`: the description and the error that are shown, or the field's lines in a field group that collects it. */
|
|
143
146
|
describedBy: (hasDescription: boolean, invalid: boolean) => string | undefined;
|
|
144
147
|
}>;
|
|
145
148
|
/**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { normalizeFieldErrors } from "../../lib/forms/errors.js";
|
|
2
2
|
import { ErrorText } from "../error-text/error-text.js";
|
|
3
3
|
import { Spinner } from "../spinner/spinner.js";
|
|
4
|
+
import { FieldRowContext, useFieldGroupLineIds } from "./field-group-context.js";
|
|
4
5
|
import field_module_default from "./field.module.js";
|
|
5
6
|
import { c } from "react/compiler-runtime";
|
|
6
|
-
import { useId } from "react";
|
|
7
|
+
import { useContext, useId } from "react";
|
|
7
8
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { clsx } from "clsx";
|
|
9
10
|
import { Field } from "@base-ui/react/field";
|
|
@@ -104,40 +105,59 @@ var InlineLabelText = (t0) => {
|
|
|
104
105
|
};
|
|
105
106
|
/**
|
|
106
107
|
* The field frame: label, control, description and error stacked full width.
|
|
108
|
+
* In a field group's row its parts share the row's tracks with its neighbours.
|
|
107
109
|
*
|
|
108
110
|
* @example
|
|
109
111
|
* <Field.Root name="email" invalid={invalid}>…</Field.Root>
|
|
110
112
|
*/
|
|
111
113
|
var FieldRoot = (t0) => {
|
|
112
|
-
const $ = c(
|
|
114
|
+
const $ = c(13);
|
|
115
|
+
let children;
|
|
113
116
|
let className;
|
|
114
117
|
let props;
|
|
115
118
|
if ($[0] !== t0) {
|
|
116
|
-
({className, ...props} = t0);
|
|
119
|
+
({className, children, ...props} = t0);
|
|
117
120
|
$[0] = t0;
|
|
118
|
-
$[1] =
|
|
119
|
-
$[2] =
|
|
121
|
+
$[1] = children;
|
|
122
|
+
$[2] = className;
|
|
123
|
+
$[3] = props;
|
|
120
124
|
} else {
|
|
121
|
-
|
|
122
|
-
|
|
125
|
+
children = $[1];
|
|
126
|
+
className = $[2];
|
|
127
|
+
props = $[3];
|
|
123
128
|
}
|
|
129
|
+
const inRow = useContext(FieldRowContext);
|
|
124
130
|
let t1;
|
|
125
|
-
if ($[
|
|
131
|
+
if ($[4] !== className) {
|
|
126
132
|
t1 = clsx(field_module_default.field, className);
|
|
127
|
-
$[
|
|
128
|
-
$[
|
|
129
|
-
} else t1 = $[
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
$[4] = className;
|
|
134
|
+
$[5] = t1;
|
|
135
|
+
} else t1 = $[5];
|
|
136
|
+
const t2 = inRow ? "" : void 0;
|
|
137
|
+
let t3;
|
|
138
|
+
if ($[6] !== children) {
|
|
139
|
+
t3 = /* @__PURE__ */ jsx(FieldRowContext, {
|
|
140
|
+
value: false,
|
|
141
|
+
children
|
|
142
|
+
});
|
|
143
|
+
$[6] = children;
|
|
144
|
+
$[7] = t3;
|
|
145
|
+
} else t3 = $[7];
|
|
146
|
+
let t4;
|
|
147
|
+
if ($[8] !== props || $[9] !== t1 || $[10] !== t2 || $[11] !== t3) {
|
|
148
|
+
t4 = /* @__PURE__ */ jsx(Field.Root, {
|
|
133
149
|
className: t1,
|
|
134
|
-
|
|
150
|
+
"data-field-group-member": t2,
|
|
151
|
+
...props,
|
|
152
|
+
children: t3
|
|
135
153
|
});
|
|
136
|
-
$[
|
|
137
|
-
$[
|
|
138
|
-
$[
|
|
139
|
-
|
|
140
|
-
|
|
154
|
+
$[8] = props;
|
|
155
|
+
$[9] = t1;
|
|
156
|
+
$[10] = t2;
|
|
157
|
+
$[11] = t3;
|
|
158
|
+
$[12] = t4;
|
|
159
|
+
} else t4 = $[12];
|
|
160
|
+
return t4;
|
|
141
161
|
};
|
|
142
162
|
/**
|
|
143
163
|
* The label above a control, trailing its requiredness. Renders nothing without
|
|
@@ -280,17 +300,20 @@ var FieldDescription = (t0) => {
|
|
|
280
300
|
} else t1 = $[7];
|
|
281
301
|
return t1;
|
|
282
302
|
};
|
|
303
|
+
var Unrendered = () => null;
|
|
283
304
|
/**
|
|
284
305
|
* The one error part every control renders, after the description. Normalises
|
|
285
306
|
* its errors to lines with `normalizeFieldErrors` and renders nothing when
|
|
286
307
|
* there are none. It is the field's only live region, so a control must not
|
|
287
|
-
* announce the same message a second time.
|
|
308
|
+
* announce the same message a second time. In a field group that collects
|
|
309
|
+
* the field, the group's error shows the lines instead, and the control is
|
|
310
|
+
* described by them.
|
|
288
311
|
*
|
|
289
312
|
* @example
|
|
290
313
|
* <Field.Error>{errors}</Field.Error>
|
|
291
314
|
*/
|
|
292
315
|
var FieldError = (t0) => {
|
|
293
|
-
const $ = c(
|
|
316
|
+
const $ = c(10);
|
|
294
317
|
let errors;
|
|
295
318
|
let props;
|
|
296
319
|
if ($[0] !== t0) {
|
|
@@ -302,15 +325,25 @@ var FieldError = (t0) => {
|
|
|
302
325
|
errors = $[1];
|
|
303
326
|
props = $[2];
|
|
304
327
|
}
|
|
328
|
+
const groupLineIds = useFieldGroupLineIds();
|
|
329
|
+
if (groupLineIds !== void 0) {
|
|
330
|
+
let t1;
|
|
331
|
+
if ($[3] !== groupLineIds) {
|
|
332
|
+
t1 = groupLineIds.map(_temp);
|
|
333
|
+
$[3] = groupLineIds;
|
|
334
|
+
$[4] = t1;
|
|
335
|
+
} else t1 = $[4];
|
|
336
|
+
return t1;
|
|
337
|
+
}
|
|
305
338
|
let t1;
|
|
306
|
-
if ($[
|
|
339
|
+
if ($[5] !== errors) {
|
|
307
340
|
t1 = normalizeFieldErrors(errors);
|
|
308
|
-
$[
|
|
309
|
-
$[
|
|
310
|
-
} else t1 = $[
|
|
341
|
+
$[5] = errors;
|
|
342
|
+
$[6] = t1;
|
|
343
|
+
} else t1 = $[6];
|
|
311
344
|
const messages = t1;
|
|
312
345
|
let t2;
|
|
313
|
-
if ($[
|
|
346
|
+
if ($[7] !== messages || $[8] !== props) {
|
|
314
347
|
t2 = messages.length === 0 ? null : /* @__PURE__ */ jsx(Field.Error, {
|
|
315
348
|
match: true,
|
|
316
349
|
...props,
|
|
@@ -318,13 +351,14 @@ var FieldError = (t0) => {
|
|
|
318
351
|
el: "span",
|
|
319
352
|
role: "alert",
|
|
320
353
|
...renderProps,
|
|
354
|
+
className: clsx(field_module_default.error, renderProps.className),
|
|
321
355
|
children: messages
|
|
322
356
|
})
|
|
323
357
|
});
|
|
324
|
-
$[
|
|
325
|
-
$[
|
|
326
|
-
$[
|
|
327
|
-
} else t2 = $[
|
|
358
|
+
$[7] = messages;
|
|
359
|
+
$[8] = props;
|
|
360
|
+
$[9] = t2;
|
|
361
|
+
} else t2 = $[9];
|
|
328
362
|
return t2;
|
|
329
363
|
};
|
|
330
364
|
/**
|
|
@@ -369,21 +403,23 @@ var FieldPending = (t0) => {
|
|
|
369
403
|
* const { labelId, errorId } = useFieldIds();
|
|
370
404
|
*/
|
|
371
405
|
var useFieldIds = () => {
|
|
372
|
-
const $ = c(
|
|
406
|
+
const $ = c(10);
|
|
373
407
|
const id = useId();
|
|
408
|
+
const groupLineIds = useFieldGroupLineIds();
|
|
374
409
|
const descriptionId = `${id}description`;
|
|
375
410
|
const errorId = `${id}error`;
|
|
376
411
|
const t0 = `${id}label`;
|
|
377
412
|
const t1 = `${id}control`;
|
|
378
413
|
let t2;
|
|
379
|
-
if ($[0] !== descriptionId || $[1] !== errorId) {
|
|
380
|
-
t2 = (hasDescription, invalid) => [hasDescription ? descriptionId : "", invalid ? errorId : ""].filter(
|
|
414
|
+
if ($[0] !== descriptionId || $[1] !== errorId || $[2] !== groupLineIds) {
|
|
415
|
+
t2 = (hasDescription, invalid) => [hasDescription ? descriptionId : "", ...groupLineIds ?? [invalid ? errorId : ""]].filter(_temp2).join(" ") || void 0;
|
|
381
416
|
$[0] = descriptionId;
|
|
382
417
|
$[1] = errorId;
|
|
383
|
-
$[2] =
|
|
384
|
-
|
|
418
|
+
$[2] = groupLineIds;
|
|
419
|
+
$[3] = t2;
|
|
420
|
+
} else t2 = $[3];
|
|
385
421
|
let t3;
|
|
386
|
-
if ($[
|
|
422
|
+
if ($[4] !== descriptionId || $[5] !== errorId || $[6] !== t0 || $[7] !== t1 || $[8] !== t2) {
|
|
387
423
|
t3 = {
|
|
388
424
|
labelId: t0,
|
|
389
425
|
descriptionId,
|
|
@@ -391,13 +427,13 @@ var useFieldIds = () => {
|
|
|
391
427
|
controlId: t1,
|
|
392
428
|
describedBy: t2
|
|
393
429
|
};
|
|
394
|
-
$[
|
|
395
|
-
$[
|
|
396
|
-
$[
|
|
397
|
-
$[
|
|
398
|
-
$[
|
|
399
|
-
$[
|
|
400
|
-
} else t3 = $[
|
|
430
|
+
$[4] = descriptionId;
|
|
431
|
+
$[5] = errorId;
|
|
432
|
+
$[6] = t0;
|
|
433
|
+
$[7] = t1;
|
|
434
|
+
$[8] = t2;
|
|
435
|
+
$[9] = t3;
|
|
436
|
+
} else t3 = $[9];
|
|
401
437
|
return t3;
|
|
402
438
|
};
|
|
403
439
|
/**
|
|
@@ -428,7 +464,14 @@ var Field$1 = {
|
|
|
428
464
|
InlineLabelText,
|
|
429
465
|
useIds: useFieldIds
|
|
430
466
|
};
|
|
431
|
-
function _temp(
|
|
467
|
+
function _temp(lineId) {
|
|
468
|
+
return /* @__PURE__ */ jsx(Field.Error, {
|
|
469
|
+
match: true,
|
|
470
|
+
id: lineId,
|
|
471
|
+
render: /* @__PURE__ */ jsx(Unrendered, {})
|
|
472
|
+
}, lineId);
|
|
473
|
+
}
|
|
474
|
+
function _temp2(part) {
|
|
432
475
|
return part !== "";
|
|
433
476
|
}
|
|
434
477
|
export { Field$1 as Field, useFieldIds };
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import './field.css';// src/components/field/field.module.scss
|
|
2
|
-
var field = "
|
|
3
|
-
var label = "
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
2
|
+
var field = "_field_dzutr_3";
|
|
3
|
+
var label = "_label_dzutr_13";
|
|
4
|
+
var description = "_description_dzutr_22";
|
|
5
|
+
var error = "_error_dzutr_25";
|
|
6
|
+
var optional = "_optional_dzutr_33";
|
|
7
|
+
var inlineText = "_inlineText_dzutr_39";
|
|
8
|
+
var inlineOptional = "_inlineOptional_dzutr_42";
|
|
9
|
+
var required = "_required_dzutr_45";
|
|
10
|
+
var pending = "_pending_dzutr_58";
|
|
10
11
|
var field_module_default = {
|
|
11
12
|
field,
|
|
12
13
|
label,
|
|
14
|
+
description,
|
|
15
|
+
error,
|
|
13
16
|
optional,
|
|
14
17
|
inlineText,
|
|
15
18
|
inlineOptional,
|
|
16
19
|
required,
|
|
17
|
-
description,
|
|
18
20
|
pending
|
|
19
21
|
};
|
|
20
|
-
export { field_module_default as default, description, field, inlineOptional, inlineText, label, optional, pending, required };
|
|
22
|
+
export { field_module_default as default, description, error, field, inlineOptional, inlineText, label, optional, pending, required };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { FieldProps } from "../field/index.ts";
|
|
3
|
+
import type { FieldsetErrorFormat, FieldsetMember } from "./fieldset-root.tsx";
|
|
4
|
+
export type FieldGroupProps = Pick<FieldProps, "requiredness" | "optionalLabel"> & Readonly<{
|
|
5
|
+
/** The visible name of the group, such as "Address". */
|
|
6
|
+
legend: string;
|
|
7
|
+
/** Help about the group as a whole, under its legend. */
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
/** Errors about the group as a whole, such as a failed address lookup, in any shape `normalizeFieldErrors` accepts. */
|
|
10
|
+
errors?: unknown;
|
|
11
|
+
/** The fields whose errors the group shows in its own error instead of under each field. */
|
|
12
|
+
members?: readonly FieldsetMember[];
|
|
13
|
+
/** Turns a member's message into its line. Left out, the line is the message. */
|
|
14
|
+
formatError?: FieldsetErrorFormat;
|
|
15
|
+
className?: string;
|
|
16
|
+
/** The fields, laid out side by side. */
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Related fields side by side under one legend, with one error for all of
|
|
21
|
+
* them: the lines of its `members`, each tied to its field's control, then its
|
|
22
|
+
* own `errors`. Every field's label, control, description and error line up
|
|
23
|
+
* with its neighbours'. The `--field-group-columns` knob sets the columns.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* <FieldGroup legend="Address" optionalLabel="optional" members={members}>
|
|
27
|
+
* <TextField label="Postal code" … />
|
|
28
|
+
* <TextField label="House number" … />
|
|
29
|
+
* </FieldGroup>
|
|
30
|
+
*/
|
|
31
|
+
export declare const FieldGroup: ({ legend, description, errors, requiredness, optionalLabel, members, formatError, className, children, }: FieldGroupProps) => ReactNode;
|