@huin-core/react-form 1.0.1 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +79 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +483 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +451 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +7 -7
package/dist/index.d.mts
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
2
|
+
import * as React from 'react';
|
3
|
+
import { Label as Label$1 } from '@huin-core/react-label';
|
4
|
+
import { Primitive } from '@huin-core/react-primitive';
|
5
|
+
import { Scope as Scope$1 } from '@huin-core/react-context';
|
6
|
+
|
7
|
+
type Scope<C = any> = {
|
8
|
+
[scopeName: string]: React.Context<C>[];
|
9
|
+
} | undefined;
|
10
|
+
type ScopeHook = (scope: Scope) => {
|
11
|
+
[__scopeProp: string]: Scope;
|
12
|
+
};
|
13
|
+
interface CreateScope {
|
14
|
+
scopeName: string;
|
15
|
+
(): ScopeHook;
|
16
|
+
}
|
17
|
+
|
18
|
+
type ScopedProps<P> = P & {
|
19
|
+
__scopeForm?: Scope$1;
|
20
|
+
};
|
21
|
+
declare const createFormScope: CreateScope;
|
22
|
+
type PrimitiveFormProps = React.ComponentPropsWithoutRef<typeof Primitive.form>;
|
23
|
+
interface FormProps extends PrimitiveFormProps {
|
24
|
+
onClearServerErrors?(): void;
|
25
|
+
}
|
26
|
+
declare const Form: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>;
|
27
|
+
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
|
28
|
+
interface FormFieldProps extends PrimitiveDivProps {
|
29
|
+
name: string;
|
30
|
+
serverInvalid?: boolean;
|
31
|
+
}
|
32
|
+
declare const FormField: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
|
33
|
+
type LabelProps = React.ComponentPropsWithoutRef<typeof Label$1>;
|
34
|
+
interface FormLabelProps extends LabelProps {
|
35
|
+
}
|
36
|
+
declare const FormLabel: React.ForwardRefExoticComponent<FormLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
37
|
+
type PrimitiveInputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;
|
38
|
+
interface FormControlProps extends PrimitiveInputProps {
|
39
|
+
}
|
40
|
+
declare const FormControl: React.ForwardRefExoticComponent<FormControlProps & React.RefAttributes<HTMLInputElement>>;
|
41
|
+
declare const validityMatchers: readonly ["badInput", "patternMismatch", "rangeOverflow", "rangeUnderflow", "stepMismatch", "tooLong", "tooShort", "typeMismatch", "valid", "valueMissing"];
|
42
|
+
type ValidityMatcher = (typeof validityMatchers)[number];
|
43
|
+
interface FormMessageProps extends Omit<FormMessageImplProps, 'name'> {
|
44
|
+
match?: ValidityMatcher | CustomMatcher;
|
45
|
+
forceMatch?: boolean;
|
46
|
+
name?: string;
|
47
|
+
}
|
48
|
+
declare const FormMessage: React.ForwardRefExoticComponent<FormMessageProps & React.RefAttributes<HTMLSpanElement>>;
|
49
|
+
type PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;
|
50
|
+
interface FormMessageImplProps extends PrimitiveSpanProps {
|
51
|
+
name: string;
|
52
|
+
}
|
53
|
+
interface FormValidityStateProps {
|
54
|
+
children(validity: ValidityState | undefined): React.ReactNode;
|
55
|
+
name?: string;
|
56
|
+
}
|
57
|
+
declare const FormValidityState: {
|
58
|
+
(props: ScopedProps<FormValidityStateProps>): react_jsx_runtime.JSX.Element;
|
59
|
+
displayName: string;
|
60
|
+
};
|
61
|
+
type PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;
|
62
|
+
interface FormSubmitProps extends PrimitiveButtonProps {
|
63
|
+
}
|
64
|
+
declare const FormSubmit: React.ForwardRefExoticComponent<FormSubmitProps & React.RefAttributes<HTMLButtonElement>>;
|
65
|
+
type SyncCustomMatcher = (value: string, formData: FormData) => boolean;
|
66
|
+
type AsyncCustomMatcher = (value: string, formData: FormData) => Promise<boolean>;
|
67
|
+
type CustomMatcher = SyncCustomMatcher | AsyncCustomMatcher;
|
68
|
+
declare const Root: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>;
|
69
|
+
declare const Field: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
|
70
|
+
declare const Label: React.ForwardRefExoticComponent<FormLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
71
|
+
declare const Control: React.ForwardRefExoticComponent<FormControlProps & React.RefAttributes<HTMLInputElement>>;
|
72
|
+
declare const Message: React.ForwardRefExoticComponent<FormMessageProps & React.RefAttributes<HTMLSpanElement>>;
|
73
|
+
declare const ValidityState: {
|
74
|
+
(props: ScopedProps<FormValidityStateProps>): react_jsx_runtime.JSX.Element;
|
75
|
+
displayName: string;
|
76
|
+
};
|
77
|
+
declare const Submit: React.ForwardRefExoticComponent<FormSubmitProps & React.RefAttributes<HTMLButtonElement>>;
|
78
|
+
|
79
|
+
export { Control, Field, Form, FormControl, type FormControlProps, FormField, type FormFieldProps, FormLabel, type FormLabelProps, FormMessage, type FormMessageProps, type FormProps, FormSubmit, type FormSubmitProps, FormValidityState, type FormValidityStateProps, Label, Message, Root, Submit, ValidityState, createFormScope };
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
2
|
+
import * as React from 'react';
|
3
|
+
import { Label as Label$1 } from '@huin-core/react-label';
|
4
|
+
import { Primitive } from '@huin-core/react-primitive';
|
5
|
+
import { Scope as Scope$1 } from '@huin-core/react-context';
|
6
|
+
|
7
|
+
type Scope<C = any> = {
|
8
|
+
[scopeName: string]: React.Context<C>[];
|
9
|
+
} | undefined;
|
10
|
+
type ScopeHook = (scope: Scope) => {
|
11
|
+
[__scopeProp: string]: Scope;
|
12
|
+
};
|
13
|
+
interface CreateScope {
|
14
|
+
scopeName: string;
|
15
|
+
(): ScopeHook;
|
16
|
+
}
|
17
|
+
|
18
|
+
type ScopedProps<P> = P & {
|
19
|
+
__scopeForm?: Scope$1;
|
20
|
+
};
|
21
|
+
declare const createFormScope: CreateScope;
|
22
|
+
type PrimitiveFormProps = React.ComponentPropsWithoutRef<typeof Primitive.form>;
|
23
|
+
interface FormProps extends PrimitiveFormProps {
|
24
|
+
onClearServerErrors?(): void;
|
25
|
+
}
|
26
|
+
declare const Form: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>;
|
27
|
+
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
|
28
|
+
interface FormFieldProps extends PrimitiveDivProps {
|
29
|
+
name: string;
|
30
|
+
serverInvalid?: boolean;
|
31
|
+
}
|
32
|
+
declare const FormField: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
|
33
|
+
type LabelProps = React.ComponentPropsWithoutRef<typeof Label$1>;
|
34
|
+
interface FormLabelProps extends LabelProps {
|
35
|
+
}
|
36
|
+
declare const FormLabel: React.ForwardRefExoticComponent<FormLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
37
|
+
type PrimitiveInputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;
|
38
|
+
interface FormControlProps extends PrimitiveInputProps {
|
39
|
+
}
|
40
|
+
declare const FormControl: React.ForwardRefExoticComponent<FormControlProps & React.RefAttributes<HTMLInputElement>>;
|
41
|
+
declare const validityMatchers: readonly ["badInput", "patternMismatch", "rangeOverflow", "rangeUnderflow", "stepMismatch", "tooLong", "tooShort", "typeMismatch", "valid", "valueMissing"];
|
42
|
+
type ValidityMatcher = (typeof validityMatchers)[number];
|
43
|
+
interface FormMessageProps extends Omit<FormMessageImplProps, 'name'> {
|
44
|
+
match?: ValidityMatcher | CustomMatcher;
|
45
|
+
forceMatch?: boolean;
|
46
|
+
name?: string;
|
47
|
+
}
|
48
|
+
declare const FormMessage: React.ForwardRefExoticComponent<FormMessageProps & React.RefAttributes<HTMLSpanElement>>;
|
49
|
+
type PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;
|
50
|
+
interface FormMessageImplProps extends PrimitiveSpanProps {
|
51
|
+
name: string;
|
52
|
+
}
|
53
|
+
interface FormValidityStateProps {
|
54
|
+
children(validity: ValidityState | undefined): React.ReactNode;
|
55
|
+
name?: string;
|
56
|
+
}
|
57
|
+
declare const FormValidityState: {
|
58
|
+
(props: ScopedProps<FormValidityStateProps>): react_jsx_runtime.JSX.Element;
|
59
|
+
displayName: string;
|
60
|
+
};
|
61
|
+
type PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;
|
62
|
+
interface FormSubmitProps extends PrimitiveButtonProps {
|
63
|
+
}
|
64
|
+
declare const FormSubmit: React.ForwardRefExoticComponent<FormSubmitProps & React.RefAttributes<HTMLButtonElement>>;
|
65
|
+
type SyncCustomMatcher = (value: string, formData: FormData) => boolean;
|
66
|
+
type AsyncCustomMatcher = (value: string, formData: FormData) => Promise<boolean>;
|
67
|
+
type CustomMatcher = SyncCustomMatcher | AsyncCustomMatcher;
|
68
|
+
declare const Root: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>;
|
69
|
+
declare const Field: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
|
70
|
+
declare const Label: React.ForwardRefExoticComponent<FormLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
71
|
+
declare const Control: React.ForwardRefExoticComponent<FormControlProps & React.RefAttributes<HTMLInputElement>>;
|
72
|
+
declare const Message: React.ForwardRefExoticComponent<FormMessageProps & React.RefAttributes<HTMLSpanElement>>;
|
73
|
+
declare const ValidityState: {
|
74
|
+
(props: ScopedProps<FormValidityStateProps>): react_jsx_runtime.JSX.Element;
|
75
|
+
displayName: string;
|
76
|
+
};
|
77
|
+
declare const Submit: React.ForwardRefExoticComponent<FormSubmitProps & React.RefAttributes<HTMLButtonElement>>;
|
78
|
+
|
79
|
+
export { Control, Field, Form, FormControl, type FormControlProps, FormField, type FormFieldProps, FormLabel, type FormLabelProps, FormMessage, type FormMessageProps, type FormProps, FormSubmit, type FormSubmitProps, FormValidityState, type FormValidityStateProps, Label, Message, Root, Submit, ValidityState, createFormScope };
|
package/dist/index.js
ADDED
@@ -0,0 +1,483 @@
|
|
1
|
+
"use strict";
|
2
|
+
"use client";
|
3
|
+
var __create = Object.create;
|
4
|
+
var __defProp = Object.defineProperty;
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
9
|
+
var __export = (target, all) => {
|
10
|
+
for (var name in all)
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
12
|
+
};
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
15
|
+
for (let key of __getOwnPropNames(from))
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
18
|
+
}
|
19
|
+
return to;
|
20
|
+
};
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
27
|
+
mod
|
28
|
+
));
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
30
|
+
|
31
|
+
// packages/react/form/src/index.ts
|
32
|
+
var src_exports = {};
|
33
|
+
__export(src_exports, {
|
34
|
+
Control: () => Control,
|
35
|
+
Field: () => Field,
|
36
|
+
Form: () => Form,
|
37
|
+
FormControl: () => FormControl,
|
38
|
+
FormField: () => FormField,
|
39
|
+
FormLabel: () => FormLabel,
|
40
|
+
FormMessage: () => FormMessage,
|
41
|
+
FormSubmit: () => FormSubmit,
|
42
|
+
FormValidityState: () => FormValidityState,
|
43
|
+
Label: () => Label,
|
44
|
+
Message: () => Message,
|
45
|
+
Root: () => Root,
|
46
|
+
Submit: () => Submit,
|
47
|
+
ValidityState: () => ValidityState,
|
48
|
+
createFormScope: () => createFormScope
|
49
|
+
});
|
50
|
+
module.exports = __toCommonJS(src_exports);
|
51
|
+
|
52
|
+
// packages/react/form/src/Form.tsx
|
53
|
+
var React = __toESM(require("react"));
|
54
|
+
var import_primitive = require("@huin-core/primitive");
|
55
|
+
var import_react_compose_refs = require("@huin-core/react-compose-refs");
|
56
|
+
var import_react_context = require("@huin-core/react-context");
|
57
|
+
var import_react_id = require("@huin-core/react-id");
|
58
|
+
var import_react_label = require("@huin-core/react-label");
|
59
|
+
var import_react_primitive = require("@huin-core/react-primitive");
|
60
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
61
|
+
var [createFormContext, createFormScope] = (0, import_react_context.createContextScope)("Form");
|
62
|
+
var FORM_NAME = "Form";
|
63
|
+
var [ValidationProvider, useValidationContext] = createFormContext(FORM_NAME);
|
64
|
+
var [AriaDescriptionProvider, useAriaDescriptionContext] = createFormContext(FORM_NAME);
|
65
|
+
var Form = React.forwardRef(
|
66
|
+
(props, forwardedRef) => {
|
67
|
+
const { __scopeForm, onClearServerErrors = () => {
|
68
|
+
}, ...rootProps } = props;
|
69
|
+
const formRef = React.useRef(null);
|
70
|
+
const composedFormRef = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, formRef);
|
71
|
+
const [validityMap, setValidityMap] = React.useState({});
|
72
|
+
const getFieldValidity = React.useCallback(
|
73
|
+
(fieldName) => validityMap[fieldName],
|
74
|
+
[validityMap]
|
75
|
+
);
|
76
|
+
const handleFieldValidityChange = React.useCallback(
|
77
|
+
(fieldName, validity) => setValidityMap((prevValidityMap) => ({
|
78
|
+
...prevValidityMap,
|
79
|
+
[fieldName]: { ...prevValidityMap[fieldName] ?? {}, ...validity }
|
80
|
+
})),
|
81
|
+
[]
|
82
|
+
);
|
83
|
+
const handleFieldValiditionClear = React.useCallback((fieldName) => {
|
84
|
+
setValidityMap((prevValidityMap) => ({ ...prevValidityMap, [fieldName]: void 0 }));
|
85
|
+
setCustomErrorsMap((prevCustomErrorsMap) => ({ ...prevCustomErrorsMap, [fieldName]: {} }));
|
86
|
+
}, []);
|
87
|
+
const [customMatcherEntriesMap, setCustomMatcherEntriesMap] = React.useState({});
|
88
|
+
const getFieldCustomMatcherEntries = React.useCallback(
|
89
|
+
(fieldName) => customMatcherEntriesMap[fieldName] ?? [],
|
90
|
+
[customMatcherEntriesMap]
|
91
|
+
);
|
92
|
+
const handleFieldCustomMatcherAdd = React.useCallback((fieldName, matcherEntry) => {
|
93
|
+
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
94
|
+
...prevCustomMatcherEntriesMap,
|
95
|
+
[fieldName]: [...prevCustomMatcherEntriesMap[fieldName] ?? [], matcherEntry]
|
96
|
+
}));
|
97
|
+
}, []);
|
98
|
+
const handleFieldCustomMatcherRemove = React.useCallback((fieldName, matcherEntryId) => {
|
99
|
+
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
100
|
+
...prevCustomMatcherEntriesMap,
|
101
|
+
[fieldName]: (prevCustomMatcherEntriesMap[fieldName] ?? []).filter(
|
102
|
+
(matcherEntry) => matcherEntry.id !== matcherEntryId
|
103
|
+
)
|
104
|
+
}));
|
105
|
+
}, []);
|
106
|
+
const [customErrorsMap, setCustomErrorsMap] = React.useState({});
|
107
|
+
const getFieldCustomErrors = React.useCallback(
|
108
|
+
(fieldName) => customErrorsMap[fieldName] ?? {},
|
109
|
+
[customErrorsMap]
|
110
|
+
);
|
111
|
+
const handleFieldCustomErrorsChange = React.useCallback((fieldName, customErrors) => {
|
112
|
+
setCustomErrorsMap((prevCustomErrorsMap) => ({
|
113
|
+
...prevCustomErrorsMap,
|
114
|
+
[fieldName]: { ...prevCustomErrorsMap[fieldName] ?? {}, ...customErrors }
|
115
|
+
}));
|
116
|
+
}, []);
|
117
|
+
const [messageIdsMap, setMessageIdsMap] = React.useState({});
|
118
|
+
const handleFieldMessageIdAdd = React.useCallback((fieldName, id) => {
|
119
|
+
setMessageIdsMap((prevMessageIdsMap) => {
|
120
|
+
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]).add(id);
|
121
|
+
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
122
|
+
});
|
123
|
+
}, []);
|
124
|
+
const handleFieldMessageIdRemove = React.useCallback((fieldName, id) => {
|
125
|
+
setMessageIdsMap((prevMessageIdsMap) => {
|
126
|
+
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]);
|
127
|
+
fieldDescriptionIds.delete(id);
|
128
|
+
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
129
|
+
});
|
130
|
+
}, []);
|
131
|
+
const getFieldDescription = React.useCallback(
|
132
|
+
(fieldName) => Array.from(messageIdsMap[fieldName] ?? []).join(" ") || void 0,
|
133
|
+
[messageIdsMap]
|
134
|
+
);
|
135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
136
|
+
ValidationProvider,
|
137
|
+
{
|
138
|
+
scope: __scopeForm,
|
139
|
+
getFieldValidity,
|
140
|
+
onFieldValidityChange: handleFieldValidityChange,
|
141
|
+
getFieldCustomMatcherEntries,
|
142
|
+
onFieldCustomMatcherEntryAdd: handleFieldCustomMatcherAdd,
|
143
|
+
onFieldCustomMatcherEntryRemove: handleFieldCustomMatcherRemove,
|
144
|
+
getFieldCustomErrors,
|
145
|
+
onFieldCustomErrorsChange: handleFieldCustomErrorsChange,
|
146
|
+
onFieldValiditionClear: handleFieldValiditionClear,
|
147
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
148
|
+
AriaDescriptionProvider,
|
149
|
+
{
|
150
|
+
scope: __scopeForm,
|
151
|
+
onFieldMessageIdAdd: handleFieldMessageIdAdd,
|
152
|
+
onFieldMessageIdRemove: handleFieldMessageIdRemove,
|
153
|
+
getFieldDescription,
|
154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
155
|
+
import_react_primitive.Primitive.form,
|
156
|
+
{
|
157
|
+
...rootProps,
|
158
|
+
ref: composedFormRef,
|
159
|
+
onInvalid: (0, import_primitive.composeEventHandlers)(props.onInvalid, (event) => {
|
160
|
+
const firstInvalidControl = getFirstInvalidControl(event.currentTarget);
|
161
|
+
if (firstInvalidControl === event.target) firstInvalidControl.focus();
|
162
|
+
event.preventDefault();
|
163
|
+
}),
|
164
|
+
onSubmit: (0, import_primitive.composeEventHandlers)(props.onSubmit, onClearServerErrors, {
|
165
|
+
checkForDefaultPrevented: false
|
166
|
+
}),
|
167
|
+
onReset: (0, import_primitive.composeEventHandlers)(props.onReset, onClearServerErrors)
|
168
|
+
}
|
169
|
+
)
|
170
|
+
}
|
171
|
+
)
|
172
|
+
}
|
173
|
+
);
|
174
|
+
}
|
175
|
+
);
|
176
|
+
Form.displayName = FORM_NAME;
|
177
|
+
var FIELD_NAME = "FormField";
|
178
|
+
var [FormFieldProvider, useFormFieldContext] = createFormContext(FIELD_NAME);
|
179
|
+
var FormField = React.forwardRef(
|
180
|
+
(props, forwardedRef) => {
|
181
|
+
const { __scopeForm, name, serverInvalid = false, ...fieldProps } = props;
|
182
|
+
const validationContext = useValidationContext(FIELD_NAME, __scopeForm);
|
183
|
+
const validity = validationContext.getFieldValidity(name);
|
184
|
+
const id = (0, import_react_id.useId)();
|
185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormFieldProvider, { scope: __scopeForm, id, name, serverInvalid, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
186
|
+
import_react_primitive.Primitive.div,
|
187
|
+
{
|
188
|
+
"data-valid": getValidAttribute(validity, serverInvalid),
|
189
|
+
"data-invalid": getInvalidAttribute(validity, serverInvalid),
|
190
|
+
...fieldProps,
|
191
|
+
ref: forwardedRef
|
192
|
+
}
|
193
|
+
) });
|
194
|
+
}
|
195
|
+
);
|
196
|
+
FormField.displayName = FIELD_NAME;
|
197
|
+
var LABEL_NAME = "FormLabel";
|
198
|
+
var FormLabel = React.forwardRef(
|
199
|
+
(props, forwardedRef) => {
|
200
|
+
const { __scopeForm, ...labelProps } = props;
|
201
|
+
const validationContext = useValidationContext(LABEL_NAME, __scopeForm);
|
202
|
+
const fieldContext = useFormFieldContext(LABEL_NAME, __scopeForm);
|
203
|
+
const htmlFor = labelProps.htmlFor || fieldContext.id;
|
204
|
+
const validity = validationContext.getFieldValidity(fieldContext.name);
|
205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
206
|
+
import_react_label.Label,
|
207
|
+
{
|
208
|
+
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
209
|
+
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
210
|
+
...labelProps,
|
211
|
+
ref: forwardedRef,
|
212
|
+
htmlFor
|
213
|
+
}
|
214
|
+
);
|
215
|
+
}
|
216
|
+
);
|
217
|
+
FormLabel.displayName = LABEL_NAME;
|
218
|
+
var CONTROL_NAME = "FormControl";
|
219
|
+
var FormControl = React.forwardRef(
|
220
|
+
(props, forwardedRef) => {
|
221
|
+
const { __scopeForm, ...controlProps } = props;
|
222
|
+
const validationContext = useValidationContext(CONTROL_NAME, __scopeForm);
|
223
|
+
const fieldContext = useFormFieldContext(CONTROL_NAME, __scopeForm);
|
224
|
+
const ariaDescriptionContext = useAriaDescriptionContext(CONTROL_NAME, __scopeForm);
|
225
|
+
const ref = React.useRef(null);
|
226
|
+
const composedRef = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
|
227
|
+
const name = controlProps.name || fieldContext.name;
|
228
|
+
const id = controlProps.id || fieldContext.id;
|
229
|
+
const customMatcherEntries = validationContext.getFieldCustomMatcherEntries(name);
|
230
|
+
const { onFieldValidityChange, onFieldCustomErrorsChange, onFieldValiditionClear } = validationContext;
|
231
|
+
const updateControlValidity = React.useCallback(
|
232
|
+
async (control) => {
|
233
|
+
if (hasBuiltInError(control.validity)) {
|
234
|
+
const controlValidity2 = validityStateToObject(control.validity);
|
235
|
+
onFieldValidityChange(name, controlValidity2);
|
236
|
+
return;
|
237
|
+
}
|
238
|
+
const formData = control.form ? new FormData(control.form) : new FormData();
|
239
|
+
const matcherArgs = [control.value, formData];
|
240
|
+
const syncCustomMatcherEntries = [];
|
241
|
+
const ayncCustomMatcherEntries = [];
|
242
|
+
customMatcherEntries.forEach((customMatcherEntry) => {
|
243
|
+
if (isAsyncCustomMatcherEntry(customMatcherEntry, matcherArgs)) {
|
244
|
+
ayncCustomMatcherEntries.push(customMatcherEntry);
|
245
|
+
} else if (isSyncCustomMatcherEntry(customMatcherEntry)) {
|
246
|
+
syncCustomMatcherEntries.push(customMatcherEntry);
|
247
|
+
}
|
248
|
+
});
|
249
|
+
const syncCustomErrors = syncCustomMatcherEntries.map(({ id: id2, match }) => {
|
250
|
+
return [id2, match(...matcherArgs)];
|
251
|
+
});
|
252
|
+
const syncCustomErrorsById = Object.fromEntries(syncCustomErrors);
|
253
|
+
const hasSyncCustomErrors = Object.values(syncCustomErrorsById).some(Boolean);
|
254
|
+
const hasCustomError = hasSyncCustomErrors;
|
255
|
+
control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : "");
|
256
|
+
const controlValidity = validityStateToObject(control.validity);
|
257
|
+
onFieldValidityChange(name, controlValidity);
|
258
|
+
onFieldCustomErrorsChange(name, syncCustomErrorsById);
|
259
|
+
if (!hasSyncCustomErrors && ayncCustomMatcherEntries.length > 0) {
|
260
|
+
const promisedCustomErrors = ayncCustomMatcherEntries.map(
|
261
|
+
({ id: id2, match }) => match(...matcherArgs).then((matches) => [id2, matches])
|
262
|
+
);
|
263
|
+
const asyncCustomErrors = await Promise.all(promisedCustomErrors);
|
264
|
+
const asyncCustomErrorsById = Object.fromEntries(asyncCustomErrors);
|
265
|
+
const hasAsyncCustomErrors = Object.values(asyncCustomErrorsById).some(Boolean);
|
266
|
+
const hasCustomError2 = hasAsyncCustomErrors;
|
267
|
+
control.setCustomValidity(hasCustomError2 ? DEFAULT_INVALID_MESSAGE : "");
|
268
|
+
const controlValidity2 = validityStateToObject(control.validity);
|
269
|
+
onFieldValidityChange(name, controlValidity2);
|
270
|
+
onFieldCustomErrorsChange(name, asyncCustomErrorsById);
|
271
|
+
}
|
272
|
+
},
|
273
|
+
[customMatcherEntries, name, onFieldCustomErrorsChange, onFieldValidityChange]
|
274
|
+
);
|
275
|
+
React.useEffect(() => {
|
276
|
+
const control = ref.current;
|
277
|
+
if (control) {
|
278
|
+
const handleChange = () => updateControlValidity(control);
|
279
|
+
control.addEventListener("change", handleChange);
|
280
|
+
return () => control.removeEventListener("change", handleChange);
|
281
|
+
}
|
282
|
+
}, [updateControlValidity]);
|
283
|
+
const resetControlValidity = React.useCallback(() => {
|
284
|
+
const control = ref.current;
|
285
|
+
if (control) {
|
286
|
+
control.setCustomValidity("");
|
287
|
+
onFieldValiditionClear(name);
|
288
|
+
}
|
289
|
+
}, [name, onFieldValiditionClear]);
|
290
|
+
React.useEffect(() => {
|
291
|
+
const form = ref.current?.form;
|
292
|
+
if (form) {
|
293
|
+
form.addEventListener("reset", resetControlValidity);
|
294
|
+
return () => form.removeEventListener("reset", resetControlValidity);
|
295
|
+
}
|
296
|
+
}, [resetControlValidity]);
|
297
|
+
React.useEffect(() => {
|
298
|
+
const control = ref.current;
|
299
|
+
const form = control?.closest("form");
|
300
|
+
if (form && fieldContext.serverInvalid) {
|
301
|
+
const firstInvalidControl = getFirstInvalidControl(form);
|
302
|
+
if (firstInvalidControl === control) firstInvalidControl.focus();
|
303
|
+
}
|
304
|
+
}, [fieldContext.serverInvalid]);
|
305
|
+
const validity = validationContext.getFieldValidity(name);
|
306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
307
|
+
import_react_primitive.Primitive.input,
|
308
|
+
{
|
309
|
+
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
310
|
+
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
311
|
+
"aria-invalid": fieldContext.serverInvalid ? true : void 0,
|
312
|
+
"aria-describedby": ariaDescriptionContext.getFieldDescription(name),
|
313
|
+
title: "",
|
314
|
+
...controlProps,
|
315
|
+
ref: composedRef,
|
316
|
+
id,
|
317
|
+
name,
|
318
|
+
onInvalid: (0, import_primitive.composeEventHandlers)(props.onInvalid, (event) => {
|
319
|
+
const control = event.currentTarget;
|
320
|
+
updateControlValidity(control);
|
321
|
+
}),
|
322
|
+
onChange: (0, import_primitive.composeEventHandlers)(props.onChange, (event) => {
|
323
|
+
resetControlValidity();
|
324
|
+
})
|
325
|
+
}
|
326
|
+
);
|
327
|
+
}
|
328
|
+
);
|
329
|
+
FormControl.displayName = CONTROL_NAME;
|
330
|
+
var DEFAULT_INVALID_MESSAGE = "This value is not valid";
|
331
|
+
var DEFAULT_BUILT_IN_MESSAGES = {
|
332
|
+
badInput: DEFAULT_INVALID_MESSAGE,
|
333
|
+
patternMismatch: "This value does not match the required pattern",
|
334
|
+
rangeOverflow: "This value is too large",
|
335
|
+
rangeUnderflow: "This value is too small",
|
336
|
+
stepMismatch: "This value does not match the required step",
|
337
|
+
tooLong: "This value is too long",
|
338
|
+
tooShort: "This value is too short",
|
339
|
+
typeMismatch: "This value does not match the required type",
|
340
|
+
valid: void 0,
|
341
|
+
valueMissing: "This value is missing"
|
342
|
+
};
|
343
|
+
var MESSAGE_NAME = "FormMessage";
|
344
|
+
var FormMessage = React.forwardRef(
|
345
|
+
(props, forwardedRef) => {
|
346
|
+
const { match, name: nameProp, ...messageProps } = props;
|
347
|
+
const fieldContext = useFormFieldContext(MESSAGE_NAME, props.__scopeForm);
|
348
|
+
const name = nameProp ?? fieldContext.name;
|
349
|
+
if (match === void 0) {
|
350
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormMessageImpl, { ...messageProps, ref: forwardedRef, name, children: props.children || DEFAULT_INVALID_MESSAGE });
|
351
|
+
} else if (typeof match === "function") {
|
352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormCustomMessage, { match, ...messageProps, ref: forwardedRef, name });
|
353
|
+
} else {
|
354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormBuiltInMessage, { match, ...messageProps, ref: forwardedRef, name });
|
355
|
+
}
|
356
|
+
}
|
357
|
+
);
|
358
|
+
FormMessage.displayName = MESSAGE_NAME;
|
359
|
+
var FormBuiltInMessage = React.forwardRef(
|
360
|
+
(props, forwardedRef) => {
|
361
|
+
const { match, forceMatch = false, name, children, ...messageProps } = props;
|
362
|
+
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
363
|
+
const validity = validationContext.getFieldValidity(name);
|
364
|
+
const matches = forceMatch || validity?.[match];
|
365
|
+
if (matches) {
|
366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormMessageImpl, { ref: forwardedRef, ...messageProps, name, children: children ?? DEFAULT_BUILT_IN_MESSAGES[match] });
|
367
|
+
}
|
368
|
+
return null;
|
369
|
+
}
|
370
|
+
);
|
371
|
+
var FormCustomMessage = React.forwardRef(
|
372
|
+
(props, forwardedRef) => {
|
373
|
+
const { match, forceMatch = false, name, id: idProp, children, ...messageProps } = props;
|
374
|
+
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
375
|
+
const ref = React.useRef(null);
|
376
|
+
const composedRef = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
|
377
|
+
const _id = (0, import_react_id.useId)();
|
378
|
+
const id = idProp ?? _id;
|
379
|
+
const customMatcherEntry = React.useMemo(() => ({ id, match }), [id, match]);
|
380
|
+
const { onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove } = validationContext;
|
381
|
+
React.useEffect(() => {
|
382
|
+
onFieldCustomMatcherEntryAdd(name, customMatcherEntry);
|
383
|
+
return () => onFieldCustomMatcherEntryRemove(name, customMatcherEntry.id);
|
384
|
+
}, [customMatcherEntry, name, onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove]);
|
385
|
+
const validity = validationContext.getFieldValidity(name);
|
386
|
+
const customErrors = validationContext.getFieldCustomErrors(name);
|
387
|
+
const hasMatchingCustomError = customErrors[id];
|
388
|
+
const matches = forceMatch || validity && !hasBuiltInError(validity) && hasMatchingCustomError;
|
389
|
+
if (matches) {
|
390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormMessageImpl, { id, ref: composedRef, ...messageProps, name, children: children ?? DEFAULT_INVALID_MESSAGE });
|
391
|
+
}
|
392
|
+
return null;
|
393
|
+
}
|
394
|
+
);
|
395
|
+
var FormMessageImpl = React.forwardRef(
|
396
|
+
(props, forwardedRef) => {
|
397
|
+
const { __scopeForm, id: idProp, name, ...messageProps } = props;
|
398
|
+
const ariaDescriptionContext = useAriaDescriptionContext(MESSAGE_NAME, __scopeForm);
|
399
|
+
const _id = (0, import_react_id.useId)();
|
400
|
+
const id = idProp ?? _id;
|
401
|
+
const { onFieldMessageIdAdd, onFieldMessageIdRemove } = ariaDescriptionContext;
|
402
|
+
React.useEffect(() => {
|
403
|
+
onFieldMessageIdAdd(name, id);
|
404
|
+
return () => onFieldMessageIdRemove(name, id);
|
405
|
+
}, [name, id, onFieldMessageIdAdd, onFieldMessageIdRemove]);
|
406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.span, { id, ...messageProps, ref: forwardedRef });
|
407
|
+
}
|
408
|
+
);
|
409
|
+
var VALIDITY_STATE_NAME = "FormValidityState";
|
410
|
+
var FormValidityState = (props) => {
|
411
|
+
const { __scopeForm, name: nameProp, children } = props;
|
412
|
+
const validationContext = useValidationContext(VALIDITY_STATE_NAME, __scopeForm);
|
413
|
+
const fieldContext = useFormFieldContext(VALIDITY_STATE_NAME, __scopeForm);
|
414
|
+
const name = nameProp ?? fieldContext.name;
|
415
|
+
const validity = validationContext.getFieldValidity(name);
|
416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: children(validity) });
|
417
|
+
};
|
418
|
+
FormValidityState.displayName = VALIDITY_STATE_NAME;
|
419
|
+
var SUBMIT_NAME = "FormSubmit";
|
420
|
+
var FormSubmit = React.forwardRef(
|
421
|
+
(props, forwardedRef) => {
|
422
|
+
const { __scopeForm, ...submitProps } = props;
|
423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.button, { type: "submit", ...submitProps, ref: forwardedRef });
|
424
|
+
}
|
425
|
+
);
|
426
|
+
FormSubmit.displayName = SUBMIT_NAME;
|
427
|
+
function validityStateToObject(validity) {
|
428
|
+
const object = {};
|
429
|
+
for (const key in validity) {
|
430
|
+
object[key] = validity[key];
|
431
|
+
}
|
432
|
+
return object;
|
433
|
+
}
|
434
|
+
function isHTMLElement(element) {
|
435
|
+
return element instanceof HTMLElement;
|
436
|
+
}
|
437
|
+
function isFormControl(element) {
|
438
|
+
return "validity" in element;
|
439
|
+
}
|
440
|
+
function isInvalid(control) {
|
441
|
+
return isFormControl(control) && (control.validity.valid === false || control.getAttribute("aria-invalid") === "true");
|
442
|
+
}
|
443
|
+
function getFirstInvalidControl(form) {
|
444
|
+
const elements = form.elements;
|
445
|
+
const [firstInvalidControl] = Array.from(elements).filter(isHTMLElement).filter(isInvalid);
|
446
|
+
return firstInvalidControl;
|
447
|
+
}
|
448
|
+
function isAsyncCustomMatcherEntry(entry, args) {
|
449
|
+
return entry.match.constructor.name === "AsyncFunction" || returnsPromise(entry.match, args);
|
450
|
+
}
|
451
|
+
function isSyncCustomMatcherEntry(entry) {
|
452
|
+
return entry.match.constructor.name === "Function";
|
453
|
+
}
|
454
|
+
function returnsPromise(func, args) {
|
455
|
+
return func(...args) instanceof Promise;
|
456
|
+
}
|
457
|
+
function hasBuiltInError(validity) {
|
458
|
+
let error = false;
|
459
|
+
for (const validityKey in validity) {
|
460
|
+
const key = validityKey;
|
461
|
+
if (key !== "valid" && key !== "customError" && validity[key]) {
|
462
|
+
error = true;
|
463
|
+
break;
|
464
|
+
}
|
465
|
+
}
|
466
|
+
return error;
|
467
|
+
}
|
468
|
+
function getValidAttribute(validity, serverInvalid) {
|
469
|
+
if (validity?.valid === true && !serverInvalid) return true;
|
470
|
+
return void 0;
|
471
|
+
}
|
472
|
+
function getInvalidAttribute(validity, serverInvalid) {
|
473
|
+
if (validity?.valid === false || serverInvalid) return true;
|
474
|
+
return void 0;
|
475
|
+
}
|
476
|
+
var Root = Form;
|
477
|
+
var Field = FormField;
|
478
|
+
var Label = FormLabel;
|
479
|
+
var Control = FormControl;
|
480
|
+
var Message = FormMessage;
|
481
|
+
var ValidityState = FormValidityState;
|
482
|
+
var Submit = FormSubmit;
|
483
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/index.ts", "../src/Form.tsx"],
|
4
|
+
"sourcesContent": ["'use client';\nexport {\n createFormScope,\n //\n Form,\n FormField,\n FormLabel,\n FormControl,\n FormMessage,\n FormValidityState,\n FormSubmit,\n //\n Root,\n Field,\n Label,\n Control,\n Message,\n ValidityState,\n Submit,\n} from './Form';\n\nexport type {\n FormProps,\n FormFieldProps,\n FormLabelProps,\n FormControlProps,\n FormMessageProps,\n FormValidityStateProps,\n FormSubmitProps,\n} from './Form';\n", "import * as React from 'react';\nimport { composeEventHandlers } from '@huin-core/primitive';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { createContextScope } from '@huin-core/react-context';\nimport { useId } from '@huin-core/react-id';\nimport { Label as LabelPrimitive } from '@huin-core/react-label';\nimport { Primitive } from '@huin-core/react-primitive';\n\nimport type { Scope } from '@huin-core/react-context';\n\ntype ScopedProps<P> = P & { __scopeForm?: Scope };\nconst [createFormContext, createFormScope] = createContextScope('Form');\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst FORM_NAME = 'Form';\n\ntype ValidityMap = { [fieldName: string]: ValidityState | undefined };\ntype CustomMatcherEntriesMap = { [fieldName: string]: CustomMatcherEntry[] };\ntype CustomErrorsMap = { [fieldName: string]: Record<string, boolean> };\n\ntype ValidationContextValue = {\n getFieldValidity(fieldName: string): ValidityState | undefined;\n onFieldValidityChange(fieldName: string, validity: ValidityState): void;\n\n getFieldCustomMatcherEntries(fieldName: string): CustomMatcherEntry[];\n onFieldCustomMatcherEntryAdd(fieldName: string, matcherEntry: CustomMatcherEntry): void;\n onFieldCustomMatcherEntryRemove(fieldName: string, matcherEntryId: string): void;\n\n getFieldCustomErrors(fieldName: string): Record<string, boolean>;\n onFieldCustomErrorsChange(fieldName: string, errors: Record<string, boolean>): void;\n\n onFieldValiditionClear(fieldName: string): void;\n};\nconst [ValidationProvider, useValidationContext] =\n createFormContext<ValidationContextValue>(FORM_NAME);\n\ntype MessageIdsMap = { [fieldName: string]: Set<string> };\n\ntype AriaDescriptionContextValue = {\n onFieldMessageIdAdd(fieldName: string, id: string): void;\n onFieldMessageIdRemove(fieldName: string, id: string): void;\n getFieldDescription(fieldName: string): string | undefined;\n};\nconst [AriaDescriptionProvider, useAriaDescriptionContext] =\n createFormContext<AriaDescriptionContextValue>(FORM_NAME);\n\ntype FormElement = React.ElementRef<typeof Primitive.form>;\ntype PrimitiveFormProps = React.ComponentPropsWithoutRef<typeof Primitive.form>;\ninterface FormProps extends PrimitiveFormProps {\n onClearServerErrors?(): void;\n}\n\nconst Form = React.forwardRef<FormElement, FormProps>(\n (props: ScopedProps<FormProps>, forwardedRef) => {\n const { __scopeForm, onClearServerErrors = () => {}, ...rootProps } = props;\n const formRef = React.useRef<HTMLFormElement>(null);\n const composedFormRef = useComposedRefs(forwardedRef, formRef);\n\n // native validity per field\n const [validityMap, setValidityMap] = React.useState<ValidityMap>({});\n const getFieldValidity: ValidationContextValue['getFieldValidity'] = React.useCallback(\n (fieldName) => validityMap[fieldName],\n [validityMap]\n );\n const handleFieldValidityChange: ValidationContextValue['onFieldValidityChange'] =\n React.useCallback(\n (fieldName, validity) =>\n setValidityMap((prevValidityMap) => ({\n ...prevValidityMap,\n [fieldName]: { ...(prevValidityMap[fieldName] ?? {}), ...validity },\n })),\n []\n );\n const handleFieldValiditionClear: ValidationContextValue['onFieldValiditionClear'] =\n React.useCallback((fieldName) => {\n setValidityMap((prevValidityMap) => ({ ...prevValidityMap, [fieldName]: undefined }));\n setCustomErrorsMap((prevCustomErrorsMap) => ({ ...prevCustomErrorsMap, [fieldName]: {} }));\n }, []);\n\n // custom matcher entries per field\n const [customMatcherEntriesMap, setCustomMatcherEntriesMap] =\n React.useState<CustomMatcherEntriesMap>({});\n const getFieldCustomMatcherEntries: ValidationContextValue['getFieldCustomMatcherEntries'] =\n React.useCallback(\n (fieldName) => customMatcherEntriesMap[fieldName] ?? [],\n [customMatcherEntriesMap]\n );\n const handleFieldCustomMatcherAdd: ValidationContextValue['onFieldCustomMatcherEntryAdd'] =\n React.useCallback((fieldName, matcherEntry) => {\n setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({\n ...prevCustomMatcherEntriesMap,\n [fieldName]: [...(prevCustomMatcherEntriesMap[fieldName] ?? []), matcherEntry],\n }));\n }, []);\n const handleFieldCustomMatcherRemove: ValidationContextValue['onFieldCustomMatcherEntryRemove'] =\n React.useCallback((fieldName, matcherEntryId) => {\n setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({\n ...prevCustomMatcherEntriesMap,\n [fieldName]: (prevCustomMatcherEntriesMap[fieldName] ?? []).filter(\n (matcherEntry) => matcherEntry.id !== matcherEntryId\n ),\n }));\n }, []);\n\n // custom errors per field\n const [customErrorsMap, setCustomErrorsMap] = React.useState<CustomErrorsMap>({});\n const getFieldCustomErrors: ValidationContextValue['getFieldCustomErrors'] = React.useCallback(\n (fieldName) => customErrorsMap[fieldName] ?? {},\n [customErrorsMap]\n );\n const handleFieldCustomErrorsChange: ValidationContextValue['onFieldCustomErrorsChange'] =\n React.useCallback((fieldName, customErrors) => {\n setCustomErrorsMap((prevCustomErrorsMap) => ({\n ...prevCustomErrorsMap,\n [fieldName]: { ...(prevCustomErrorsMap[fieldName] ?? {}), ...customErrors },\n }));\n }, []);\n\n // messageIds per field\n const [messageIdsMap, setMessageIdsMap] = React.useState<MessageIdsMap>({});\n const handleFieldMessageIdAdd: AriaDescriptionContextValue['onFieldMessageIdAdd'] =\n React.useCallback((fieldName, id) => {\n setMessageIdsMap((prevMessageIdsMap) => {\n const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]).add(id);\n return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };\n });\n }, []);\n const handleFieldMessageIdRemove: AriaDescriptionContextValue['onFieldMessageIdRemove'] =\n React.useCallback((fieldName, id) => {\n setMessageIdsMap((prevMessageIdsMap) => {\n const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]);\n fieldDescriptionIds.delete(id);\n return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };\n });\n }, []);\n const getFieldDescription: AriaDescriptionContextValue['getFieldDescription'] =\n React.useCallback(\n (fieldName) => Array.from(messageIdsMap[fieldName] ?? []).join(' ') || undefined,\n [messageIdsMap]\n );\n\n return (\n <ValidationProvider\n scope={__scopeForm}\n getFieldValidity={getFieldValidity}\n onFieldValidityChange={handleFieldValidityChange}\n getFieldCustomMatcherEntries={getFieldCustomMatcherEntries}\n onFieldCustomMatcherEntryAdd={handleFieldCustomMatcherAdd}\n onFieldCustomMatcherEntryRemove={handleFieldCustomMatcherRemove}\n getFieldCustomErrors={getFieldCustomErrors}\n onFieldCustomErrorsChange={handleFieldCustomErrorsChange}\n onFieldValiditionClear={handleFieldValiditionClear}\n >\n <AriaDescriptionProvider\n scope={__scopeForm}\n onFieldMessageIdAdd={handleFieldMessageIdAdd}\n onFieldMessageIdRemove={handleFieldMessageIdRemove}\n getFieldDescription={getFieldDescription}\n >\n <Primitive.form\n {...rootProps}\n ref={composedFormRef}\n // focus first invalid control when the form is submitted\n onInvalid={composeEventHandlers(props.onInvalid, (event) => {\n const firstInvalidControl = getFirstInvalidControl(event.currentTarget);\n if (firstInvalidControl === event.target) firstInvalidControl.focus();\n\n // prevent default browser UI for form validation\n event.preventDefault();\n })}\n // clear server errors when the form is re-submitted\n onSubmit={composeEventHandlers(props.onSubmit, onClearServerErrors, {\n checkForDefaultPrevented: false,\n })}\n // clear server errors when the form is reset\n onReset={composeEventHandlers(props.onReset, onClearServerErrors)}\n />\n </AriaDescriptionProvider>\n </ValidationProvider>\n );\n }\n);\n\nForm.displayName = FORM_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormField\n * -----------------------------------------------------------------------------------------------*/\n\nconst FIELD_NAME = 'FormField';\n\ntype FormFieldContextValue = {\n id: string;\n name: string;\n serverInvalid: boolean;\n};\nconst [FormFieldProvider, useFormFieldContext] =\n createFormContext<FormFieldContextValue>(FIELD_NAME);\n\ntype FormFieldElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface FormFieldProps extends PrimitiveDivProps {\n name: string;\n serverInvalid?: boolean;\n}\n\nconst FormField = React.forwardRef<FormFieldElement, FormFieldProps>(\n (props: ScopedProps<FormFieldProps>, forwardedRef) => {\n const { __scopeForm, name, serverInvalid = false, ...fieldProps } = props;\n const validationContext = useValidationContext(FIELD_NAME, __scopeForm);\n const validity = validationContext.getFieldValidity(name);\n const id = useId();\n\n return (\n <FormFieldProvider scope={__scopeForm} id={id} name={name} serverInvalid={serverInvalid}>\n <Primitive.div\n data-valid={getValidAttribute(validity, serverInvalid)}\n data-invalid={getInvalidAttribute(validity, serverInvalid)}\n {...fieldProps}\n ref={forwardedRef}\n />\n </FormFieldProvider>\n );\n }\n);\n\nFormField.displayName = FIELD_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormLabel\n * -----------------------------------------------------------------------------------------------*/\n\nconst LABEL_NAME = 'FormLabel';\n\ntype FormLabelElement = React.ElementRef<typeof LabelPrimitive>;\ntype LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive>;\ninterface FormLabelProps extends LabelProps {}\n\nconst FormLabel = React.forwardRef<FormLabelElement, FormLabelProps>(\n (props: ScopedProps<FormLabelProps>, forwardedRef) => {\n const { __scopeForm, ...labelProps } = props;\n const validationContext = useValidationContext(LABEL_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(LABEL_NAME, __scopeForm);\n const htmlFor = labelProps.htmlFor || fieldContext.id;\n const validity = validationContext.getFieldValidity(fieldContext.name);\n\n return (\n <LabelPrimitive\n data-valid={getValidAttribute(validity, fieldContext.serverInvalid)}\n data-invalid={getInvalidAttribute(validity, fieldContext.serverInvalid)}\n {...labelProps}\n ref={forwardedRef}\n htmlFor={htmlFor}\n />\n );\n }\n);\n\nFormLabel.displayName = LABEL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormControl\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTROL_NAME = 'FormControl';\n\ntype FormControlElement = React.ElementRef<typeof Primitive.input>;\ntype PrimitiveInputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;\ninterface FormControlProps extends PrimitiveInputProps {}\n\nconst FormControl = React.forwardRef<FormControlElement, FormControlProps>(\n (props: ScopedProps<FormControlProps>, forwardedRef) => {\n const { __scopeForm, ...controlProps } = props;\n\n const validationContext = useValidationContext(CONTROL_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(CONTROL_NAME, __scopeForm);\n const ariaDescriptionContext = useAriaDescriptionContext(CONTROL_NAME, __scopeForm);\n\n const ref = React.useRef<FormControlElement>(null);\n const composedRef = useComposedRefs(forwardedRef, ref);\n const name = controlProps.name || fieldContext.name;\n const id = controlProps.id || fieldContext.id;\n const customMatcherEntries = validationContext.getFieldCustomMatcherEntries(name);\n\n const { onFieldValidityChange, onFieldCustomErrorsChange, onFieldValiditionClear } =\n validationContext;\n const updateControlValidity = React.useCallback(\n async (control: FormControlElement) => {\n //------------------------------------------------------------------------------------------\n // 1. first, if we have built-in errors we stop here\n\n if (hasBuiltInError(control.validity)) {\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n return;\n }\n\n //------------------------------------------------------------------------------------------\n // 2. then gather the form data to give to custom matchers for cross-comparisons\n\n const formData = control.form ? new FormData(control.form) : new FormData();\n const matcherArgs: CustomMatcherArgs = [control.value, formData];\n\n //------------------------------------------------------------------------------------------\n // 3. split sync and async custom matcher entries\n\n const syncCustomMatcherEntries: Array<SyncCustomMatcherEntry> = [];\n const ayncCustomMatcherEntries: Array<AsyncCustomMatcherEntry> = [];\n customMatcherEntries.forEach((customMatcherEntry) => {\n if (isAsyncCustomMatcherEntry(customMatcherEntry, matcherArgs)) {\n ayncCustomMatcherEntries.push(customMatcherEntry);\n } else if (isSyncCustomMatcherEntry(customMatcherEntry)) {\n syncCustomMatcherEntries.push(customMatcherEntry);\n }\n });\n\n //------------------------------------------------------------------------------------------\n // 4. run sync custom matchers and update control validity / internal validity + errors\n\n const syncCustomErrors = syncCustomMatcherEntries.map(({ id, match }) => {\n return [id, match(...matcherArgs)] as const;\n });\n const syncCustomErrorsById = Object.fromEntries(syncCustomErrors);\n const hasSyncCustomErrors = Object.values(syncCustomErrorsById).some(Boolean);\n const hasCustomError = hasSyncCustomErrors;\n control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : '');\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n onFieldCustomErrorsChange(name, syncCustomErrorsById);\n\n //------------------------------------------------------------------------------------------\n // 5. run async custom matchers and update control validity / internal validity + errors\n\n if (!hasSyncCustomErrors && ayncCustomMatcherEntries.length > 0) {\n const promisedCustomErrors = ayncCustomMatcherEntries.map(({ id, match }) =>\n match(...matcherArgs).then((matches) => [id, matches] as const)\n );\n const asyncCustomErrors = await Promise.all(promisedCustomErrors);\n const asyncCustomErrorsById = Object.fromEntries(asyncCustomErrors);\n const hasAsyncCustomErrors = Object.values(asyncCustomErrorsById).some(Boolean);\n const hasCustomError = hasAsyncCustomErrors;\n control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : '');\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n onFieldCustomErrorsChange(name, asyncCustomErrorsById);\n }\n },\n [customMatcherEntries, name, onFieldCustomErrorsChange, onFieldValidityChange]\n );\n\n React.useEffect(() => {\n const control = ref.current;\n if (control) {\n // We only want validate on change (native `change` event, not React's `onChange`). This is primarily\n // a UX decision, we don't want to validate on every keystroke and React's `onChange` is the `input` event.\n const handleChange = () => updateControlValidity(control);\n control.addEventListener('change', handleChange);\n return () => control.removeEventListener('change', handleChange);\n }\n }, [updateControlValidity]);\n\n const resetControlValidity = React.useCallback(() => {\n const control = ref.current;\n if (control) {\n control.setCustomValidity('');\n onFieldValiditionClear(name);\n }\n }, [name, onFieldValiditionClear]);\n\n // reset validity and errors when the form is reset\n React.useEffect(() => {\n const form = ref.current?.form;\n if (form) {\n form.addEventListener('reset', resetControlValidity);\n return () => form.removeEventListener('reset', resetControlValidity);\n }\n }, [resetControlValidity]);\n\n // focus first invalid control when fields are set as invalid by server\n React.useEffect(() => {\n const control = ref.current;\n const form = control?.closest('form');\n if (form && fieldContext.serverInvalid) {\n const firstInvalidControl = getFirstInvalidControl(form);\n if (firstInvalidControl === control) firstInvalidControl.focus();\n }\n }, [fieldContext.serverInvalid]);\n\n const validity = validationContext.getFieldValidity(name);\n\n return (\n <Primitive.input\n data-valid={getValidAttribute(validity, fieldContext.serverInvalid)}\n data-invalid={getInvalidAttribute(validity, fieldContext.serverInvalid)}\n aria-invalid={fieldContext.serverInvalid ? true : undefined}\n aria-describedby={ariaDescriptionContext.getFieldDescription(name)}\n // disable default browser behaviour of showing built-in error message on hover\n title=\"\"\n {...controlProps}\n ref={composedRef}\n id={id}\n name={name}\n onInvalid={composeEventHandlers(props.onInvalid, (event) => {\n const control = event.currentTarget;\n updateControlValidity(control);\n })}\n onChange={composeEventHandlers(props.onChange, (event) => {\n // reset validity when user changes value\n resetControlValidity();\n })}\n />\n );\n }\n);\n\nFormControl.displayName = CONTROL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormMessage\n * -----------------------------------------------------------------------------------------------*/\n\nconst validityMatchers = [\n 'badInput',\n 'patternMismatch',\n 'rangeOverflow',\n 'rangeUnderflow',\n 'stepMismatch',\n 'tooLong',\n 'tooShort',\n 'typeMismatch',\n 'valid',\n 'valueMissing',\n] as const;\ntype ValidityMatcher = (typeof validityMatchers)[number];\n\nconst DEFAULT_INVALID_MESSAGE = 'This value is not valid';\nconst DEFAULT_BUILT_IN_MESSAGES: Record<ValidityMatcher, string | undefined> = {\n badInput: DEFAULT_INVALID_MESSAGE,\n patternMismatch: 'This value does not match the required pattern',\n rangeOverflow: 'This value is too large',\n rangeUnderflow: 'This value is too small',\n stepMismatch: 'This value does not match the required step',\n tooLong: 'This value is too long',\n tooShort: 'This value is too short',\n typeMismatch: 'This value does not match the required type',\n valid: undefined,\n valueMissing: 'This value is missing',\n};\n\nconst MESSAGE_NAME = 'FormMessage';\n\ntype FormMessageElement = FormMessageImplElement;\ninterface FormMessageProps extends Omit<FormMessageImplProps, 'name'> {\n match?: ValidityMatcher | CustomMatcher;\n forceMatch?: boolean;\n name?: string;\n}\n\nconst FormMessage = React.forwardRef<FormMessageElement, FormMessageProps>(\n (props: ScopedProps<FormMessageProps>, forwardedRef) => {\n const { match, name: nameProp, ...messageProps } = props;\n const fieldContext = useFormFieldContext(MESSAGE_NAME, props.__scopeForm);\n const name = nameProp ?? fieldContext.name;\n\n if (match === undefined) {\n return (\n <FormMessageImpl {...messageProps} ref={forwardedRef} name={name}>\n {props.children || DEFAULT_INVALID_MESSAGE}\n </FormMessageImpl>\n );\n } else if (typeof match === 'function') {\n return <FormCustomMessage match={match} {...messageProps} ref={forwardedRef} name={name} />;\n } else {\n return <FormBuiltInMessage match={match} {...messageProps} ref={forwardedRef} name={name} />;\n }\n }\n);\n\nFormMessage.displayName = MESSAGE_NAME;\n\ntype FormBuiltInMessageElement = FormMessageImplElement;\ninterface FormBuiltInMessageProps extends FormMessageImplProps {\n match: ValidityMatcher;\n forceMatch?: boolean;\n name: string;\n}\n\nconst FormBuiltInMessage = React.forwardRef<FormBuiltInMessageElement, FormBuiltInMessageProps>(\n (props: ScopedProps<FormBuiltInMessageProps>, forwardedRef) => {\n const { match, forceMatch = false, name, children, ...messageProps } = props;\n const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);\n const validity = validationContext.getFieldValidity(name);\n const matches = forceMatch || validity?.[match];\n\n if (matches) {\n return (\n <FormMessageImpl ref={forwardedRef} {...messageProps} name={name}>\n {children ?? DEFAULT_BUILT_IN_MESSAGES[match]}\n </FormMessageImpl>\n );\n }\n\n return null;\n }\n);\n\ntype FormCustomMessageElement = React.ElementRef<typeof FormMessageImpl>;\ninterface FormCustomMessageProps extends React.ComponentPropsWithoutRef<typeof FormMessageImpl> {\n match: CustomMatcher;\n forceMatch?: boolean;\n name: string;\n}\n\nconst FormCustomMessage = React.forwardRef<FormCustomMessageElement, FormCustomMessageProps>(\n (props: ScopedProps<FormCustomMessageProps>, forwardedRef) => {\n const { match, forceMatch = false, name, id: idProp, children, ...messageProps } = props;\n const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);\n const ref = React.useRef<FormCustomMessageElement>(null);\n const composedRef = useComposedRefs(forwardedRef, ref);\n const _id = useId();\n const id = idProp ?? _id;\n\n const customMatcherEntry = React.useMemo(() => ({ id, match }), [id, match]);\n const { onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove } = validationContext;\n React.useEffect(() => {\n onFieldCustomMatcherEntryAdd(name, customMatcherEntry);\n return () => onFieldCustomMatcherEntryRemove(name, customMatcherEntry.id);\n }, [customMatcherEntry, name, onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove]);\n\n const validity = validationContext.getFieldValidity(name);\n const customErrors = validationContext.getFieldCustomErrors(name);\n const hasMatchingCustomError = customErrors[id];\n const matches =\n forceMatch || (validity && !hasBuiltInError(validity) && hasMatchingCustomError);\n\n if (matches) {\n return (\n <FormMessageImpl id={id} ref={composedRef} {...messageProps} name={name}>\n {children ?? DEFAULT_INVALID_MESSAGE}\n </FormMessageImpl>\n );\n }\n\n return null;\n }\n);\n\ntype FormMessageImplElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface FormMessageImplProps extends PrimitiveSpanProps {\n name: string;\n}\n\nconst FormMessageImpl = React.forwardRef<FormMessageImplElement, FormMessageImplProps>(\n (props: ScopedProps<FormMessageImplProps>, forwardedRef) => {\n const { __scopeForm, id: idProp, name, ...messageProps } = props;\n const ariaDescriptionContext = useAriaDescriptionContext(MESSAGE_NAME, __scopeForm);\n const _id = useId();\n const id = idProp ?? _id;\n\n const { onFieldMessageIdAdd, onFieldMessageIdRemove } = ariaDescriptionContext;\n React.useEffect(() => {\n onFieldMessageIdAdd(name, id);\n return () => onFieldMessageIdRemove(name, id);\n }, [name, id, onFieldMessageIdAdd, onFieldMessageIdRemove]);\n\n return <Primitive.span id={id} {...messageProps} ref={forwardedRef} />;\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * FormValidityState\n * -----------------------------------------------------------------------------------------------*/\n\nconst VALIDITY_STATE_NAME = 'FormValidityState';\n\ninterface FormValidityStateProps {\n children(validity: ValidityState | undefined): React.ReactNode;\n name?: string;\n}\n\nconst FormValidityState = (props: ScopedProps<FormValidityStateProps>) => {\n const { __scopeForm, name: nameProp, children } = props;\n const validationContext = useValidationContext(VALIDITY_STATE_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(VALIDITY_STATE_NAME, __scopeForm);\n const name = nameProp ?? fieldContext.name;\n const validity = validationContext.getFieldValidity(name);\n return <>{children(validity)}</>;\n};\n\nFormValidityState.displayName = VALIDITY_STATE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormSubmit\n * -----------------------------------------------------------------------------------------------*/\n\nconst SUBMIT_NAME = 'FormSubmit';\n\ntype FormSubmitElement = React.ElementRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;\ninterface FormSubmitProps extends PrimitiveButtonProps {}\n\nconst FormSubmit = React.forwardRef<FormSubmitElement, FormSubmitProps>(\n (props: ScopedProps<FormSubmitProps>, forwardedRef) => {\n const { __scopeForm, ...submitProps } = props;\n return <Primitive.button type=\"submit\" {...submitProps} ref={forwardedRef} />;\n }\n);\n\nFormSubmit.displayName = SUBMIT_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype ValidityStateKey = keyof ValidityState;\ntype SyncCustomMatcher = (value: string, formData: FormData) => boolean;\ntype AsyncCustomMatcher = (value: string, formData: FormData) => Promise<boolean>;\ntype CustomMatcher = SyncCustomMatcher | AsyncCustomMatcher;\ntype CustomMatcherEntry = { id: string; match: CustomMatcher };\ntype SyncCustomMatcherEntry = { id: string; match: SyncCustomMatcher };\ntype AsyncCustomMatcherEntry = { id: string; match: AsyncCustomMatcher };\ntype CustomMatcherArgs = [string, FormData];\n\nfunction validityStateToObject(validity: ValidityState) {\n const object: any = {};\n for (const key in validity) {\n object[key] = validity[key as ValidityStateKey];\n }\n return object as Record<ValidityStateKey, boolean>;\n}\n\nfunction isHTMLElement(element: any): element is HTMLElement {\n return element instanceof HTMLElement;\n}\n\nfunction isFormControl(element: any): element is { validity: ValidityState } {\n return 'validity' in element;\n}\n\nfunction isInvalid(control: HTMLElement) {\n return (\n isFormControl(control) &&\n (control.validity.valid === false || control.getAttribute('aria-invalid') === 'true')\n );\n}\n\nfunction getFirstInvalidControl(form: HTMLFormElement): HTMLElement | undefined {\n const elements = form.elements;\n const [firstInvalidControl] = Array.from(elements).filter(isHTMLElement).filter(isInvalid);\n return firstInvalidControl;\n}\n\nfunction isAsyncCustomMatcherEntry(\n entry: CustomMatcherEntry,\n args: CustomMatcherArgs\n): entry is AsyncCustomMatcherEntry {\n return entry.match.constructor.name === 'AsyncFunction' || returnsPromise(entry.match, args);\n}\n\nfunction isSyncCustomMatcherEntry(entry: CustomMatcherEntry): entry is SyncCustomMatcherEntry {\n return entry.match.constructor.name === 'Function';\n}\n\nfunction returnsPromise(func: Function, args: Array<unknown>) {\n return func(...args) instanceof Promise;\n}\n\nfunction hasBuiltInError(validity: ValidityState) {\n let error = false;\n for (const validityKey in validity) {\n const key = validityKey as ValidityStateKey;\n if (key !== 'valid' && key !== 'customError' && validity[key]) {\n error = true;\n break;\n }\n }\n return error;\n}\n\nfunction getValidAttribute(validity: ValidityState | undefined, serverInvalid: boolean) {\n if (validity?.valid === true && !serverInvalid) return true;\n return undefined;\n}\nfunction getInvalidAttribute(validity: ValidityState | undefined, serverInvalid: boolean) {\n if (validity?.valid === false || serverInvalid) return true;\n return undefined;\n}\n\n/* -----------------------------------------------------------------------------------------------*/\n\nconst Root = Form;\nconst Field = FormField;\nconst Label = FormLabel;\nconst Control = FormControl;\nconst Message = FormMessage;\nconst ValidityState = FormValidityState;\nconst Submit = FormSubmit;\n\nexport {\n createFormScope,\n //\n Form,\n FormField,\n FormLabel,\n FormControl,\n FormMessage,\n FormValidityState,\n FormSubmit,\n //\n Root,\n Field,\n Label,\n Control,\n Message,\n ValidityState,\n Submit,\n};\n\nexport type {\n FormProps,\n FormFieldProps,\n FormLabelProps,\n FormControlProps,\n FormMessageProps,\n FormValidityStateProps,\n FormSubmitProps,\n};\n"],
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,uBAAqC;AACrC,gCAAgC;AAChC,2BAAmC;AACnC,sBAAsB;AACtB,yBAAwC;AACxC,6BAA0B;AA4JhB;AAvJV,IAAM,CAAC,mBAAmB,eAAe,QAAI,yCAAmB,MAAM;AAMtE,IAAM,YAAY;AAmBlB,IAAM,CAAC,oBAAoB,oBAAoB,IAC7C,kBAA0C,SAAS;AASrD,IAAM,CAAC,yBAAyB,yBAAyB,IACvD,kBAA+C,SAAS;AAQ1D,IAAM,OAAa;AAAA,EACjB,CAAC,OAA+B,iBAAiB;AAC/C,UAAM,EAAE,aAAa,sBAAsB,MAAM;AAAA,IAAC,GAAG,GAAG,UAAU,IAAI;AACtE,UAAM,UAAgB,aAAwB,IAAI;AAClD,UAAM,sBAAkB,2CAAgB,cAAc,OAAO;AAG7D,UAAM,CAAC,aAAa,cAAc,IAAU,eAAsB,CAAC,CAAC;AACpE,UAAM,mBAAqE;AAAA,MACzE,CAAC,cAAc,YAAY,SAAS;AAAA,MACpC,CAAC,WAAW;AAAA,IACd;AACA,UAAM,4BACE;AAAA,MACJ,CAAC,WAAW,aACV,eAAe,CAAC,qBAAqB;AAAA,QACnC,GAAG;AAAA,QACH,CAAC,SAAS,GAAG,EAAE,GAAI,gBAAgB,SAAS,KAAK,CAAC,GAAI,GAAG,SAAS;AAAA,MACpE,EAAE;AAAA,MACJ,CAAC;AAAA,IACH;AACF,UAAM,6BACE,kBAAY,CAAC,cAAc;AAC/B,qBAAe,CAAC,qBAAqB,EAAE,GAAG,iBAAiB,CAAC,SAAS,GAAG,OAAU,EAAE;AACpF,yBAAmB,CAAC,yBAAyB,EAAE,GAAG,qBAAqB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE;AAAA,IAC3F,GAAG,CAAC,CAAC;AAGP,UAAM,CAAC,yBAAyB,0BAA0B,IAClD,eAAkC,CAAC,CAAC;AAC5C,UAAM,+BACE;AAAA,MACJ,CAAC,cAAc,wBAAwB,SAAS,KAAK,CAAC;AAAA,MACtD,CAAC,uBAAuB;AAAA,IAC1B;AACF,UAAM,8BACE,kBAAY,CAAC,WAAW,iBAAiB;AAC7C,iCAA2B,CAAC,iCAAiC;AAAA,QAC3D,GAAG;AAAA,QACH,CAAC,SAAS,GAAG,CAAC,GAAI,4BAA4B,SAAS,KAAK,CAAC,GAAI,YAAY;AAAA,MAC/E,EAAE;AAAA,IACJ,GAAG,CAAC,CAAC;AACP,UAAM,iCACE,kBAAY,CAAC,WAAW,mBAAmB;AAC/C,iCAA2B,CAAC,iCAAiC;AAAA,QAC3D,GAAG;AAAA,QACH,CAAC,SAAS,IAAI,4BAA4B,SAAS,KAAK,CAAC,GAAG;AAAA,UAC1D,CAAC,iBAAiB,aAAa,OAAO;AAAA,QACxC;AAAA,MACF,EAAE;AAAA,IACJ,GAAG,CAAC,CAAC;AAGP,UAAM,CAAC,iBAAiB,kBAAkB,IAAU,eAA0B,CAAC,CAAC;AAChF,UAAM,uBAA6E;AAAA,MACjF,CAAC,cAAc,gBAAgB,SAAS,KAAK,CAAC;AAAA,MAC9C,CAAC,eAAe;AAAA,IAClB;AACA,UAAM,gCACE,kBAAY,CAAC,WAAW,iBAAiB;AAC7C,yBAAmB,CAAC,yBAAyB;AAAA,QAC3C,GAAG;AAAA,QACH,CAAC,SAAS,GAAG,EAAE,GAAI,oBAAoB,SAAS,KAAK,CAAC,GAAI,GAAG,aAAa;AAAA,MAC5E,EAAE;AAAA,IACJ,GAAG,CAAC,CAAC;AAGP,UAAM,CAAC,eAAe,gBAAgB,IAAU,eAAwB,CAAC,CAAC;AAC1E,UAAM,0BACE,kBAAY,CAAC,WAAW,OAAO;AACnC,uBAAiB,CAAC,sBAAsB;AACtC,cAAM,sBAAsB,IAAI,IAAI,kBAAkB,SAAS,CAAC,EAAE,IAAI,EAAE;AACxE,eAAO,EAAE,GAAG,mBAAmB,CAAC,SAAS,GAAG,oBAAoB;AAAA,MAClE,CAAC;AAAA,IACH,GAAG,CAAC,CAAC;AACP,UAAM,6BACE,kBAAY,CAAC,WAAW,OAAO;AACnC,uBAAiB,CAAC,sBAAsB;AACtC,cAAM,sBAAsB,IAAI,IAAI,kBAAkB,SAAS,CAAC;AAChE,4BAAoB,OAAO,EAAE;AAC7B,eAAO,EAAE,GAAG,mBAAmB,CAAC,SAAS,GAAG,oBAAoB;AAAA,MAClE,CAAC;AAAA,IACH,GAAG,CAAC,CAAC;AACP,UAAM,sBACE;AAAA,MACJ,CAAC,cAAc,MAAM,KAAK,cAAc,SAAS,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK;AAAA,MACvE,CAAC,aAAa;AAAA,IAChB;AAEF,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA,uBAAuB;AAAA,QACvB;AAAA,QACA,8BAA8B;AAAA,QAC9B,iCAAiC;AAAA,QACjC;AAAA,QACA,2BAA2B;AAAA,QAC3B,wBAAwB;AAAA,QAExB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,qBAAqB;AAAA,YACrB,wBAAwB;AAAA,YACxB;AAAA,YAEA;AAAA,cAAC,iCAAU;AAAA,cAAV;AAAA,gBACE,GAAG;AAAA,gBACJ,KAAK;AAAA,gBAEL,eAAW,uCAAqB,MAAM,WAAW,CAAC,UAAU;AAC1D,wBAAM,sBAAsB,uBAAuB,MAAM,aAAa;AACtE,sBAAI,wBAAwB,MAAM,OAAQ,qBAAoB,MAAM;AAGpE,wBAAM,eAAe;AAAA,gBACvB,CAAC;AAAA,gBAED,cAAU,uCAAqB,MAAM,UAAU,qBAAqB;AAAA,kBAClE,0BAA0B;AAAA,gBAC5B,CAAC;AAAA,gBAED,aAAS,uCAAqB,MAAM,SAAS,mBAAmB;AAAA;AAAA,YAClE;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;AAMnB,IAAM,aAAa;AAOnB,IAAM,CAAC,mBAAmB,mBAAmB,IAC3C,kBAAyC,UAAU;AASrD,IAAM,YAAkB;AAAA,EACtB,CAAC,OAAoC,iBAAiB;AACpD,UAAM,EAAE,aAAa,MAAM,gBAAgB,OAAO,GAAG,WAAW,IAAI;AACpE,UAAM,oBAAoB,qBAAqB,YAAY,WAAW;AACtE,UAAM,WAAW,kBAAkB,iBAAiB,IAAI;AACxD,UAAM,SAAK,uBAAM;AAEjB,WACE,4CAAC,qBAAkB,OAAO,aAAa,IAAQ,MAAY,eACzD;AAAA,MAAC,iCAAU;AAAA,MAAV;AAAA,QACC,cAAY,kBAAkB,UAAU,aAAa;AAAA,QACrD,gBAAc,oBAAoB,UAAU,aAAa;AAAA,QACxD,GAAG;AAAA,QACJ,KAAK;AAAA;AAAA,IACP,GACF;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAMxB,IAAM,aAAa;AAMnB,IAAM,YAAkB;AAAA,EACtB,CAAC,OAAoC,iBAAiB;AACpD,UAAM,EAAE,aAAa,GAAG,WAAW,IAAI;AACvC,UAAM,oBAAoB,qBAAqB,YAAY,WAAW;AACtE,UAAM,eAAe,oBAAoB,YAAY,WAAW;AAChE,UAAM,UAAU,WAAW,WAAW,aAAa;AACnD,UAAM,WAAW,kBAAkB,iBAAiB,aAAa,IAAI;AAErE,WACE;AAAA,MAAC,mBAAAA;AAAA,MAAA;AAAA,QACC,cAAY,kBAAkB,UAAU,aAAa,aAAa;AAAA,QAClE,gBAAc,oBAAoB,UAAU,aAAa,aAAa;AAAA,QACrE,GAAG;AAAA,QACJ,KAAK;AAAA,QACL;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAMxB,IAAM,eAAe;AAMrB,IAAM,cAAoB;AAAA,EACxB,CAAC,OAAsC,iBAAiB;AACtD,UAAM,EAAE,aAAa,GAAG,aAAa,IAAI;AAEzC,UAAM,oBAAoB,qBAAqB,cAAc,WAAW;AACxE,UAAM,eAAe,oBAAoB,cAAc,WAAW;AAClE,UAAM,yBAAyB,0BAA0B,cAAc,WAAW;AAElF,UAAM,MAAY,aAA2B,IAAI;AACjD,UAAM,kBAAc,2CAAgB,cAAc,GAAG;AACrD,UAAM,OAAO,aAAa,QAAQ,aAAa;AAC/C,UAAM,KAAK,aAAa,MAAM,aAAa;AAC3C,UAAM,uBAAuB,kBAAkB,6BAA6B,IAAI;AAEhF,UAAM,EAAE,uBAAuB,2BAA2B,uBAAuB,IAC/E;AACF,UAAM,wBAA8B;AAAA,MAClC,OAAO,YAAgC;AAIrC,YAAI,gBAAgB,QAAQ,QAAQ,GAAG;AACrC,gBAAMC,mBAAkB,sBAAsB,QAAQ,QAAQ;AAC9D,gCAAsB,MAAMA,gBAAe;AAC3C;AAAA,QACF;AAKA,cAAM,WAAW,QAAQ,OAAO,IAAI,SAAS,QAAQ,IAAI,IAAI,IAAI,SAAS;AAC1E,cAAM,cAAiC,CAAC,QAAQ,OAAO,QAAQ;AAK/D,cAAM,2BAA0D,CAAC;AACjE,cAAM,2BAA2D,CAAC;AAClE,6BAAqB,QAAQ,CAAC,uBAAuB;AACnD,cAAI,0BAA0B,oBAAoB,WAAW,GAAG;AAC9D,qCAAyB,KAAK,kBAAkB;AAAA,UAClD,WAAW,yBAAyB,kBAAkB,GAAG;AACvD,qCAAyB,KAAK,kBAAkB;AAAA,UAClD;AAAA,QACF,CAAC;AAKD,cAAM,mBAAmB,yBAAyB,IAAI,CAAC,EAAE,IAAAC,KAAI,MAAM,MAAM;AACvE,iBAAO,CAACA,KAAI,MAAM,GAAG,WAAW,CAAC;AAAA,QACnC,CAAC;AACD,cAAM,uBAAuB,OAAO,YAAY,gBAAgB;AAChE,cAAM,sBAAsB,OAAO,OAAO,oBAAoB,EAAE,KAAK,OAAO;AAC5E,cAAM,iBAAiB;AACvB,gBAAQ,kBAAkB,iBAAiB,0BAA0B,EAAE;AACvE,cAAM,kBAAkB,sBAAsB,QAAQ,QAAQ;AAC9D,8BAAsB,MAAM,eAAe;AAC3C,kCAA0B,MAAM,oBAAoB;AAKpD,YAAI,CAAC,uBAAuB,yBAAyB,SAAS,GAAG;AAC/D,gBAAM,uBAAuB,yBAAyB;AAAA,YAAI,CAAC,EAAE,IAAAA,KAAI,MAAM,MACrE,MAAM,GAAG,WAAW,EAAE,KAAK,CAAC,YAAY,CAACA,KAAI,OAAO,CAAU;AAAA,UAChE;AACA,gBAAM,oBAAoB,MAAM,QAAQ,IAAI,oBAAoB;AAChE,gBAAM,wBAAwB,OAAO,YAAY,iBAAiB;AAClE,gBAAM,uBAAuB,OAAO,OAAO,qBAAqB,EAAE,KAAK,OAAO;AAC9E,gBAAMC,kBAAiB;AACvB,kBAAQ,kBAAkBA,kBAAiB,0BAA0B,EAAE;AACvE,gBAAMF,mBAAkB,sBAAsB,QAAQ,QAAQ;AAC9D,gCAAsB,MAAMA,gBAAe;AAC3C,oCAA0B,MAAM,qBAAqB;AAAA,QACvD;AAAA,MACF;AAAA,MACA,CAAC,sBAAsB,MAAM,2BAA2B,qBAAqB;AAAA,IAC/E;AAEA,IAAM,gBAAU,MAAM;AACpB,YAAM,UAAU,IAAI;AACpB,UAAI,SAAS;AAGX,cAAM,eAAe,MAAM,sBAAsB,OAAO;AACxD,gBAAQ,iBAAiB,UAAU,YAAY;AAC/C,eAAO,MAAM,QAAQ,oBAAoB,UAAU,YAAY;AAAA,MACjE;AAAA,IACF,GAAG,CAAC,qBAAqB,CAAC;AAE1B,UAAM,uBAA6B,kBAAY,MAAM;AACnD,YAAM,UAAU,IAAI;AACpB,UAAI,SAAS;AACX,gBAAQ,kBAAkB,EAAE;AAC5B,+BAAuB,IAAI;AAAA,MAC7B;AAAA,IACF,GAAG,CAAC,MAAM,sBAAsB,CAAC;AAGjC,IAAM,gBAAU,MAAM;AACpB,YAAM,OAAO,IAAI,SAAS;AAC1B,UAAI,MAAM;AACR,aAAK,iBAAiB,SAAS,oBAAoB;AACnD,eAAO,MAAM,KAAK,oBAAoB,SAAS,oBAAoB;AAAA,MACrE;AAAA,IACF,GAAG,CAAC,oBAAoB,CAAC;AAGzB,IAAM,gBAAU,MAAM;AACpB,YAAM,UAAU,IAAI;AACpB,YAAM,OAAO,SAAS,QAAQ,MAAM;AACpC,UAAI,QAAQ,aAAa,eAAe;AACtC,cAAM,sBAAsB,uBAAuB,IAAI;AACvD,YAAI,wBAAwB,QAAS,qBAAoB,MAAM;AAAA,MACjE;AAAA,IACF,GAAG,CAAC,aAAa,aAAa,CAAC;AAE/B,UAAM,WAAW,kBAAkB,iBAAiB,IAAI;AAExD,WACE;AAAA,MAAC,iCAAU;AAAA,MAAV;AAAA,QACC,cAAY,kBAAkB,UAAU,aAAa,aAAa;AAAA,QAClE,gBAAc,oBAAoB,UAAU,aAAa,aAAa;AAAA,QACtE,gBAAc,aAAa,gBAAgB,OAAO;AAAA,QAClD,oBAAkB,uBAAuB,oBAAoB,IAAI;AAAA,QAEjE,OAAM;AAAA,QACL,GAAG;AAAA,QACJ,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,eAAW,uCAAqB,MAAM,WAAW,CAAC,UAAU;AAC1D,gBAAM,UAAU,MAAM;AACtB,gCAAsB,OAAO;AAAA,QAC/B,CAAC;AAAA,QACD,cAAU,uCAAqB,MAAM,UAAU,CAAC,UAAU;AAExD,+BAAqB;AAAA,QACvB,CAAC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;AAoB1B,IAAM,0BAA0B;AAChC,IAAM,4BAAyE;AAAA,EAC7E,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,SAAS;AAAA,EACT,UAAU;AAAA,EACV,cAAc;AAAA,EACd,OAAO;AAAA,EACP,cAAc;AAChB;AAEA,IAAM,eAAe;AASrB,IAAM,cAAoB;AAAA,EACxB,CAAC,OAAsC,iBAAiB;AACtD,UAAM,EAAE,OAAO,MAAM,UAAU,GAAG,aAAa,IAAI;AACnD,UAAM,eAAe,oBAAoB,cAAc,MAAM,WAAW;AACxE,UAAM,OAAO,YAAY,aAAa;AAEtC,QAAI,UAAU,QAAW;AACvB,aACE,4CAAC,mBAAiB,GAAG,cAAc,KAAK,cAAc,MACnD,gBAAM,YAAY,yBACrB;AAAA,IAEJ,WAAW,OAAO,UAAU,YAAY;AACtC,aAAO,4CAAC,qBAAkB,OAAe,GAAG,cAAc,KAAK,cAAc,MAAY;AAAA,IAC3F,OAAO;AACL,aAAO,4CAAC,sBAAmB,OAAe,GAAG,cAAc,KAAK,cAAc,MAAY;AAAA,IAC5F;AAAA,EACF;AACF;AAEA,YAAY,cAAc;AAS1B,IAAM,qBAA2B;AAAA,EAC/B,CAAC,OAA6C,iBAAiB;AAC7D,UAAM,EAAE,OAAO,aAAa,OAAO,MAAM,UAAU,GAAG,aAAa,IAAI;AACvE,UAAM,oBAAoB,qBAAqB,cAAc,aAAa,WAAW;AACrF,UAAM,WAAW,kBAAkB,iBAAiB,IAAI;AACxD,UAAM,UAAU,cAAc,WAAW,KAAK;AAE9C,QAAI,SAAS;AACX,aACE,4CAAC,mBAAgB,KAAK,cAAe,GAAG,cAAc,MACnD,sBAAY,0BAA0B,KAAK,GAC9C;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AACF;AASA,IAAM,oBAA0B;AAAA,EAC9B,CAAC,OAA4C,iBAAiB;AAC5D,UAAM,EAAE,OAAO,aAAa,OAAO,MAAM,IAAI,QAAQ,UAAU,GAAG,aAAa,IAAI;AACnF,UAAM,oBAAoB,qBAAqB,cAAc,aAAa,WAAW;AACrF,UAAM,MAAY,aAAiC,IAAI;AACvD,UAAM,kBAAc,2CAAgB,cAAc,GAAG;AACrD,UAAM,UAAM,uBAAM;AAClB,UAAM,KAAK,UAAU;AAErB,UAAM,qBAA2B,cAAQ,OAAO,EAAE,IAAI,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC;AAC3E,UAAM,EAAE,8BAA8B,gCAAgC,IAAI;AAC1E,IAAM,gBAAU,MAAM;AACpB,mCAA6B,MAAM,kBAAkB;AACrD,aAAO,MAAM,gCAAgC,MAAM,mBAAmB,EAAE;AAAA,IAC1E,GAAG,CAAC,oBAAoB,MAAM,8BAA8B,+BAA+B,CAAC;AAE5F,UAAM,WAAW,kBAAkB,iBAAiB,IAAI;AACxD,UAAM,eAAe,kBAAkB,qBAAqB,IAAI;AAChE,UAAM,yBAAyB,aAAa,EAAE;AAC9C,UAAM,UACJ,cAAe,YAAY,CAAC,gBAAgB,QAAQ,KAAK;AAE3D,QAAI,SAAS;AACX,aACE,4CAAC,mBAAgB,IAAQ,KAAK,aAAc,GAAG,cAAc,MAC1D,sBAAY,yBACf;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AACF;AAQA,IAAM,kBAAwB;AAAA,EAC5B,CAAC,OAA0C,iBAAiB;AAC1D,UAAM,EAAE,aAAa,IAAI,QAAQ,MAAM,GAAG,aAAa,IAAI;AAC3D,UAAM,yBAAyB,0BAA0B,cAAc,WAAW;AAClF,UAAM,UAAM,uBAAM;AAClB,UAAM,KAAK,UAAU;AAErB,UAAM,EAAE,qBAAqB,uBAAuB,IAAI;AACxD,IAAM,gBAAU,MAAM;AACpB,0BAAoB,MAAM,EAAE;AAC5B,aAAO,MAAM,uBAAuB,MAAM,EAAE;AAAA,IAC9C,GAAG,CAAC,MAAM,IAAI,qBAAqB,sBAAsB,CAAC;AAE1D,WAAO,4CAAC,iCAAU,MAAV,EAAe,IAAS,GAAG,cAAc,KAAK,cAAc;AAAA,EACtE;AACF;AAMA,IAAM,sBAAsB;AAO5B,IAAM,oBAAoB,CAAC,UAA+C;AACxE,QAAM,EAAE,aAAa,MAAM,UAAU,SAAS,IAAI;AAClD,QAAM,oBAAoB,qBAAqB,qBAAqB,WAAW;AAC/E,QAAM,eAAe,oBAAoB,qBAAqB,WAAW;AACzE,QAAM,OAAO,YAAY,aAAa;AACtC,QAAM,WAAW,kBAAkB,iBAAiB,IAAI;AACxD,SAAO,2EAAG,mBAAS,QAAQ,GAAE;AAC/B;AAEA,kBAAkB,cAAc;AAMhC,IAAM,cAAc;AAMpB,IAAM,aAAmB;AAAA,EACvB,CAAC,OAAqC,iBAAiB;AACrD,UAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,WAAO,4CAAC,iCAAU,QAAV,EAAiB,MAAK,UAAU,GAAG,aAAa,KAAK,cAAc;AAAA,EAC7E;AACF;AAEA,WAAW,cAAc;AAazB,SAAS,sBAAsB,UAAyB;AACtD,QAAM,SAAc,CAAC;AACrB,aAAW,OAAO,UAAU;AAC1B,WAAO,GAAG,IAAI,SAAS,GAAuB;AAAA,EAChD;AACA,SAAO;AACT;AAEA,SAAS,cAAc,SAAsC;AAC3D,SAAO,mBAAmB;AAC5B;AAEA,SAAS,cAAc,SAAsD;AAC3E,SAAO,cAAc;AACvB;AAEA,SAAS,UAAU,SAAsB;AACvC,SACE,cAAc,OAAO,MACpB,QAAQ,SAAS,UAAU,SAAS,QAAQ,aAAa,cAAc,MAAM;AAElF;AAEA,SAAS,uBAAuB,MAAgD;AAC9E,QAAM,WAAW,KAAK;AACtB,QAAM,CAAC,mBAAmB,IAAI,MAAM,KAAK,QAAQ,EAAE,OAAO,aAAa,EAAE,OAAO,SAAS;AACzF,SAAO;AACT;AAEA,SAAS,0BACP,OACA,MACkC;AAClC,SAAO,MAAM,MAAM,YAAY,SAAS,mBAAmB,eAAe,MAAM,OAAO,IAAI;AAC7F;AAEA,SAAS,yBAAyB,OAA4D;AAC5F,SAAO,MAAM,MAAM,YAAY,SAAS;AAC1C;AAEA,SAAS,eAAe,MAAgB,MAAsB;AAC5D,SAAO,KAAK,GAAG,IAAI,aAAa;AAClC;AAEA,SAAS,gBAAgB,UAAyB;AAChD,MAAI,QAAQ;AACZ,aAAW,eAAe,UAAU;AAClC,UAAM,MAAM;AACZ,QAAI,QAAQ,WAAW,QAAQ,iBAAiB,SAAS,GAAG,GAAG;AAC7D,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,UAAqC,eAAwB;AACtF,MAAI,UAAU,UAAU,QAAQ,CAAC,cAAe,QAAO;AACvD,SAAO;AACT;AACA,SAAS,oBAAoB,UAAqC,eAAwB;AACxF,MAAI,UAAU,UAAU,SAAS,cAAe,QAAO;AACvD,SAAO;AACT;AAIA,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,gBAAgB;AACtB,IAAM,SAAS;",
|
6
|
+
"names": ["LabelPrimitive", "controlValidity", "id", "hasCustomError"]
|
7
|
+
}
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,451 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
// packages/react/form/src/Form.tsx
|
4
|
+
import * as React from "react";
|
5
|
+
import { composeEventHandlers } from "@huin-core/primitive";
|
6
|
+
import { useComposedRefs } from "@huin-core/react-compose-refs";
|
7
|
+
import { createContextScope } from "@huin-core/react-context";
|
8
|
+
import { useId } from "@huin-core/react-id";
|
9
|
+
import { Label as LabelPrimitive } from "@huin-core/react-label";
|
10
|
+
import { Primitive } from "@huin-core/react-primitive";
|
11
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
12
|
+
var [createFormContext, createFormScope] = createContextScope("Form");
|
13
|
+
var FORM_NAME = "Form";
|
14
|
+
var [ValidationProvider, useValidationContext] = createFormContext(FORM_NAME);
|
15
|
+
var [AriaDescriptionProvider, useAriaDescriptionContext] = createFormContext(FORM_NAME);
|
16
|
+
var Form = React.forwardRef(
|
17
|
+
(props, forwardedRef) => {
|
18
|
+
const { __scopeForm, onClearServerErrors = () => {
|
19
|
+
}, ...rootProps } = props;
|
20
|
+
const formRef = React.useRef(null);
|
21
|
+
const composedFormRef = useComposedRefs(forwardedRef, formRef);
|
22
|
+
const [validityMap, setValidityMap] = React.useState({});
|
23
|
+
const getFieldValidity = React.useCallback(
|
24
|
+
(fieldName) => validityMap[fieldName],
|
25
|
+
[validityMap]
|
26
|
+
);
|
27
|
+
const handleFieldValidityChange = React.useCallback(
|
28
|
+
(fieldName, validity) => setValidityMap((prevValidityMap) => ({
|
29
|
+
...prevValidityMap,
|
30
|
+
[fieldName]: { ...prevValidityMap[fieldName] ?? {}, ...validity }
|
31
|
+
})),
|
32
|
+
[]
|
33
|
+
);
|
34
|
+
const handleFieldValiditionClear = React.useCallback((fieldName) => {
|
35
|
+
setValidityMap((prevValidityMap) => ({ ...prevValidityMap, [fieldName]: void 0 }));
|
36
|
+
setCustomErrorsMap((prevCustomErrorsMap) => ({ ...prevCustomErrorsMap, [fieldName]: {} }));
|
37
|
+
}, []);
|
38
|
+
const [customMatcherEntriesMap, setCustomMatcherEntriesMap] = React.useState({});
|
39
|
+
const getFieldCustomMatcherEntries = React.useCallback(
|
40
|
+
(fieldName) => customMatcherEntriesMap[fieldName] ?? [],
|
41
|
+
[customMatcherEntriesMap]
|
42
|
+
);
|
43
|
+
const handleFieldCustomMatcherAdd = React.useCallback((fieldName, matcherEntry) => {
|
44
|
+
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
45
|
+
...prevCustomMatcherEntriesMap,
|
46
|
+
[fieldName]: [...prevCustomMatcherEntriesMap[fieldName] ?? [], matcherEntry]
|
47
|
+
}));
|
48
|
+
}, []);
|
49
|
+
const handleFieldCustomMatcherRemove = React.useCallback((fieldName, matcherEntryId) => {
|
50
|
+
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
51
|
+
...prevCustomMatcherEntriesMap,
|
52
|
+
[fieldName]: (prevCustomMatcherEntriesMap[fieldName] ?? []).filter(
|
53
|
+
(matcherEntry) => matcherEntry.id !== matcherEntryId
|
54
|
+
)
|
55
|
+
}));
|
56
|
+
}, []);
|
57
|
+
const [customErrorsMap, setCustomErrorsMap] = React.useState({});
|
58
|
+
const getFieldCustomErrors = React.useCallback(
|
59
|
+
(fieldName) => customErrorsMap[fieldName] ?? {},
|
60
|
+
[customErrorsMap]
|
61
|
+
);
|
62
|
+
const handleFieldCustomErrorsChange = React.useCallback((fieldName, customErrors) => {
|
63
|
+
setCustomErrorsMap((prevCustomErrorsMap) => ({
|
64
|
+
...prevCustomErrorsMap,
|
65
|
+
[fieldName]: { ...prevCustomErrorsMap[fieldName] ?? {}, ...customErrors }
|
66
|
+
}));
|
67
|
+
}, []);
|
68
|
+
const [messageIdsMap, setMessageIdsMap] = React.useState({});
|
69
|
+
const handleFieldMessageIdAdd = React.useCallback((fieldName, id) => {
|
70
|
+
setMessageIdsMap((prevMessageIdsMap) => {
|
71
|
+
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]).add(id);
|
72
|
+
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
73
|
+
});
|
74
|
+
}, []);
|
75
|
+
const handleFieldMessageIdRemove = React.useCallback((fieldName, id) => {
|
76
|
+
setMessageIdsMap((prevMessageIdsMap) => {
|
77
|
+
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]);
|
78
|
+
fieldDescriptionIds.delete(id);
|
79
|
+
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
80
|
+
});
|
81
|
+
}, []);
|
82
|
+
const getFieldDescription = React.useCallback(
|
83
|
+
(fieldName) => Array.from(messageIdsMap[fieldName] ?? []).join(" ") || void 0,
|
84
|
+
[messageIdsMap]
|
85
|
+
);
|
86
|
+
return /* @__PURE__ */ jsx(
|
87
|
+
ValidationProvider,
|
88
|
+
{
|
89
|
+
scope: __scopeForm,
|
90
|
+
getFieldValidity,
|
91
|
+
onFieldValidityChange: handleFieldValidityChange,
|
92
|
+
getFieldCustomMatcherEntries,
|
93
|
+
onFieldCustomMatcherEntryAdd: handleFieldCustomMatcherAdd,
|
94
|
+
onFieldCustomMatcherEntryRemove: handleFieldCustomMatcherRemove,
|
95
|
+
getFieldCustomErrors,
|
96
|
+
onFieldCustomErrorsChange: handleFieldCustomErrorsChange,
|
97
|
+
onFieldValiditionClear: handleFieldValiditionClear,
|
98
|
+
children: /* @__PURE__ */ jsx(
|
99
|
+
AriaDescriptionProvider,
|
100
|
+
{
|
101
|
+
scope: __scopeForm,
|
102
|
+
onFieldMessageIdAdd: handleFieldMessageIdAdd,
|
103
|
+
onFieldMessageIdRemove: handleFieldMessageIdRemove,
|
104
|
+
getFieldDescription,
|
105
|
+
children: /* @__PURE__ */ jsx(
|
106
|
+
Primitive.form,
|
107
|
+
{
|
108
|
+
...rootProps,
|
109
|
+
ref: composedFormRef,
|
110
|
+
onInvalid: composeEventHandlers(props.onInvalid, (event) => {
|
111
|
+
const firstInvalidControl = getFirstInvalidControl(event.currentTarget);
|
112
|
+
if (firstInvalidControl === event.target) firstInvalidControl.focus();
|
113
|
+
event.preventDefault();
|
114
|
+
}),
|
115
|
+
onSubmit: composeEventHandlers(props.onSubmit, onClearServerErrors, {
|
116
|
+
checkForDefaultPrevented: false
|
117
|
+
}),
|
118
|
+
onReset: composeEventHandlers(props.onReset, onClearServerErrors)
|
119
|
+
}
|
120
|
+
)
|
121
|
+
}
|
122
|
+
)
|
123
|
+
}
|
124
|
+
);
|
125
|
+
}
|
126
|
+
);
|
127
|
+
Form.displayName = FORM_NAME;
|
128
|
+
var FIELD_NAME = "FormField";
|
129
|
+
var [FormFieldProvider, useFormFieldContext] = createFormContext(FIELD_NAME);
|
130
|
+
var FormField = React.forwardRef(
|
131
|
+
(props, forwardedRef) => {
|
132
|
+
const { __scopeForm, name, serverInvalid = false, ...fieldProps } = props;
|
133
|
+
const validationContext = useValidationContext(FIELD_NAME, __scopeForm);
|
134
|
+
const validity = validationContext.getFieldValidity(name);
|
135
|
+
const id = useId();
|
136
|
+
return /* @__PURE__ */ jsx(FormFieldProvider, { scope: __scopeForm, id, name, serverInvalid, children: /* @__PURE__ */ jsx(
|
137
|
+
Primitive.div,
|
138
|
+
{
|
139
|
+
"data-valid": getValidAttribute(validity, serverInvalid),
|
140
|
+
"data-invalid": getInvalidAttribute(validity, serverInvalid),
|
141
|
+
...fieldProps,
|
142
|
+
ref: forwardedRef
|
143
|
+
}
|
144
|
+
) });
|
145
|
+
}
|
146
|
+
);
|
147
|
+
FormField.displayName = FIELD_NAME;
|
148
|
+
var LABEL_NAME = "FormLabel";
|
149
|
+
var FormLabel = React.forwardRef(
|
150
|
+
(props, forwardedRef) => {
|
151
|
+
const { __scopeForm, ...labelProps } = props;
|
152
|
+
const validationContext = useValidationContext(LABEL_NAME, __scopeForm);
|
153
|
+
const fieldContext = useFormFieldContext(LABEL_NAME, __scopeForm);
|
154
|
+
const htmlFor = labelProps.htmlFor || fieldContext.id;
|
155
|
+
const validity = validationContext.getFieldValidity(fieldContext.name);
|
156
|
+
return /* @__PURE__ */ jsx(
|
157
|
+
LabelPrimitive,
|
158
|
+
{
|
159
|
+
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
160
|
+
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
161
|
+
...labelProps,
|
162
|
+
ref: forwardedRef,
|
163
|
+
htmlFor
|
164
|
+
}
|
165
|
+
);
|
166
|
+
}
|
167
|
+
);
|
168
|
+
FormLabel.displayName = LABEL_NAME;
|
169
|
+
var CONTROL_NAME = "FormControl";
|
170
|
+
var FormControl = React.forwardRef(
|
171
|
+
(props, forwardedRef) => {
|
172
|
+
const { __scopeForm, ...controlProps } = props;
|
173
|
+
const validationContext = useValidationContext(CONTROL_NAME, __scopeForm);
|
174
|
+
const fieldContext = useFormFieldContext(CONTROL_NAME, __scopeForm);
|
175
|
+
const ariaDescriptionContext = useAriaDescriptionContext(CONTROL_NAME, __scopeForm);
|
176
|
+
const ref = React.useRef(null);
|
177
|
+
const composedRef = useComposedRefs(forwardedRef, ref);
|
178
|
+
const name = controlProps.name || fieldContext.name;
|
179
|
+
const id = controlProps.id || fieldContext.id;
|
180
|
+
const customMatcherEntries = validationContext.getFieldCustomMatcherEntries(name);
|
181
|
+
const { onFieldValidityChange, onFieldCustomErrorsChange, onFieldValiditionClear } = validationContext;
|
182
|
+
const updateControlValidity = React.useCallback(
|
183
|
+
async (control) => {
|
184
|
+
if (hasBuiltInError(control.validity)) {
|
185
|
+
const controlValidity2 = validityStateToObject(control.validity);
|
186
|
+
onFieldValidityChange(name, controlValidity2);
|
187
|
+
return;
|
188
|
+
}
|
189
|
+
const formData = control.form ? new FormData(control.form) : new FormData();
|
190
|
+
const matcherArgs = [control.value, formData];
|
191
|
+
const syncCustomMatcherEntries = [];
|
192
|
+
const ayncCustomMatcherEntries = [];
|
193
|
+
customMatcherEntries.forEach((customMatcherEntry) => {
|
194
|
+
if (isAsyncCustomMatcherEntry(customMatcherEntry, matcherArgs)) {
|
195
|
+
ayncCustomMatcherEntries.push(customMatcherEntry);
|
196
|
+
} else if (isSyncCustomMatcherEntry(customMatcherEntry)) {
|
197
|
+
syncCustomMatcherEntries.push(customMatcherEntry);
|
198
|
+
}
|
199
|
+
});
|
200
|
+
const syncCustomErrors = syncCustomMatcherEntries.map(({ id: id2, match }) => {
|
201
|
+
return [id2, match(...matcherArgs)];
|
202
|
+
});
|
203
|
+
const syncCustomErrorsById = Object.fromEntries(syncCustomErrors);
|
204
|
+
const hasSyncCustomErrors = Object.values(syncCustomErrorsById).some(Boolean);
|
205
|
+
const hasCustomError = hasSyncCustomErrors;
|
206
|
+
control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : "");
|
207
|
+
const controlValidity = validityStateToObject(control.validity);
|
208
|
+
onFieldValidityChange(name, controlValidity);
|
209
|
+
onFieldCustomErrorsChange(name, syncCustomErrorsById);
|
210
|
+
if (!hasSyncCustomErrors && ayncCustomMatcherEntries.length > 0) {
|
211
|
+
const promisedCustomErrors = ayncCustomMatcherEntries.map(
|
212
|
+
({ id: id2, match }) => match(...matcherArgs).then((matches) => [id2, matches])
|
213
|
+
);
|
214
|
+
const asyncCustomErrors = await Promise.all(promisedCustomErrors);
|
215
|
+
const asyncCustomErrorsById = Object.fromEntries(asyncCustomErrors);
|
216
|
+
const hasAsyncCustomErrors = Object.values(asyncCustomErrorsById).some(Boolean);
|
217
|
+
const hasCustomError2 = hasAsyncCustomErrors;
|
218
|
+
control.setCustomValidity(hasCustomError2 ? DEFAULT_INVALID_MESSAGE : "");
|
219
|
+
const controlValidity2 = validityStateToObject(control.validity);
|
220
|
+
onFieldValidityChange(name, controlValidity2);
|
221
|
+
onFieldCustomErrorsChange(name, asyncCustomErrorsById);
|
222
|
+
}
|
223
|
+
},
|
224
|
+
[customMatcherEntries, name, onFieldCustomErrorsChange, onFieldValidityChange]
|
225
|
+
);
|
226
|
+
React.useEffect(() => {
|
227
|
+
const control = ref.current;
|
228
|
+
if (control) {
|
229
|
+
const handleChange = () => updateControlValidity(control);
|
230
|
+
control.addEventListener("change", handleChange);
|
231
|
+
return () => control.removeEventListener("change", handleChange);
|
232
|
+
}
|
233
|
+
}, [updateControlValidity]);
|
234
|
+
const resetControlValidity = React.useCallback(() => {
|
235
|
+
const control = ref.current;
|
236
|
+
if (control) {
|
237
|
+
control.setCustomValidity("");
|
238
|
+
onFieldValiditionClear(name);
|
239
|
+
}
|
240
|
+
}, [name, onFieldValiditionClear]);
|
241
|
+
React.useEffect(() => {
|
242
|
+
const form = ref.current?.form;
|
243
|
+
if (form) {
|
244
|
+
form.addEventListener("reset", resetControlValidity);
|
245
|
+
return () => form.removeEventListener("reset", resetControlValidity);
|
246
|
+
}
|
247
|
+
}, [resetControlValidity]);
|
248
|
+
React.useEffect(() => {
|
249
|
+
const control = ref.current;
|
250
|
+
const form = control?.closest("form");
|
251
|
+
if (form && fieldContext.serverInvalid) {
|
252
|
+
const firstInvalidControl = getFirstInvalidControl(form);
|
253
|
+
if (firstInvalidControl === control) firstInvalidControl.focus();
|
254
|
+
}
|
255
|
+
}, [fieldContext.serverInvalid]);
|
256
|
+
const validity = validationContext.getFieldValidity(name);
|
257
|
+
return /* @__PURE__ */ jsx(
|
258
|
+
Primitive.input,
|
259
|
+
{
|
260
|
+
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
261
|
+
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
262
|
+
"aria-invalid": fieldContext.serverInvalid ? true : void 0,
|
263
|
+
"aria-describedby": ariaDescriptionContext.getFieldDescription(name),
|
264
|
+
title: "",
|
265
|
+
...controlProps,
|
266
|
+
ref: composedRef,
|
267
|
+
id,
|
268
|
+
name,
|
269
|
+
onInvalid: composeEventHandlers(props.onInvalid, (event) => {
|
270
|
+
const control = event.currentTarget;
|
271
|
+
updateControlValidity(control);
|
272
|
+
}),
|
273
|
+
onChange: composeEventHandlers(props.onChange, (event) => {
|
274
|
+
resetControlValidity();
|
275
|
+
})
|
276
|
+
}
|
277
|
+
);
|
278
|
+
}
|
279
|
+
);
|
280
|
+
FormControl.displayName = CONTROL_NAME;
|
281
|
+
var DEFAULT_INVALID_MESSAGE = "This value is not valid";
|
282
|
+
var DEFAULT_BUILT_IN_MESSAGES = {
|
283
|
+
badInput: DEFAULT_INVALID_MESSAGE,
|
284
|
+
patternMismatch: "This value does not match the required pattern",
|
285
|
+
rangeOverflow: "This value is too large",
|
286
|
+
rangeUnderflow: "This value is too small",
|
287
|
+
stepMismatch: "This value does not match the required step",
|
288
|
+
tooLong: "This value is too long",
|
289
|
+
tooShort: "This value is too short",
|
290
|
+
typeMismatch: "This value does not match the required type",
|
291
|
+
valid: void 0,
|
292
|
+
valueMissing: "This value is missing"
|
293
|
+
};
|
294
|
+
var MESSAGE_NAME = "FormMessage";
|
295
|
+
var FormMessage = React.forwardRef(
|
296
|
+
(props, forwardedRef) => {
|
297
|
+
const { match, name: nameProp, ...messageProps } = props;
|
298
|
+
const fieldContext = useFormFieldContext(MESSAGE_NAME, props.__scopeForm);
|
299
|
+
const name = nameProp ?? fieldContext.name;
|
300
|
+
if (match === void 0) {
|
301
|
+
return /* @__PURE__ */ jsx(FormMessageImpl, { ...messageProps, ref: forwardedRef, name, children: props.children || DEFAULT_INVALID_MESSAGE });
|
302
|
+
} else if (typeof match === "function") {
|
303
|
+
return /* @__PURE__ */ jsx(FormCustomMessage, { match, ...messageProps, ref: forwardedRef, name });
|
304
|
+
} else {
|
305
|
+
return /* @__PURE__ */ jsx(FormBuiltInMessage, { match, ...messageProps, ref: forwardedRef, name });
|
306
|
+
}
|
307
|
+
}
|
308
|
+
);
|
309
|
+
FormMessage.displayName = MESSAGE_NAME;
|
310
|
+
var FormBuiltInMessage = React.forwardRef(
|
311
|
+
(props, forwardedRef) => {
|
312
|
+
const { match, forceMatch = false, name, children, ...messageProps } = props;
|
313
|
+
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
314
|
+
const validity = validationContext.getFieldValidity(name);
|
315
|
+
const matches = forceMatch || validity?.[match];
|
316
|
+
if (matches) {
|
317
|
+
return /* @__PURE__ */ jsx(FormMessageImpl, { ref: forwardedRef, ...messageProps, name, children: children ?? DEFAULT_BUILT_IN_MESSAGES[match] });
|
318
|
+
}
|
319
|
+
return null;
|
320
|
+
}
|
321
|
+
);
|
322
|
+
var FormCustomMessage = React.forwardRef(
|
323
|
+
(props, forwardedRef) => {
|
324
|
+
const { match, forceMatch = false, name, id: idProp, children, ...messageProps } = props;
|
325
|
+
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
326
|
+
const ref = React.useRef(null);
|
327
|
+
const composedRef = useComposedRefs(forwardedRef, ref);
|
328
|
+
const _id = useId();
|
329
|
+
const id = idProp ?? _id;
|
330
|
+
const customMatcherEntry = React.useMemo(() => ({ id, match }), [id, match]);
|
331
|
+
const { onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove } = validationContext;
|
332
|
+
React.useEffect(() => {
|
333
|
+
onFieldCustomMatcherEntryAdd(name, customMatcherEntry);
|
334
|
+
return () => onFieldCustomMatcherEntryRemove(name, customMatcherEntry.id);
|
335
|
+
}, [customMatcherEntry, name, onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove]);
|
336
|
+
const validity = validationContext.getFieldValidity(name);
|
337
|
+
const customErrors = validationContext.getFieldCustomErrors(name);
|
338
|
+
const hasMatchingCustomError = customErrors[id];
|
339
|
+
const matches = forceMatch || validity && !hasBuiltInError(validity) && hasMatchingCustomError;
|
340
|
+
if (matches) {
|
341
|
+
return /* @__PURE__ */ jsx(FormMessageImpl, { id, ref: composedRef, ...messageProps, name, children: children ?? DEFAULT_INVALID_MESSAGE });
|
342
|
+
}
|
343
|
+
return null;
|
344
|
+
}
|
345
|
+
);
|
346
|
+
var FormMessageImpl = React.forwardRef(
|
347
|
+
(props, forwardedRef) => {
|
348
|
+
const { __scopeForm, id: idProp, name, ...messageProps } = props;
|
349
|
+
const ariaDescriptionContext = useAriaDescriptionContext(MESSAGE_NAME, __scopeForm);
|
350
|
+
const _id = useId();
|
351
|
+
const id = idProp ?? _id;
|
352
|
+
const { onFieldMessageIdAdd, onFieldMessageIdRemove } = ariaDescriptionContext;
|
353
|
+
React.useEffect(() => {
|
354
|
+
onFieldMessageIdAdd(name, id);
|
355
|
+
return () => onFieldMessageIdRemove(name, id);
|
356
|
+
}, [name, id, onFieldMessageIdAdd, onFieldMessageIdRemove]);
|
357
|
+
return /* @__PURE__ */ jsx(Primitive.span, { id, ...messageProps, ref: forwardedRef });
|
358
|
+
}
|
359
|
+
);
|
360
|
+
var VALIDITY_STATE_NAME = "FormValidityState";
|
361
|
+
var FormValidityState = (props) => {
|
362
|
+
const { __scopeForm, name: nameProp, children } = props;
|
363
|
+
const validationContext = useValidationContext(VALIDITY_STATE_NAME, __scopeForm);
|
364
|
+
const fieldContext = useFormFieldContext(VALIDITY_STATE_NAME, __scopeForm);
|
365
|
+
const name = nameProp ?? fieldContext.name;
|
366
|
+
const validity = validationContext.getFieldValidity(name);
|
367
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children(validity) });
|
368
|
+
};
|
369
|
+
FormValidityState.displayName = VALIDITY_STATE_NAME;
|
370
|
+
var SUBMIT_NAME = "FormSubmit";
|
371
|
+
var FormSubmit = React.forwardRef(
|
372
|
+
(props, forwardedRef) => {
|
373
|
+
const { __scopeForm, ...submitProps } = props;
|
374
|
+
return /* @__PURE__ */ jsx(Primitive.button, { type: "submit", ...submitProps, ref: forwardedRef });
|
375
|
+
}
|
376
|
+
);
|
377
|
+
FormSubmit.displayName = SUBMIT_NAME;
|
378
|
+
function validityStateToObject(validity) {
|
379
|
+
const object = {};
|
380
|
+
for (const key in validity) {
|
381
|
+
object[key] = validity[key];
|
382
|
+
}
|
383
|
+
return object;
|
384
|
+
}
|
385
|
+
function isHTMLElement(element) {
|
386
|
+
return element instanceof HTMLElement;
|
387
|
+
}
|
388
|
+
function isFormControl(element) {
|
389
|
+
return "validity" in element;
|
390
|
+
}
|
391
|
+
function isInvalid(control) {
|
392
|
+
return isFormControl(control) && (control.validity.valid === false || control.getAttribute("aria-invalid") === "true");
|
393
|
+
}
|
394
|
+
function getFirstInvalidControl(form) {
|
395
|
+
const elements = form.elements;
|
396
|
+
const [firstInvalidControl] = Array.from(elements).filter(isHTMLElement).filter(isInvalid);
|
397
|
+
return firstInvalidControl;
|
398
|
+
}
|
399
|
+
function isAsyncCustomMatcherEntry(entry, args) {
|
400
|
+
return entry.match.constructor.name === "AsyncFunction" || returnsPromise(entry.match, args);
|
401
|
+
}
|
402
|
+
function isSyncCustomMatcherEntry(entry) {
|
403
|
+
return entry.match.constructor.name === "Function";
|
404
|
+
}
|
405
|
+
function returnsPromise(func, args) {
|
406
|
+
return func(...args) instanceof Promise;
|
407
|
+
}
|
408
|
+
function hasBuiltInError(validity) {
|
409
|
+
let error = false;
|
410
|
+
for (const validityKey in validity) {
|
411
|
+
const key = validityKey;
|
412
|
+
if (key !== "valid" && key !== "customError" && validity[key]) {
|
413
|
+
error = true;
|
414
|
+
break;
|
415
|
+
}
|
416
|
+
}
|
417
|
+
return error;
|
418
|
+
}
|
419
|
+
function getValidAttribute(validity, serverInvalid) {
|
420
|
+
if (validity?.valid === true && !serverInvalid) return true;
|
421
|
+
return void 0;
|
422
|
+
}
|
423
|
+
function getInvalidAttribute(validity, serverInvalid) {
|
424
|
+
if (validity?.valid === false || serverInvalid) return true;
|
425
|
+
return void 0;
|
426
|
+
}
|
427
|
+
var Root = Form;
|
428
|
+
var Field = FormField;
|
429
|
+
var Label = FormLabel;
|
430
|
+
var Control = FormControl;
|
431
|
+
var Message = FormMessage;
|
432
|
+
var ValidityState = FormValidityState;
|
433
|
+
var Submit = FormSubmit;
|
434
|
+
export {
|
435
|
+
Control,
|
436
|
+
Field,
|
437
|
+
Form,
|
438
|
+
FormControl,
|
439
|
+
FormField,
|
440
|
+
FormLabel,
|
441
|
+
FormMessage,
|
442
|
+
FormSubmit,
|
443
|
+
FormValidityState,
|
444
|
+
Label,
|
445
|
+
Message,
|
446
|
+
Root,
|
447
|
+
Submit,
|
448
|
+
ValidityState,
|
449
|
+
createFormScope
|
450
|
+
};
|
451
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/Form.tsx"],
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nimport { composeEventHandlers } from '@huin-core/primitive';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { createContextScope } from '@huin-core/react-context';\nimport { useId } from '@huin-core/react-id';\nimport { Label as LabelPrimitive } from '@huin-core/react-label';\nimport { Primitive } from '@huin-core/react-primitive';\n\nimport type { Scope } from '@huin-core/react-context';\n\ntype ScopedProps<P> = P & { __scopeForm?: Scope };\nconst [createFormContext, createFormScope] = createContextScope('Form');\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst FORM_NAME = 'Form';\n\ntype ValidityMap = { [fieldName: string]: ValidityState | undefined };\ntype CustomMatcherEntriesMap = { [fieldName: string]: CustomMatcherEntry[] };\ntype CustomErrorsMap = { [fieldName: string]: Record<string, boolean> };\n\ntype ValidationContextValue = {\n getFieldValidity(fieldName: string): ValidityState | undefined;\n onFieldValidityChange(fieldName: string, validity: ValidityState): void;\n\n getFieldCustomMatcherEntries(fieldName: string): CustomMatcherEntry[];\n onFieldCustomMatcherEntryAdd(fieldName: string, matcherEntry: CustomMatcherEntry): void;\n onFieldCustomMatcherEntryRemove(fieldName: string, matcherEntryId: string): void;\n\n getFieldCustomErrors(fieldName: string): Record<string, boolean>;\n onFieldCustomErrorsChange(fieldName: string, errors: Record<string, boolean>): void;\n\n onFieldValiditionClear(fieldName: string): void;\n};\nconst [ValidationProvider, useValidationContext] =\n createFormContext<ValidationContextValue>(FORM_NAME);\n\ntype MessageIdsMap = { [fieldName: string]: Set<string> };\n\ntype AriaDescriptionContextValue = {\n onFieldMessageIdAdd(fieldName: string, id: string): void;\n onFieldMessageIdRemove(fieldName: string, id: string): void;\n getFieldDescription(fieldName: string): string | undefined;\n};\nconst [AriaDescriptionProvider, useAriaDescriptionContext] =\n createFormContext<AriaDescriptionContextValue>(FORM_NAME);\n\ntype FormElement = React.ElementRef<typeof Primitive.form>;\ntype PrimitiveFormProps = React.ComponentPropsWithoutRef<typeof Primitive.form>;\ninterface FormProps extends PrimitiveFormProps {\n onClearServerErrors?(): void;\n}\n\nconst Form = React.forwardRef<FormElement, FormProps>(\n (props: ScopedProps<FormProps>, forwardedRef) => {\n const { __scopeForm, onClearServerErrors = () => {}, ...rootProps } = props;\n const formRef = React.useRef<HTMLFormElement>(null);\n const composedFormRef = useComposedRefs(forwardedRef, formRef);\n\n // native validity per field\n const [validityMap, setValidityMap] = React.useState<ValidityMap>({});\n const getFieldValidity: ValidationContextValue['getFieldValidity'] = React.useCallback(\n (fieldName) => validityMap[fieldName],\n [validityMap]\n );\n const handleFieldValidityChange: ValidationContextValue['onFieldValidityChange'] =\n React.useCallback(\n (fieldName, validity) =>\n setValidityMap((prevValidityMap) => ({\n ...prevValidityMap,\n [fieldName]: { ...(prevValidityMap[fieldName] ?? {}), ...validity },\n })),\n []\n );\n const handleFieldValiditionClear: ValidationContextValue['onFieldValiditionClear'] =\n React.useCallback((fieldName) => {\n setValidityMap((prevValidityMap) => ({ ...prevValidityMap, [fieldName]: undefined }));\n setCustomErrorsMap((prevCustomErrorsMap) => ({ ...prevCustomErrorsMap, [fieldName]: {} }));\n }, []);\n\n // custom matcher entries per field\n const [customMatcherEntriesMap, setCustomMatcherEntriesMap] =\n React.useState<CustomMatcherEntriesMap>({});\n const getFieldCustomMatcherEntries: ValidationContextValue['getFieldCustomMatcherEntries'] =\n React.useCallback(\n (fieldName) => customMatcherEntriesMap[fieldName] ?? [],\n [customMatcherEntriesMap]\n );\n const handleFieldCustomMatcherAdd: ValidationContextValue['onFieldCustomMatcherEntryAdd'] =\n React.useCallback((fieldName, matcherEntry) => {\n setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({\n ...prevCustomMatcherEntriesMap,\n [fieldName]: [...(prevCustomMatcherEntriesMap[fieldName] ?? []), matcherEntry],\n }));\n }, []);\n const handleFieldCustomMatcherRemove: ValidationContextValue['onFieldCustomMatcherEntryRemove'] =\n React.useCallback((fieldName, matcherEntryId) => {\n setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({\n ...prevCustomMatcherEntriesMap,\n [fieldName]: (prevCustomMatcherEntriesMap[fieldName] ?? []).filter(\n (matcherEntry) => matcherEntry.id !== matcherEntryId\n ),\n }));\n }, []);\n\n // custom errors per field\n const [customErrorsMap, setCustomErrorsMap] = React.useState<CustomErrorsMap>({});\n const getFieldCustomErrors: ValidationContextValue['getFieldCustomErrors'] = React.useCallback(\n (fieldName) => customErrorsMap[fieldName] ?? {},\n [customErrorsMap]\n );\n const handleFieldCustomErrorsChange: ValidationContextValue['onFieldCustomErrorsChange'] =\n React.useCallback((fieldName, customErrors) => {\n setCustomErrorsMap((prevCustomErrorsMap) => ({\n ...prevCustomErrorsMap,\n [fieldName]: { ...(prevCustomErrorsMap[fieldName] ?? {}), ...customErrors },\n }));\n }, []);\n\n // messageIds per field\n const [messageIdsMap, setMessageIdsMap] = React.useState<MessageIdsMap>({});\n const handleFieldMessageIdAdd: AriaDescriptionContextValue['onFieldMessageIdAdd'] =\n React.useCallback((fieldName, id) => {\n setMessageIdsMap((prevMessageIdsMap) => {\n const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]).add(id);\n return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };\n });\n }, []);\n const handleFieldMessageIdRemove: AriaDescriptionContextValue['onFieldMessageIdRemove'] =\n React.useCallback((fieldName, id) => {\n setMessageIdsMap((prevMessageIdsMap) => {\n const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]);\n fieldDescriptionIds.delete(id);\n return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };\n });\n }, []);\n const getFieldDescription: AriaDescriptionContextValue['getFieldDescription'] =\n React.useCallback(\n (fieldName) => Array.from(messageIdsMap[fieldName] ?? []).join(' ') || undefined,\n [messageIdsMap]\n );\n\n return (\n <ValidationProvider\n scope={__scopeForm}\n getFieldValidity={getFieldValidity}\n onFieldValidityChange={handleFieldValidityChange}\n getFieldCustomMatcherEntries={getFieldCustomMatcherEntries}\n onFieldCustomMatcherEntryAdd={handleFieldCustomMatcherAdd}\n onFieldCustomMatcherEntryRemove={handleFieldCustomMatcherRemove}\n getFieldCustomErrors={getFieldCustomErrors}\n onFieldCustomErrorsChange={handleFieldCustomErrorsChange}\n onFieldValiditionClear={handleFieldValiditionClear}\n >\n <AriaDescriptionProvider\n scope={__scopeForm}\n onFieldMessageIdAdd={handleFieldMessageIdAdd}\n onFieldMessageIdRemove={handleFieldMessageIdRemove}\n getFieldDescription={getFieldDescription}\n >\n <Primitive.form\n {...rootProps}\n ref={composedFormRef}\n // focus first invalid control when the form is submitted\n onInvalid={composeEventHandlers(props.onInvalid, (event) => {\n const firstInvalidControl = getFirstInvalidControl(event.currentTarget);\n if (firstInvalidControl === event.target) firstInvalidControl.focus();\n\n // prevent default browser UI for form validation\n event.preventDefault();\n })}\n // clear server errors when the form is re-submitted\n onSubmit={composeEventHandlers(props.onSubmit, onClearServerErrors, {\n checkForDefaultPrevented: false,\n })}\n // clear server errors when the form is reset\n onReset={composeEventHandlers(props.onReset, onClearServerErrors)}\n />\n </AriaDescriptionProvider>\n </ValidationProvider>\n );\n }\n);\n\nForm.displayName = FORM_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormField\n * -----------------------------------------------------------------------------------------------*/\n\nconst FIELD_NAME = 'FormField';\n\ntype FormFieldContextValue = {\n id: string;\n name: string;\n serverInvalid: boolean;\n};\nconst [FormFieldProvider, useFormFieldContext] =\n createFormContext<FormFieldContextValue>(FIELD_NAME);\n\ntype FormFieldElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface FormFieldProps extends PrimitiveDivProps {\n name: string;\n serverInvalid?: boolean;\n}\n\nconst FormField = React.forwardRef<FormFieldElement, FormFieldProps>(\n (props: ScopedProps<FormFieldProps>, forwardedRef) => {\n const { __scopeForm, name, serverInvalid = false, ...fieldProps } = props;\n const validationContext = useValidationContext(FIELD_NAME, __scopeForm);\n const validity = validationContext.getFieldValidity(name);\n const id = useId();\n\n return (\n <FormFieldProvider scope={__scopeForm} id={id} name={name} serverInvalid={serverInvalid}>\n <Primitive.div\n data-valid={getValidAttribute(validity, serverInvalid)}\n data-invalid={getInvalidAttribute(validity, serverInvalid)}\n {...fieldProps}\n ref={forwardedRef}\n />\n </FormFieldProvider>\n );\n }\n);\n\nFormField.displayName = FIELD_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormLabel\n * -----------------------------------------------------------------------------------------------*/\n\nconst LABEL_NAME = 'FormLabel';\n\ntype FormLabelElement = React.ElementRef<typeof LabelPrimitive>;\ntype LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive>;\ninterface FormLabelProps extends LabelProps {}\n\nconst FormLabel = React.forwardRef<FormLabelElement, FormLabelProps>(\n (props: ScopedProps<FormLabelProps>, forwardedRef) => {\n const { __scopeForm, ...labelProps } = props;\n const validationContext = useValidationContext(LABEL_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(LABEL_NAME, __scopeForm);\n const htmlFor = labelProps.htmlFor || fieldContext.id;\n const validity = validationContext.getFieldValidity(fieldContext.name);\n\n return (\n <LabelPrimitive\n data-valid={getValidAttribute(validity, fieldContext.serverInvalid)}\n data-invalid={getInvalidAttribute(validity, fieldContext.serverInvalid)}\n {...labelProps}\n ref={forwardedRef}\n htmlFor={htmlFor}\n />\n );\n }\n);\n\nFormLabel.displayName = LABEL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormControl\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTROL_NAME = 'FormControl';\n\ntype FormControlElement = React.ElementRef<typeof Primitive.input>;\ntype PrimitiveInputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;\ninterface FormControlProps extends PrimitiveInputProps {}\n\nconst FormControl = React.forwardRef<FormControlElement, FormControlProps>(\n (props: ScopedProps<FormControlProps>, forwardedRef) => {\n const { __scopeForm, ...controlProps } = props;\n\n const validationContext = useValidationContext(CONTROL_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(CONTROL_NAME, __scopeForm);\n const ariaDescriptionContext = useAriaDescriptionContext(CONTROL_NAME, __scopeForm);\n\n const ref = React.useRef<FormControlElement>(null);\n const composedRef = useComposedRefs(forwardedRef, ref);\n const name = controlProps.name || fieldContext.name;\n const id = controlProps.id || fieldContext.id;\n const customMatcherEntries = validationContext.getFieldCustomMatcherEntries(name);\n\n const { onFieldValidityChange, onFieldCustomErrorsChange, onFieldValiditionClear } =\n validationContext;\n const updateControlValidity = React.useCallback(\n async (control: FormControlElement) => {\n //------------------------------------------------------------------------------------------\n // 1. first, if we have built-in errors we stop here\n\n if (hasBuiltInError(control.validity)) {\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n return;\n }\n\n //------------------------------------------------------------------------------------------\n // 2. then gather the form data to give to custom matchers for cross-comparisons\n\n const formData = control.form ? new FormData(control.form) : new FormData();\n const matcherArgs: CustomMatcherArgs = [control.value, formData];\n\n //------------------------------------------------------------------------------------------\n // 3. split sync and async custom matcher entries\n\n const syncCustomMatcherEntries: Array<SyncCustomMatcherEntry> = [];\n const ayncCustomMatcherEntries: Array<AsyncCustomMatcherEntry> = [];\n customMatcherEntries.forEach((customMatcherEntry) => {\n if (isAsyncCustomMatcherEntry(customMatcherEntry, matcherArgs)) {\n ayncCustomMatcherEntries.push(customMatcherEntry);\n } else if (isSyncCustomMatcherEntry(customMatcherEntry)) {\n syncCustomMatcherEntries.push(customMatcherEntry);\n }\n });\n\n //------------------------------------------------------------------------------------------\n // 4. run sync custom matchers and update control validity / internal validity + errors\n\n const syncCustomErrors = syncCustomMatcherEntries.map(({ id, match }) => {\n return [id, match(...matcherArgs)] as const;\n });\n const syncCustomErrorsById = Object.fromEntries(syncCustomErrors);\n const hasSyncCustomErrors = Object.values(syncCustomErrorsById).some(Boolean);\n const hasCustomError = hasSyncCustomErrors;\n control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : '');\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n onFieldCustomErrorsChange(name, syncCustomErrorsById);\n\n //------------------------------------------------------------------------------------------\n // 5. run async custom matchers and update control validity / internal validity + errors\n\n if (!hasSyncCustomErrors && ayncCustomMatcherEntries.length > 0) {\n const promisedCustomErrors = ayncCustomMatcherEntries.map(({ id, match }) =>\n match(...matcherArgs).then((matches) => [id, matches] as const)\n );\n const asyncCustomErrors = await Promise.all(promisedCustomErrors);\n const asyncCustomErrorsById = Object.fromEntries(asyncCustomErrors);\n const hasAsyncCustomErrors = Object.values(asyncCustomErrorsById).some(Boolean);\n const hasCustomError = hasAsyncCustomErrors;\n control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : '');\n const controlValidity = validityStateToObject(control.validity);\n onFieldValidityChange(name, controlValidity);\n onFieldCustomErrorsChange(name, asyncCustomErrorsById);\n }\n },\n [customMatcherEntries, name, onFieldCustomErrorsChange, onFieldValidityChange]\n );\n\n React.useEffect(() => {\n const control = ref.current;\n if (control) {\n // We only want validate on change (native `change` event, not React's `onChange`). This is primarily\n // a UX decision, we don't want to validate on every keystroke and React's `onChange` is the `input` event.\n const handleChange = () => updateControlValidity(control);\n control.addEventListener('change', handleChange);\n return () => control.removeEventListener('change', handleChange);\n }\n }, [updateControlValidity]);\n\n const resetControlValidity = React.useCallback(() => {\n const control = ref.current;\n if (control) {\n control.setCustomValidity('');\n onFieldValiditionClear(name);\n }\n }, [name, onFieldValiditionClear]);\n\n // reset validity and errors when the form is reset\n React.useEffect(() => {\n const form = ref.current?.form;\n if (form) {\n form.addEventListener('reset', resetControlValidity);\n return () => form.removeEventListener('reset', resetControlValidity);\n }\n }, [resetControlValidity]);\n\n // focus first invalid control when fields are set as invalid by server\n React.useEffect(() => {\n const control = ref.current;\n const form = control?.closest('form');\n if (form && fieldContext.serverInvalid) {\n const firstInvalidControl = getFirstInvalidControl(form);\n if (firstInvalidControl === control) firstInvalidControl.focus();\n }\n }, [fieldContext.serverInvalid]);\n\n const validity = validationContext.getFieldValidity(name);\n\n return (\n <Primitive.input\n data-valid={getValidAttribute(validity, fieldContext.serverInvalid)}\n data-invalid={getInvalidAttribute(validity, fieldContext.serverInvalid)}\n aria-invalid={fieldContext.serverInvalid ? true : undefined}\n aria-describedby={ariaDescriptionContext.getFieldDescription(name)}\n // disable default browser behaviour of showing built-in error message on hover\n title=\"\"\n {...controlProps}\n ref={composedRef}\n id={id}\n name={name}\n onInvalid={composeEventHandlers(props.onInvalid, (event) => {\n const control = event.currentTarget;\n updateControlValidity(control);\n })}\n onChange={composeEventHandlers(props.onChange, (event) => {\n // reset validity when user changes value\n resetControlValidity();\n })}\n />\n );\n }\n);\n\nFormControl.displayName = CONTROL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormMessage\n * -----------------------------------------------------------------------------------------------*/\n\nconst validityMatchers = [\n 'badInput',\n 'patternMismatch',\n 'rangeOverflow',\n 'rangeUnderflow',\n 'stepMismatch',\n 'tooLong',\n 'tooShort',\n 'typeMismatch',\n 'valid',\n 'valueMissing',\n] as const;\ntype ValidityMatcher = (typeof validityMatchers)[number];\n\nconst DEFAULT_INVALID_MESSAGE = 'This value is not valid';\nconst DEFAULT_BUILT_IN_MESSAGES: Record<ValidityMatcher, string | undefined> = {\n badInput: DEFAULT_INVALID_MESSAGE,\n patternMismatch: 'This value does not match the required pattern',\n rangeOverflow: 'This value is too large',\n rangeUnderflow: 'This value is too small',\n stepMismatch: 'This value does not match the required step',\n tooLong: 'This value is too long',\n tooShort: 'This value is too short',\n typeMismatch: 'This value does not match the required type',\n valid: undefined,\n valueMissing: 'This value is missing',\n};\n\nconst MESSAGE_NAME = 'FormMessage';\n\ntype FormMessageElement = FormMessageImplElement;\ninterface FormMessageProps extends Omit<FormMessageImplProps, 'name'> {\n match?: ValidityMatcher | CustomMatcher;\n forceMatch?: boolean;\n name?: string;\n}\n\nconst FormMessage = React.forwardRef<FormMessageElement, FormMessageProps>(\n (props: ScopedProps<FormMessageProps>, forwardedRef) => {\n const { match, name: nameProp, ...messageProps } = props;\n const fieldContext = useFormFieldContext(MESSAGE_NAME, props.__scopeForm);\n const name = nameProp ?? fieldContext.name;\n\n if (match === undefined) {\n return (\n <FormMessageImpl {...messageProps} ref={forwardedRef} name={name}>\n {props.children || DEFAULT_INVALID_MESSAGE}\n </FormMessageImpl>\n );\n } else if (typeof match === 'function') {\n return <FormCustomMessage match={match} {...messageProps} ref={forwardedRef} name={name} />;\n } else {\n return <FormBuiltInMessage match={match} {...messageProps} ref={forwardedRef} name={name} />;\n }\n }\n);\n\nFormMessage.displayName = MESSAGE_NAME;\n\ntype FormBuiltInMessageElement = FormMessageImplElement;\ninterface FormBuiltInMessageProps extends FormMessageImplProps {\n match: ValidityMatcher;\n forceMatch?: boolean;\n name: string;\n}\n\nconst FormBuiltInMessage = React.forwardRef<FormBuiltInMessageElement, FormBuiltInMessageProps>(\n (props: ScopedProps<FormBuiltInMessageProps>, forwardedRef) => {\n const { match, forceMatch = false, name, children, ...messageProps } = props;\n const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);\n const validity = validationContext.getFieldValidity(name);\n const matches = forceMatch || validity?.[match];\n\n if (matches) {\n return (\n <FormMessageImpl ref={forwardedRef} {...messageProps} name={name}>\n {children ?? DEFAULT_BUILT_IN_MESSAGES[match]}\n </FormMessageImpl>\n );\n }\n\n return null;\n }\n);\n\ntype FormCustomMessageElement = React.ElementRef<typeof FormMessageImpl>;\ninterface FormCustomMessageProps extends React.ComponentPropsWithoutRef<typeof FormMessageImpl> {\n match: CustomMatcher;\n forceMatch?: boolean;\n name: string;\n}\n\nconst FormCustomMessage = React.forwardRef<FormCustomMessageElement, FormCustomMessageProps>(\n (props: ScopedProps<FormCustomMessageProps>, forwardedRef) => {\n const { match, forceMatch = false, name, id: idProp, children, ...messageProps } = props;\n const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);\n const ref = React.useRef<FormCustomMessageElement>(null);\n const composedRef = useComposedRefs(forwardedRef, ref);\n const _id = useId();\n const id = idProp ?? _id;\n\n const customMatcherEntry = React.useMemo(() => ({ id, match }), [id, match]);\n const { onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove } = validationContext;\n React.useEffect(() => {\n onFieldCustomMatcherEntryAdd(name, customMatcherEntry);\n return () => onFieldCustomMatcherEntryRemove(name, customMatcherEntry.id);\n }, [customMatcherEntry, name, onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove]);\n\n const validity = validationContext.getFieldValidity(name);\n const customErrors = validationContext.getFieldCustomErrors(name);\n const hasMatchingCustomError = customErrors[id];\n const matches =\n forceMatch || (validity && !hasBuiltInError(validity) && hasMatchingCustomError);\n\n if (matches) {\n return (\n <FormMessageImpl id={id} ref={composedRef} {...messageProps} name={name}>\n {children ?? DEFAULT_INVALID_MESSAGE}\n </FormMessageImpl>\n );\n }\n\n return null;\n }\n);\n\ntype FormMessageImplElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface FormMessageImplProps extends PrimitiveSpanProps {\n name: string;\n}\n\nconst FormMessageImpl = React.forwardRef<FormMessageImplElement, FormMessageImplProps>(\n (props: ScopedProps<FormMessageImplProps>, forwardedRef) => {\n const { __scopeForm, id: idProp, name, ...messageProps } = props;\n const ariaDescriptionContext = useAriaDescriptionContext(MESSAGE_NAME, __scopeForm);\n const _id = useId();\n const id = idProp ?? _id;\n\n const { onFieldMessageIdAdd, onFieldMessageIdRemove } = ariaDescriptionContext;\n React.useEffect(() => {\n onFieldMessageIdAdd(name, id);\n return () => onFieldMessageIdRemove(name, id);\n }, [name, id, onFieldMessageIdAdd, onFieldMessageIdRemove]);\n\n return <Primitive.span id={id} {...messageProps} ref={forwardedRef} />;\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * FormValidityState\n * -----------------------------------------------------------------------------------------------*/\n\nconst VALIDITY_STATE_NAME = 'FormValidityState';\n\ninterface FormValidityStateProps {\n children(validity: ValidityState | undefined): React.ReactNode;\n name?: string;\n}\n\nconst FormValidityState = (props: ScopedProps<FormValidityStateProps>) => {\n const { __scopeForm, name: nameProp, children } = props;\n const validationContext = useValidationContext(VALIDITY_STATE_NAME, __scopeForm);\n const fieldContext = useFormFieldContext(VALIDITY_STATE_NAME, __scopeForm);\n const name = nameProp ?? fieldContext.name;\n const validity = validationContext.getFieldValidity(name);\n return <>{children(validity)}</>;\n};\n\nFormValidityState.displayName = VALIDITY_STATE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * FormSubmit\n * -----------------------------------------------------------------------------------------------*/\n\nconst SUBMIT_NAME = 'FormSubmit';\n\ntype FormSubmitElement = React.ElementRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;\ninterface FormSubmitProps extends PrimitiveButtonProps {}\n\nconst FormSubmit = React.forwardRef<FormSubmitElement, FormSubmitProps>(\n (props: ScopedProps<FormSubmitProps>, forwardedRef) => {\n const { __scopeForm, ...submitProps } = props;\n return <Primitive.button type=\"submit\" {...submitProps} ref={forwardedRef} />;\n }\n);\n\nFormSubmit.displayName = SUBMIT_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype ValidityStateKey = keyof ValidityState;\ntype SyncCustomMatcher = (value: string, formData: FormData) => boolean;\ntype AsyncCustomMatcher = (value: string, formData: FormData) => Promise<boolean>;\ntype CustomMatcher = SyncCustomMatcher | AsyncCustomMatcher;\ntype CustomMatcherEntry = { id: string; match: CustomMatcher };\ntype SyncCustomMatcherEntry = { id: string; match: SyncCustomMatcher };\ntype AsyncCustomMatcherEntry = { id: string; match: AsyncCustomMatcher };\ntype CustomMatcherArgs = [string, FormData];\n\nfunction validityStateToObject(validity: ValidityState) {\n const object: any = {};\n for (const key in validity) {\n object[key] = validity[key as ValidityStateKey];\n }\n return object as Record<ValidityStateKey, boolean>;\n}\n\nfunction isHTMLElement(element: any): element is HTMLElement {\n return element instanceof HTMLElement;\n}\n\nfunction isFormControl(element: any): element is { validity: ValidityState } {\n return 'validity' in element;\n}\n\nfunction isInvalid(control: HTMLElement) {\n return (\n isFormControl(control) &&\n (control.validity.valid === false || control.getAttribute('aria-invalid') === 'true')\n );\n}\n\nfunction getFirstInvalidControl(form: HTMLFormElement): HTMLElement | undefined {\n const elements = form.elements;\n const [firstInvalidControl] = Array.from(elements).filter(isHTMLElement).filter(isInvalid);\n return firstInvalidControl;\n}\n\nfunction isAsyncCustomMatcherEntry(\n entry: CustomMatcherEntry,\n args: CustomMatcherArgs\n): entry is AsyncCustomMatcherEntry {\n return entry.match.constructor.name === 'AsyncFunction' || returnsPromise(entry.match, args);\n}\n\nfunction isSyncCustomMatcherEntry(entry: CustomMatcherEntry): entry is SyncCustomMatcherEntry {\n return entry.match.constructor.name === 'Function';\n}\n\nfunction returnsPromise(func: Function, args: Array<unknown>) {\n return func(...args) instanceof Promise;\n}\n\nfunction hasBuiltInError(validity: ValidityState) {\n let error = false;\n for (const validityKey in validity) {\n const key = validityKey as ValidityStateKey;\n if (key !== 'valid' && key !== 'customError' && validity[key]) {\n error = true;\n break;\n }\n }\n return error;\n}\n\nfunction getValidAttribute(validity: ValidityState | undefined, serverInvalid: boolean) {\n if (validity?.valid === true && !serverInvalid) return true;\n return undefined;\n}\nfunction getInvalidAttribute(validity: ValidityState | undefined, serverInvalid: boolean) {\n if (validity?.valid === false || serverInvalid) return true;\n return undefined;\n}\n\n/* -----------------------------------------------------------------------------------------------*/\n\nconst Root = Form;\nconst Field = FormField;\nconst Label = FormLabel;\nconst Control = FormControl;\nconst Message = FormMessage;\nconst ValidityState = FormValidityState;\nconst Submit = FormSubmit;\n\nexport {\n createFormScope,\n //\n Form,\n FormField,\n FormLabel,\n FormControl,\n FormMessage,\n FormValidityState,\n FormSubmit,\n //\n Root,\n Field,\n Label,\n Control,\n Message,\n ValidityState,\n Submit,\n};\n\nexport type {\n FormProps,\n FormFieldProps,\n FormLabelProps,\n FormControlProps,\n FormMessageProps,\n FormValidityStateProps,\n FormSubmitProps,\n};\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["controlValidity", "id", "hasCustomError"]
|
7
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@huin-core/react-form",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.3",
|
4
4
|
"license": "MIT",
|
5
5
|
"exports": {
|
6
6
|
".": {
|
@@ -28,12 +28,12 @@
|
|
28
28
|
"version": "yarn version"
|
29
29
|
},
|
30
30
|
"dependencies": {
|
31
|
-
"@huin-core/primitive": "
|
32
|
-
"@huin-core/react-compose-refs": "
|
33
|
-
"@huin-core/react-context": "
|
34
|
-
"@huin-core/react-id": "
|
35
|
-
"@huin-core/react-label": "
|
36
|
-
"@huin-core/react-primitive": "
|
31
|
+
"@huin-core/primitive": "latest",
|
32
|
+
"@huin-core/react-compose-refs": "latest",
|
33
|
+
"@huin-core/react-context": "latest",
|
34
|
+
"@huin-core/react-id": "latest",
|
35
|
+
"@huin-core/react-label": "latest",
|
36
|
+
"@huin-core/react-primitive": "latest"
|
37
37
|
},
|
38
38
|
"peerDependencies": {
|
39
39
|
"@types/react": "*",
|