@conform-to/react 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README +1 -1
- package/context.d.ts +12 -9
- package/helpers.d.ts +9 -9
- package/helpers.js +8 -6
- package/helpers.mjs +8 -6
- package/hooks.d.ts +1 -1
- package/hooks.js +2 -0
- package/hooks.mjs +2 -0
- package/index.d.ts +1 -1
- package/index.js +2 -0
- package/index.mjs +1 -1
- package/integrations.d.ts +38 -12
- package/integrations.js +116 -52
- package/integrations.mjs +114 -54
- package/package.json +6 -4
package/README
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
Version 1.0.
|
|
11
|
+
Version 1.0.3 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
12
|
|
|
13
13
|
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
|
|
14
14
|
|
package/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Constraint, type FormId, type FieldName, type FormContext as BaseFormContext, type FormValue, type FormState, type Intent, type SubscriptionScope, type SubscriptionSubject, type
|
|
1
|
+
import { type Constraint, type Combine, type FormId, type FieldName, type FormContext as BaseFormContext, type FormValue, type FormState, type Intent, type SubscriptionScope, type SubscriptionSubject, type FormOptions as BaseFormOptions } from '@conform-to/dom';
|
|
2
2
|
import { type FormEvent, type ReactElement, type ReactNode, type MutableRefObject } from 'react';
|
|
3
3
|
export type Pretty<T> = {
|
|
4
4
|
[K in keyof T]: T[K];
|
|
@@ -21,19 +21,22 @@ export type FormMetadata<Schema extends Record<string, unknown> = Record<string,
|
|
|
21
21
|
id: FormId<Schema, FormError>;
|
|
22
22
|
context: Wrapped<FormContext<Schema, FormError>>;
|
|
23
23
|
status?: 'success' | 'error';
|
|
24
|
-
getFieldset: () => {
|
|
25
|
-
[Key in
|
|
26
|
-
}
|
|
24
|
+
getFieldset: () => Required<{
|
|
25
|
+
[Key in keyof Combine<Schema>]: FieldMetadata<Combine<Schema>[Key], Schema, FormError>;
|
|
26
|
+
}>;
|
|
27
27
|
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
28
28
|
noValidate: boolean;
|
|
29
29
|
};
|
|
30
|
+
type SubfieldMetadata<Schema, FormSchema extends Record<string, any>, FormError> = [Schema] extends [Primitive] ? {} : [Schema] extends [Array<infer Item> | null | undefined] ? {
|
|
31
|
+
getFieldList: () => Array<FieldMetadata<Item, FormSchema, FormError>>;
|
|
32
|
+
} : [Schema] extends [Record<string, any> | null | undefined] ? {
|
|
33
|
+
getFieldset: () => Required<{
|
|
34
|
+
[Key in keyof Combine<Schema>]: FieldMetadata<Combine<Schema>[Key], FormSchema, FormError>;
|
|
35
|
+
}>;
|
|
36
|
+
} : {};
|
|
30
37
|
export type FieldMetadata<Schema = unknown, FormSchema extends Record<string, any> = Record<string, unknown>, FormError = string[]> = Metadata<Schema, FormSchema, FormError> & Constraint & {
|
|
31
38
|
formId: FormId<FormSchema, FormError>;
|
|
32
|
-
|
|
33
|
-
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormSchema, FormError>;
|
|
34
|
-
};
|
|
35
|
-
getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, FormSchema, FormError>> : never;
|
|
36
|
-
};
|
|
39
|
+
} & SubfieldMetadata<Schema, FormSchema, FormError>;
|
|
37
40
|
export declare const Form: import("react").Context<FormContext<any, string[], any>[]>;
|
|
38
41
|
declare const wrappedSymbol: unique symbol;
|
|
39
42
|
export type Wrapped<Type> = {
|
package/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { FormMetadata, FieldMetadata, Metadata, Pretty
|
|
2
|
+
import type { FormMetadata, FieldMetadata, Metadata, Pretty } from './context';
|
|
3
3
|
type FormControlProps = {
|
|
4
4
|
key: string | undefined;
|
|
5
5
|
id: string;
|
|
@@ -125,7 +125,7 @@ export declare function getFormControlProps<Schema>(metadata: FieldMetadata<Sche
|
|
|
125
125
|
* Depends on the provided options, it will also set `defaultChecked` / `checked` if it is a checkbox or radio button,
|
|
126
126
|
* or otherwise `defaultValue` / `value`.
|
|
127
127
|
*
|
|
128
|
-
* @see https://conform.guide/api/react/
|
|
128
|
+
* @see https://conform.guide/api/react/getInputProps
|
|
129
129
|
* @example
|
|
130
130
|
* ```tsx
|
|
131
131
|
* // To setup an uncontrolled input
|
|
@@ -138,14 +138,14 @@ export declare function getFormControlProps<Schema>(metadata: FieldMetadata<Sche
|
|
|
138
138
|
* <input {...getInputProps(metadata, { type: 'radio', value: false })} />
|
|
139
139
|
* ```
|
|
140
140
|
*/
|
|
141
|
-
export declare function getInputProps<Schema
|
|
141
|
+
export declare function getInputProps<Schema>(metadata: FieldMetadata<Schema, any, any>, options: InputOptions): InputProps;
|
|
142
142
|
/**
|
|
143
143
|
* Derives the properties of a select element based on the field metadata,
|
|
144
144
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
|
|
145
145
|
* and constraint attributes such as `required` or `multiple`.
|
|
146
146
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
147
147
|
*
|
|
148
|
-
* @see https://conform.guide/api/react/
|
|
148
|
+
* @see https://conform.guide/api/react/getSelectProps
|
|
149
149
|
* @example
|
|
150
150
|
* ```tsx
|
|
151
151
|
* // To setup an uncontrolled select
|
|
@@ -154,14 +154,14 @@ export declare function getInputProps<Schema extends Primitive | File[]>(metadat
|
|
|
154
154
|
* <select {...getSelectProps(metadata, { value: false })} />
|
|
155
155
|
* ```
|
|
156
156
|
*/
|
|
157
|
-
export declare function getSelectProps<Schema
|
|
157
|
+
export declare function getSelectProps<Schema>(metadata: FieldMetadata<Schema, any, any>, options?: SelectOptions): SelectProps;
|
|
158
158
|
/**
|
|
159
159
|
* Derives the properties of a textarea element based on the field metadata,
|
|
160
160
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
|
|
161
161
|
* and constraint attributes such as `required`, `minLength` or `maxLength`.
|
|
162
162
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
163
163
|
*
|
|
164
|
-
* @see https://conform.guide/api/react/
|
|
164
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
165
165
|
* @example
|
|
166
166
|
* ```tsx
|
|
167
167
|
* // To setup an uncontrolled textarea
|
|
@@ -170,12 +170,12 @@ export declare function getSelectProps<Schema extends Exclude<Primitive, File> |
|
|
|
170
170
|
* <textarea {...getTextareaProps(metadata, { value: false })} />
|
|
171
171
|
* ```
|
|
172
172
|
*/
|
|
173
|
-
export declare function getTextareaProps<Schema
|
|
173
|
+
export declare function getTextareaProps<Schema>(metadata: FieldMetadata<Schema, any, any>, options?: TextareaOptions): TextareaProps;
|
|
174
174
|
/**
|
|
175
175
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
176
176
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
177
177
|
*
|
|
178
|
-
* @see https://conform.guide/api/react/
|
|
178
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
179
179
|
* @example
|
|
180
180
|
* ```tsx
|
|
181
181
|
* <fieldset>
|
|
@@ -201,7 +201,7 @@ export declare function getCollectionProps<Schema extends Array<string | boolean
|
|
|
201
201
|
*/
|
|
202
202
|
options: string[];
|
|
203
203
|
/**
|
|
204
|
-
* Decide whether defaultValue should be returned. Pass `false` if you want to
|
|
204
|
+
* Decide whether defaultValue should be returned. Pass `false` if you want to manage the value yourself.
|
|
205
205
|
*/
|
|
206
206
|
value?: boolean;
|
|
207
207
|
}>): Array<InputProps & Pick<Required<InputProps>, 'type' | 'value'>>;
|
package/helpers.js
CHANGED
|
@@ -85,7 +85,7 @@ function getFormControlProps(metadata, options) {
|
|
|
85
85
|
* Depends on the provided options, it will also set `defaultChecked` / `checked` if it is a checkbox or radio button,
|
|
86
86
|
* or otherwise `defaultValue` / `value`.
|
|
87
87
|
*
|
|
88
|
-
* @see https://conform.guide/api/react/
|
|
88
|
+
* @see https://conform.guide/api/react/getInputProps
|
|
89
89
|
* @example
|
|
90
90
|
* ```tsx
|
|
91
91
|
* // To setup an uncontrolled input
|
|
@@ -126,7 +126,7 @@ function getInputProps(metadata, options) {
|
|
|
126
126
|
* and constraint attributes such as `required` or `multiple`.
|
|
127
127
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
128
128
|
*
|
|
129
|
-
* @see https://conform.guide/api/react/
|
|
129
|
+
* @see https://conform.guide/api/react/getSelectProps
|
|
130
130
|
* @example
|
|
131
131
|
* ```tsx
|
|
132
132
|
* // To setup an uncontrolled select
|
|
@@ -141,7 +141,8 @@ function getSelectProps(metadata) {
|
|
|
141
141
|
multiple: metadata.multiple
|
|
142
142
|
});
|
|
143
143
|
if (typeof options.value === 'undefined' || options.value) {
|
|
144
|
-
|
|
144
|
+
var _metadata$initialValu;
|
|
145
|
+
props.defaultValue = Array.isArray(metadata.initialValue) ? metadata.initialValue.map(item => "".concat(item !== null && item !== void 0 ? item : '')) : (_metadata$initialValu = metadata.initialValue) === null || _metadata$initialValu === void 0 ? void 0 : _metadata$initialValu.toString();
|
|
145
146
|
}
|
|
146
147
|
return simplify(props);
|
|
147
148
|
}
|
|
@@ -152,7 +153,7 @@ function getSelectProps(metadata) {
|
|
|
152
153
|
* and constraint attributes such as `required`, `minLength` or `maxLength`.
|
|
153
154
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
154
155
|
*
|
|
155
|
-
* @see https://conform.guide/api/react/
|
|
156
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
156
157
|
* @example
|
|
157
158
|
* ```tsx
|
|
158
159
|
* // To setup an uncontrolled textarea
|
|
@@ -168,7 +169,8 @@ function getTextareaProps(metadata) {
|
|
|
168
169
|
maxLength: metadata.maxLength
|
|
169
170
|
});
|
|
170
171
|
if (typeof options.value === 'undefined' || options.value) {
|
|
171
|
-
|
|
172
|
+
var _metadata$initialValu2;
|
|
173
|
+
props.defaultValue = (_metadata$initialValu2 = metadata.initialValue) === null || _metadata$initialValu2 === void 0 ? void 0 : _metadata$initialValu2.toString();
|
|
172
174
|
}
|
|
173
175
|
return simplify(props);
|
|
174
176
|
}
|
|
@@ -177,7 +179,7 @@ function getTextareaProps(metadata) {
|
|
|
177
179
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
178
180
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
179
181
|
*
|
|
180
|
-
* @see https://conform.guide/api/react/
|
|
182
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
181
183
|
* @example
|
|
182
184
|
* ```tsx
|
|
183
185
|
* <fieldset>
|
package/helpers.mjs
CHANGED
|
@@ -81,7 +81,7 @@ function getFormControlProps(metadata, options) {
|
|
|
81
81
|
* Depends on the provided options, it will also set `defaultChecked` / `checked` if it is a checkbox or radio button,
|
|
82
82
|
* or otherwise `defaultValue` / `value`.
|
|
83
83
|
*
|
|
84
|
-
* @see https://conform.guide/api/react/
|
|
84
|
+
* @see https://conform.guide/api/react/getInputProps
|
|
85
85
|
* @example
|
|
86
86
|
* ```tsx
|
|
87
87
|
* // To setup an uncontrolled input
|
|
@@ -122,7 +122,7 @@ function getInputProps(metadata, options) {
|
|
|
122
122
|
* and constraint attributes such as `required` or `multiple`.
|
|
123
123
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
124
124
|
*
|
|
125
|
-
* @see https://conform.guide/api/react/
|
|
125
|
+
* @see https://conform.guide/api/react/getSelectProps
|
|
126
126
|
* @example
|
|
127
127
|
* ```tsx
|
|
128
128
|
* // To setup an uncontrolled select
|
|
@@ -137,7 +137,8 @@ function getSelectProps(metadata) {
|
|
|
137
137
|
multiple: metadata.multiple
|
|
138
138
|
});
|
|
139
139
|
if (typeof options.value === 'undefined' || options.value) {
|
|
140
|
-
|
|
140
|
+
var _metadata$initialValu;
|
|
141
|
+
props.defaultValue = Array.isArray(metadata.initialValue) ? metadata.initialValue.map(item => "".concat(item !== null && item !== void 0 ? item : '')) : (_metadata$initialValu = metadata.initialValue) === null || _metadata$initialValu === void 0 ? void 0 : _metadata$initialValu.toString();
|
|
141
142
|
}
|
|
142
143
|
return simplify(props);
|
|
143
144
|
}
|
|
@@ -148,7 +149,7 @@ function getSelectProps(metadata) {
|
|
|
148
149
|
* and constraint attributes such as `required`, `minLength` or `maxLength`.
|
|
149
150
|
* Depends on the provided options, it will also set `defaultValue` / `value`.
|
|
150
151
|
*
|
|
151
|
-
* @see https://conform.guide/api/react/
|
|
152
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
152
153
|
* @example
|
|
153
154
|
* ```tsx
|
|
154
155
|
* // To setup an uncontrolled textarea
|
|
@@ -164,7 +165,8 @@ function getTextareaProps(metadata) {
|
|
|
164
165
|
maxLength: metadata.maxLength
|
|
165
166
|
});
|
|
166
167
|
if (typeof options.value === 'undefined' || options.value) {
|
|
167
|
-
|
|
168
|
+
var _metadata$initialValu2;
|
|
169
|
+
props.defaultValue = (_metadata$initialValu2 = metadata.initialValue) === null || _metadata$initialValu2 === void 0 ? void 0 : _metadata$initialValu2.toString();
|
|
168
170
|
}
|
|
169
171
|
return simplify(props);
|
|
170
172
|
}
|
|
@@ -173,7 +175,7 @@ function getTextareaProps(metadata) {
|
|
|
173
175
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
174
176
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
175
177
|
*
|
|
176
|
-
* @see https://conform.guide/api/react/
|
|
178
|
+
* @see https://conform.guide/api/react/getTextareaProps
|
|
177
179
|
* @example
|
|
178
180
|
* ```tsx
|
|
179
181
|
* <fieldset>
|
package/hooks.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { type FormMetadata, type FieldMetadata, type Pretty, type FormOptions }
|
|
|
8
8
|
export declare const useSafeLayoutEffect: typeof useEffect;
|
|
9
9
|
export declare function useFormId<Schema extends Record<string, unknown>, FormError>(preferredId?: string): FormId<Schema, FormError>;
|
|
10
10
|
export declare function useNoValidate(defaultNoValidate?: boolean): boolean;
|
|
11
|
-
export declare function useForm<Schema extends Record<string, any>, FormValue = Schema, FormError = string[]>(options: Pretty<Omit<FormOptions<Schema, FormError, FormValue>, 'formId'> & {
|
|
11
|
+
export declare function useForm<Schema extends Record<string, any>, FormValue = Schema, FormError = string[]>(options: Pretty<Omit<FormOptions<Schema, FormError, FormValue>, 'formId' | 'onSchedule'> & {
|
|
12
12
|
/**
|
|
13
13
|
* The form id. If not provided, a random id will be generated.
|
|
14
14
|
*/
|
package/hooks.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
|
|
6
6
|
var react = require('react');
|
|
7
|
+
var reactDom = require('react-dom');
|
|
7
8
|
var context = require('./context.js');
|
|
8
9
|
|
|
9
10
|
var _excluded = ["id"];
|
|
@@ -37,6 +38,7 @@ function useForm(options) {
|
|
|
37
38
|
formConfig = _rollupPluginBabelHelpers.objectWithoutProperties(options, _excluded);
|
|
38
39
|
var formId = useFormId(id);
|
|
39
40
|
var [context$1] = react.useState(() => context.createFormContext(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
|
|
41
|
+
onSchedule: callback => reactDom.flushSync(callback),
|
|
40
42
|
formId
|
|
41
43
|
})));
|
|
42
44
|
useSafeLayoutEffect(() => {
|
package/hooks.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
2
|
import { useState, useEffect, useLayoutEffect, useId } from 'react';
|
|
3
|
+
import { flushSync } from 'react-dom';
|
|
3
4
|
import { createFormContext, useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
|
|
4
5
|
|
|
5
6
|
var _excluded = ["id"];
|
|
@@ -33,6 +34,7 @@ function useForm(options) {
|
|
|
33
34
|
formConfig = _objectWithoutProperties(options, _excluded);
|
|
34
35
|
var formId = useFormId(id);
|
|
35
36
|
var [context] = useState(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
|
|
37
|
+
onSchedule: callback => flushSync(callback),
|
|
36
38
|
formId
|
|
37
39
|
})));
|
|
38
40
|
useSafeLayoutEffect(() => {
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { type Submission, type SubmissionResult, type DefaultValue, type Intent, type FormId, type FieldName, parse, } from '@conform-to/dom';
|
|
2
2
|
export { type FieldMetadata, type FormMetadata, FormProvider, FormStateInput, } from './context';
|
|
3
3
|
export { useForm, useFormMetadata, useField } from './hooks';
|
|
4
|
-
export { useInputControl } from './integrations';
|
|
4
|
+
export { Control as unstable_Control, useControl as unstable_useControl, useInputControl, } from './integrations';
|
|
5
5
|
export { getFormProps, getFieldsetProps, getInputProps, getSelectProps, getTextareaProps, getCollectionProps, } from './helpers';
|
package/index.js
CHANGED
|
@@ -19,6 +19,8 @@ exports.FormStateInput = context.FormStateInput;
|
|
|
19
19
|
exports.useField = hooks.useField;
|
|
20
20
|
exports.useForm = hooks.useForm;
|
|
21
21
|
exports.useFormMetadata = hooks.useFormMetadata;
|
|
22
|
+
exports.unstable_Control = integrations.Control;
|
|
23
|
+
exports.unstable_useControl = integrations.useControl;
|
|
22
24
|
exports.useInputControl = integrations.useInputControl;
|
|
23
25
|
exports.getCollectionProps = helpers.getCollectionProps;
|
|
24
26
|
exports.getFieldsetProps = helpers.getFieldsetProps;
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { parse } from '@conform-to/dom';
|
|
2
2
|
export { FormProvider, FormStateInput } from './context.mjs';
|
|
3
3
|
export { useField, useForm, useFormMetadata } from './hooks.mjs';
|
|
4
|
-
export { useInputControl } from './integrations.mjs';
|
|
4
|
+
export { Control as unstable_Control, useControl as unstable_useControl, useInputControl } from './integrations.mjs';
|
|
5
5
|
export { getCollectionProps, getFieldsetProps, getFormProps, getInputProps, getSelectProps, getTextareaProps } from './helpers.mjs';
|
package/integrations.d.ts
CHANGED
|
@@ -1,19 +1,45 @@
|
|
|
1
|
-
import { type Key } from 'react';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
focus: () => void;
|
|
6
|
-
blur: () => void;
|
|
7
|
-
};
|
|
8
|
-
export declare function getFormElement(formId: string): HTMLFormElement;
|
|
9
|
-
export declare function getFieldElements(form: HTMLFormElement, name: string): Array<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
|
|
10
|
-
export declare function getEventTarget(form: HTMLFormElement, name: string): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null;
|
|
1
|
+
import { type Key, type RefCallback } from 'react';
|
|
2
|
+
export declare function getFormElement(formId: string): HTMLFormElement | null;
|
|
3
|
+
export declare function getFieldElements(form: HTMLFormElement | null, name: string): Array<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
|
|
4
|
+
export declare function getEventTarget(form: HTMLFormElement | null, name: string, value?: string | string[]): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null;
|
|
11
5
|
export declare function createDummySelect(form: HTMLFormElement, name: string, value?: string | string[] | undefined): HTMLSelectElement;
|
|
12
6
|
export declare function isDummySelect(element: HTMLElement): element is HTMLSelectElement;
|
|
13
7
|
export declare function updateFieldValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, value: string | string[]): void;
|
|
14
|
-
export declare function
|
|
8
|
+
export declare function useInputEvent(): {
|
|
9
|
+
change(value: string | string[]): void;
|
|
10
|
+
focus(): void;
|
|
11
|
+
blur(): void;
|
|
12
|
+
register: RefCallback<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | undefined>;
|
|
13
|
+
};
|
|
14
|
+
export declare function useInputValue<Value extends string | string[] | Array<string | undefined>>(options: {
|
|
15
|
+
key?: Key | null | undefined;
|
|
16
|
+
initialValue?: Value | undefined;
|
|
17
|
+
}): readonly [(Value extends string ? Value : string | string[]) | undefined, import("react").Dispatch<import("react").SetStateAction<(Value extends string ? Value : string | string[]) | undefined>>];
|
|
18
|
+
export declare function useControl<Value extends string | string[] | Array<string | undefined>>(meta: {
|
|
19
|
+
key?: Key | null | undefined;
|
|
20
|
+
initialValue?: Value | undefined;
|
|
21
|
+
}): {
|
|
22
|
+
register: RefCallback<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | undefined>;
|
|
23
|
+
value: (Value extends string ? Value : string | string[]) | undefined;
|
|
24
|
+
change: (value: Value extends string ? Value : string | string[]) => void;
|
|
25
|
+
focus: () => void;
|
|
26
|
+
blur: () => void;
|
|
27
|
+
};
|
|
28
|
+
export declare function useInputControl<Value extends string | string[] | Array<string | undefined>>(meta: {
|
|
15
29
|
key?: Key | null | undefined;
|
|
16
30
|
name: string;
|
|
17
31
|
formId: string;
|
|
18
32
|
initialValue?: Value | undefined;
|
|
19
|
-
}):
|
|
33
|
+
}): {
|
|
34
|
+
value: (Value extends string ? Value : string | string[]) | undefined;
|
|
35
|
+
change: import("react").Dispatch<import("react").SetStateAction<(Value extends string ? Value : string | string[]) | undefined>>;
|
|
36
|
+
focus: () => void;
|
|
37
|
+
blur: () => void;
|
|
38
|
+
};
|
|
39
|
+
export declare function Control<Value extends string | string[] | Array<string | undefined>>(props: {
|
|
40
|
+
meta: {
|
|
41
|
+
key?: Key | null | undefined;
|
|
42
|
+
initialValue?: Value | undefined;
|
|
43
|
+
};
|
|
44
|
+
render: (control: ReturnType<typeof useControl<Value>>) => React.ReactNode;
|
|
45
|
+
}): import("react").ReactNode;
|
package/integrations.js
CHANGED
|
@@ -2,24 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
|
|
6
5
|
var react = require('react');
|
|
7
6
|
|
|
8
7
|
function getFormElement(formId) {
|
|
9
|
-
|
|
10
|
-
if (!element) {
|
|
11
|
-
throw new Error('Form not found');
|
|
12
|
-
}
|
|
13
|
-
return element;
|
|
8
|
+
return document.forms.namedItem(formId);
|
|
14
9
|
}
|
|
15
10
|
function getFieldElements(form, name) {
|
|
16
|
-
var field = form.elements.namedItem(name);
|
|
11
|
+
var field = form === null || form === void 0 ? void 0 : form.elements.namedItem(name);
|
|
17
12
|
var elements = !field ? [] : field instanceof Element ? [field] : Array.from(field.values());
|
|
18
13
|
return elements.filter(element => element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement);
|
|
19
14
|
}
|
|
20
|
-
function getEventTarget(form, name) {
|
|
15
|
+
function getEventTarget(form, name, value) {
|
|
21
16
|
var _elements$;
|
|
22
17
|
var elements = getFieldElements(form, name);
|
|
18
|
+
if (elements.length > 1) {
|
|
19
|
+
var options = typeof value === 'string' ? [value] : value;
|
|
20
|
+
for (var element of elements) {
|
|
21
|
+
if (typeof options !== 'undefined' && element instanceof HTMLInputElement && element.type === 'checkbox' && (element.checked ? options.includes(element.value) : !options.includes(element.value))) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
return element;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
23
27
|
return (_elements$ = elements[0]) !== null && _elements$ !== void 0 ? _elements$ : null;
|
|
24
28
|
}
|
|
25
29
|
function createDummySelect(form, name, value) {
|
|
@@ -52,7 +56,7 @@ function isDummySelect(element) {
|
|
|
52
56
|
}
|
|
53
57
|
function updateFieldValue(element, value) {
|
|
54
58
|
if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
|
|
55
|
-
element.checked = element.value === value;
|
|
59
|
+
element.checked = Array.isArray(value) ? value.includes(element.value) : element.value === value;
|
|
56
60
|
} else if (element instanceof HTMLSelectElement && element.multiple) {
|
|
57
61
|
var selectedValue = Array.isArray(value) ? [...value] : [value];
|
|
58
62
|
for (var option of element.options) {
|
|
@@ -100,44 +104,18 @@ function updateFieldValue(element, value) {
|
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
// as there is no way to skip an entry in a multiple select when they all share the same name
|
|
106
|
-
var inputInitialValue = metaOrOptions.initialValue;
|
|
107
|
+
function useInputEvent() {
|
|
108
|
+
var ref = react.useRef(null);
|
|
107
109
|
var eventDispatched = react.useRef({
|
|
108
110
|
change: false,
|
|
109
111
|
focus: false,
|
|
110
112
|
blur: false
|
|
111
113
|
});
|
|
112
|
-
var [key, setKey] = react.useState(metaOrOptions.key);
|
|
113
|
-
var [initialValue, setInitialValue] = react.useState(inputInitialValue);
|
|
114
|
-
var [value, setValue] = react.useState(inputInitialValue);
|
|
115
|
-
if (key !== metaOrOptions.key) {
|
|
116
|
-
setValue(inputInitialValue);
|
|
117
|
-
setInitialValue(inputInitialValue);
|
|
118
|
-
setKey(metaOrOptions.key);
|
|
119
|
-
}
|
|
120
|
-
react.useEffect(() => {
|
|
121
|
-
var form = getFormElement(metaOrOptions.formId);
|
|
122
|
-
if (getEventTarget(form, metaOrOptions.name)) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
createDummySelect(form, metaOrOptions.name, initialValue);
|
|
126
|
-
return () => {
|
|
127
|
-
var elements = getFieldElements(form, metaOrOptions.name);
|
|
128
|
-
for (var element of elements) {
|
|
129
|
-
if (isDummySelect(element)) {
|
|
130
|
-
element.remove();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}, [metaOrOptions.formId, metaOrOptions.name, initialValue]);
|
|
135
114
|
react.useEffect(() => {
|
|
136
115
|
var createEventListener = listener => {
|
|
137
116
|
return event => {
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
if ((element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) && element.name === metaOrOptions.name && ((_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.id) === metaOrOptions.formId) {
|
|
117
|
+
var element = ref.current;
|
|
118
|
+
if (element && event.target === element) {
|
|
141
119
|
eventDispatched.current[listener] = true;
|
|
142
120
|
}
|
|
143
121
|
};
|
|
@@ -153,14 +131,13 @@ function useInputControl(metaOrOptions) {
|
|
|
153
131
|
document.removeEventListener('focusin', focusHandler, true);
|
|
154
132
|
document.removeEventListener('focusout', blurHandler, true);
|
|
155
133
|
};
|
|
156
|
-
}, [
|
|
157
|
-
|
|
134
|
+
}, [ref]);
|
|
135
|
+
return react.useMemo(() => {
|
|
158
136
|
return {
|
|
159
137
|
change(value) {
|
|
160
138
|
if (!eventDispatched.current.change) {
|
|
161
139
|
eventDispatched.current.change = true;
|
|
162
|
-
var
|
|
163
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
140
|
+
var element = ref.current;
|
|
164
141
|
if (element) {
|
|
165
142
|
updateFieldValue(element, value);
|
|
166
143
|
|
|
@@ -174,14 +151,12 @@ function useInputControl(metaOrOptions) {
|
|
|
174
151
|
}));
|
|
175
152
|
}
|
|
176
153
|
}
|
|
177
|
-
setValue(value);
|
|
178
154
|
eventDispatched.current.change = false;
|
|
179
155
|
},
|
|
180
156
|
focus() {
|
|
181
157
|
if (!eventDispatched.current.focus) {
|
|
182
158
|
eventDispatched.current.focus = true;
|
|
183
|
-
var
|
|
184
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
159
|
+
var element = ref.current;
|
|
185
160
|
if (element) {
|
|
186
161
|
element.dispatchEvent(new FocusEvent('focusin', {
|
|
187
162
|
bubbles: true
|
|
@@ -194,8 +169,7 @@ function useInputControl(metaOrOptions) {
|
|
|
194
169
|
blur() {
|
|
195
170
|
if (!eventDispatched.current.blur) {
|
|
196
171
|
eventDispatched.current.blur = true;
|
|
197
|
-
var
|
|
198
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
172
|
+
var element = ref.current;
|
|
199
173
|
if (element) {
|
|
200
174
|
element.dispatchEvent(new FocusEvent('focusout', {
|
|
201
175
|
bubbles: true
|
|
@@ -204,18 +178,108 @@ function useInputControl(metaOrOptions) {
|
|
|
204
178
|
}
|
|
205
179
|
}
|
|
206
180
|
eventDispatched.current.blur = false;
|
|
181
|
+
},
|
|
182
|
+
register(element) {
|
|
183
|
+
ref.current = element;
|
|
207
184
|
}
|
|
208
185
|
};
|
|
209
|
-
}, [
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
186
|
+
}, []);
|
|
187
|
+
}
|
|
188
|
+
function useInputValue(options) {
|
|
189
|
+
var initializeValue = () => {
|
|
190
|
+
var _options$initialValue;
|
|
191
|
+
if (typeof options.initialValue === 'string') {
|
|
192
|
+
// @ts-expect-error FIXME: To ensure that the type of value is also `string | undefined` if initialValue is not an array
|
|
193
|
+
return options.initialValue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// @ts-expect-error Same as above
|
|
197
|
+
return (_options$initialValue = options.initialValue) === null || _options$initialValue === void 0 ? void 0 : _options$initialValue.map(value => value !== null && value !== void 0 ? value : '');
|
|
198
|
+
};
|
|
199
|
+
var [key, setKey] = react.useState(options.key);
|
|
200
|
+
var [value, setValue] = react.useState(initializeValue);
|
|
201
|
+
if (key !== options.key) {
|
|
202
|
+
setValue(initializeValue);
|
|
203
|
+
setKey(options.key);
|
|
204
|
+
}
|
|
205
|
+
return [value, setValue];
|
|
206
|
+
}
|
|
207
|
+
function useControl(meta) {
|
|
208
|
+
var [value, setValue] = useInputValue(meta);
|
|
209
|
+
var {
|
|
210
|
+
register,
|
|
211
|
+
change,
|
|
212
|
+
focus,
|
|
213
|
+
blur
|
|
214
|
+
} = useInputEvent();
|
|
215
|
+
var handleChange = value => {
|
|
216
|
+
setValue(value);
|
|
217
|
+
change(value);
|
|
218
|
+
};
|
|
219
|
+
return {
|
|
220
|
+
register,
|
|
221
|
+
value,
|
|
222
|
+
change: handleChange,
|
|
223
|
+
focus,
|
|
224
|
+
blur
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function useInputControl(meta) {
|
|
228
|
+
var [value, setValue] = useInputValue(meta);
|
|
229
|
+
var initializedRef = react.useRef(false);
|
|
230
|
+
var {
|
|
231
|
+
register,
|
|
232
|
+
change,
|
|
233
|
+
focus,
|
|
234
|
+
blur
|
|
235
|
+
} = useInputEvent();
|
|
236
|
+
react.useEffect(() => {
|
|
237
|
+
var form = getFormElement(meta.formId);
|
|
238
|
+
if (!form) {
|
|
239
|
+
// eslint-disable-next-line no-console
|
|
240
|
+
console.warn("useInputControl is unable to find form#".concat(meta.formId, " and identify if a dummy input is required"));
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
var element = getEventTarget(form, meta.name);
|
|
244
|
+
if (!element && typeof value !== 'undefined' && (!Array.isArray(value) || value.length > 0)) {
|
|
245
|
+
element = createDummySelect(form, meta.name, value);
|
|
246
|
+
}
|
|
247
|
+
register(element);
|
|
248
|
+
if (!initializedRef.current) {
|
|
249
|
+
initializedRef.current = true;
|
|
250
|
+
} else {
|
|
251
|
+
change(value !== null && value !== void 0 ? value : '');
|
|
252
|
+
}
|
|
253
|
+
return () => {
|
|
254
|
+
register(null);
|
|
255
|
+
var elements = getFieldElements(form, meta.name);
|
|
256
|
+
for (var _element of elements) {
|
|
257
|
+
if (isDummySelect(_element)) {
|
|
258
|
+
_element.remove();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}, [meta.formId, meta.name, value, change, register]);
|
|
263
|
+
return {
|
|
264
|
+
value,
|
|
265
|
+
change: setValue,
|
|
266
|
+
focus,
|
|
267
|
+
blur
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function Control(props) {
|
|
271
|
+
var control = useControl(props.meta);
|
|
272
|
+
return props.render(control);
|
|
213
273
|
}
|
|
214
274
|
|
|
275
|
+
exports.Control = Control;
|
|
215
276
|
exports.createDummySelect = createDummySelect;
|
|
216
277
|
exports.getEventTarget = getEventTarget;
|
|
217
278
|
exports.getFieldElements = getFieldElements;
|
|
218
279
|
exports.getFormElement = getFormElement;
|
|
219
280
|
exports.isDummySelect = isDummySelect;
|
|
220
281
|
exports.updateFieldValue = updateFieldValue;
|
|
282
|
+
exports.useControl = useControl;
|
|
221
283
|
exports.useInputControl = useInputControl;
|
|
284
|
+
exports.useInputEvent = useInputEvent;
|
|
285
|
+
exports.useInputValue = useInputValue;
|
package/integrations.mjs
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRef, useState, useEffect, useMemo } from 'react';
|
|
1
|
+
import { useRef, useEffect, useMemo, useState } from 'react';
|
|
3
2
|
|
|
4
3
|
function getFormElement(formId) {
|
|
5
|
-
|
|
6
|
-
if (!element) {
|
|
7
|
-
throw new Error('Form not found');
|
|
8
|
-
}
|
|
9
|
-
return element;
|
|
4
|
+
return document.forms.namedItem(formId);
|
|
10
5
|
}
|
|
11
6
|
function getFieldElements(form, name) {
|
|
12
|
-
var field = form.elements.namedItem(name);
|
|
7
|
+
var field = form === null || form === void 0 ? void 0 : form.elements.namedItem(name);
|
|
13
8
|
var elements = !field ? [] : field instanceof Element ? [field] : Array.from(field.values());
|
|
14
9
|
return elements.filter(element => element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement);
|
|
15
10
|
}
|
|
16
|
-
function getEventTarget(form, name) {
|
|
11
|
+
function getEventTarget(form, name, value) {
|
|
17
12
|
var _elements$;
|
|
18
13
|
var elements = getFieldElements(form, name);
|
|
14
|
+
if (elements.length > 1) {
|
|
15
|
+
var options = typeof value === 'string' ? [value] : value;
|
|
16
|
+
for (var element of elements) {
|
|
17
|
+
if (typeof options !== 'undefined' && element instanceof HTMLInputElement && element.type === 'checkbox' && (element.checked ? options.includes(element.value) : !options.includes(element.value))) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
return element;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
19
23
|
return (_elements$ = elements[0]) !== null && _elements$ !== void 0 ? _elements$ : null;
|
|
20
24
|
}
|
|
21
25
|
function createDummySelect(form, name, value) {
|
|
@@ -48,7 +52,7 @@ function isDummySelect(element) {
|
|
|
48
52
|
}
|
|
49
53
|
function updateFieldValue(element, value) {
|
|
50
54
|
if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
|
|
51
|
-
element.checked = element.value === value;
|
|
55
|
+
element.checked = Array.isArray(value) ? value.includes(element.value) : element.value === value;
|
|
52
56
|
} else if (element instanceof HTMLSelectElement && element.multiple) {
|
|
53
57
|
var selectedValue = Array.isArray(value) ? [...value] : [value];
|
|
54
58
|
for (var option of element.options) {
|
|
@@ -96,44 +100,18 @@ function updateFieldValue(element, value) {
|
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
// as there is no way to skip an entry in a multiple select when they all share the same name
|
|
102
|
-
var inputInitialValue = metaOrOptions.initialValue;
|
|
103
|
+
function useInputEvent() {
|
|
104
|
+
var ref = useRef(null);
|
|
103
105
|
var eventDispatched = useRef({
|
|
104
106
|
change: false,
|
|
105
107
|
focus: false,
|
|
106
108
|
blur: false
|
|
107
109
|
});
|
|
108
|
-
var [key, setKey] = useState(metaOrOptions.key);
|
|
109
|
-
var [initialValue, setInitialValue] = useState(inputInitialValue);
|
|
110
|
-
var [value, setValue] = useState(inputInitialValue);
|
|
111
|
-
if (key !== metaOrOptions.key) {
|
|
112
|
-
setValue(inputInitialValue);
|
|
113
|
-
setInitialValue(inputInitialValue);
|
|
114
|
-
setKey(metaOrOptions.key);
|
|
115
|
-
}
|
|
116
|
-
useEffect(() => {
|
|
117
|
-
var form = getFormElement(metaOrOptions.formId);
|
|
118
|
-
if (getEventTarget(form, metaOrOptions.name)) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
createDummySelect(form, metaOrOptions.name, initialValue);
|
|
122
|
-
return () => {
|
|
123
|
-
var elements = getFieldElements(form, metaOrOptions.name);
|
|
124
|
-
for (var element of elements) {
|
|
125
|
-
if (isDummySelect(element)) {
|
|
126
|
-
element.remove();
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}, [metaOrOptions.formId, metaOrOptions.name, initialValue]);
|
|
131
110
|
useEffect(() => {
|
|
132
111
|
var createEventListener = listener => {
|
|
133
112
|
return event => {
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
if ((element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) && element.name === metaOrOptions.name && ((_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.id) === metaOrOptions.formId) {
|
|
113
|
+
var element = ref.current;
|
|
114
|
+
if (element && event.target === element) {
|
|
137
115
|
eventDispatched.current[listener] = true;
|
|
138
116
|
}
|
|
139
117
|
};
|
|
@@ -149,14 +127,13 @@ function useInputControl(metaOrOptions) {
|
|
|
149
127
|
document.removeEventListener('focusin', focusHandler, true);
|
|
150
128
|
document.removeEventListener('focusout', blurHandler, true);
|
|
151
129
|
};
|
|
152
|
-
}, [
|
|
153
|
-
|
|
130
|
+
}, [ref]);
|
|
131
|
+
return useMemo(() => {
|
|
154
132
|
return {
|
|
155
133
|
change(value) {
|
|
156
134
|
if (!eventDispatched.current.change) {
|
|
157
135
|
eventDispatched.current.change = true;
|
|
158
|
-
var
|
|
159
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
136
|
+
var element = ref.current;
|
|
160
137
|
if (element) {
|
|
161
138
|
updateFieldValue(element, value);
|
|
162
139
|
|
|
@@ -170,14 +147,12 @@ function useInputControl(metaOrOptions) {
|
|
|
170
147
|
}));
|
|
171
148
|
}
|
|
172
149
|
}
|
|
173
|
-
setValue(value);
|
|
174
150
|
eventDispatched.current.change = false;
|
|
175
151
|
},
|
|
176
152
|
focus() {
|
|
177
153
|
if (!eventDispatched.current.focus) {
|
|
178
154
|
eventDispatched.current.focus = true;
|
|
179
|
-
var
|
|
180
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
155
|
+
var element = ref.current;
|
|
181
156
|
if (element) {
|
|
182
157
|
element.dispatchEvent(new FocusEvent('focusin', {
|
|
183
158
|
bubbles: true
|
|
@@ -190,8 +165,7 @@ function useInputControl(metaOrOptions) {
|
|
|
190
165
|
blur() {
|
|
191
166
|
if (!eventDispatched.current.blur) {
|
|
192
167
|
eventDispatched.current.blur = true;
|
|
193
|
-
var
|
|
194
|
-
var element = getEventTarget(form, metaOrOptions.name);
|
|
168
|
+
var element = ref.current;
|
|
195
169
|
if (element) {
|
|
196
170
|
element.dispatchEvent(new FocusEvent('focusout', {
|
|
197
171
|
bubbles: true
|
|
@@ -200,12 +174,98 @@ function useInputControl(metaOrOptions) {
|
|
|
200
174
|
}
|
|
201
175
|
}
|
|
202
176
|
eventDispatched.current.blur = false;
|
|
177
|
+
},
|
|
178
|
+
register(element) {
|
|
179
|
+
ref.current = element;
|
|
203
180
|
}
|
|
204
181
|
};
|
|
205
|
-
}, [
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
182
|
+
}, []);
|
|
183
|
+
}
|
|
184
|
+
function useInputValue(options) {
|
|
185
|
+
var initializeValue = () => {
|
|
186
|
+
var _options$initialValue;
|
|
187
|
+
if (typeof options.initialValue === 'string') {
|
|
188
|
+
// @ts-expect-error FIXME: To ensure that the type of value is also `string | undefined` if initialValue is not an array
|
|
189
|
+
return options.initialValue;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// @ts-expect-error Same as above
|
|
193
|
+
return (_options$initialValue = options.initialValue) === null || _options$initialValue === void 0 ? void 0 : _options$initialValue.map(value => value !== null && value !== void 0 ? value : '');
|
|
194
|
+
};
|
|
195
|
+
var [key, setKey] = useState(options.key);
|
|
196
|
+
var [value, setValue] = useState(initializeValue);
|
|
197
|
+
if (key !== options.key) {
|
|
198
|
+
setValue(initializeValue);
|
|
199
|
+
setKey(options.key);
|
|
200
|
+
}
|
|
201
|
+
return [value, setValue];
|
|
202
|
+
}
|
|
203
|
+
function useControl(meta) {
|
|
204
|
+
var [value, setValue] = useInputValue(meta);
|
|
205
|
+
var {
|
|
206
|
+
register,
|
|
207
|
+
change,
|
|
208
|
+
focus,
|
|
209
|
+
blur
|
|
210
|
+
} = useInputEvent();
|
|
211
|
+
var handleChange = value => {
|
|
212
|
+
setValue(value);
|
|
213
|
+
change(value);
|
|
214
|
+
};
|
|
215
|
+
return {
|
|
216
|
+
register,
|
|
217
|
+
value,
|
|
218
|
+
change: handleChange,
|
|
219
|
+
focus,
|
|
220
|
+
blur
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function useInputControl(meta) {
|
|
224
|
+
var [value, setValue] = useInputValue(meta);
|
|
225
|
+
var initializedRef = useRef(false);
|
|
226
|
+
var {
|
|
227
|
+
register,
|
|
228
|
+
change,
|
|
229
|
+
focus,
|
|
230
|
+
blur
|
|
231
|
+
} = useInputEvent();
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
var form = getFormElement(meta.formId);
|
|
234
|
+
if (!form) {
|
|
235
|
+
// eslint-disable-next-line no-console
|
|
236
|
+
console.warn("useInputControl is unable to find form#".concat(meta.formId, " and identify if a dummy input is required"));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
var element = getEventTarget(form, meta.name);
|
|
240
|
+
if (!element && typeof value !== 'undefined' && (!Array.isArray(value) || value.length > 0)) {
|
|
241
|
+
element = createDummySelect(form, meta.name, value);
|
|
242
|
+
}
|
|
243
|
+
register(element);
|
|
244
|
+
if (!initializedRef.current) {
|
|
245
|
+
initializedRef.current = true;
|
|
246
|
+
} else {
|
|
247
|
+
change(value !== null && value !== void 0 ? value : '');
|
|
248
|
+
}
|
|
249
|
+
return () => {
|
|
250
|
+
register(null);
|
|
251
|
+
var elements = getFieldElements(form, meta.name);
|
|
252
|
+
for (var _element of elements) {
|
|
253
|
+
if (isDummySelect(_element)) {
|
|
254
|
+
_element.remove();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}, [meta.formId, meta.name, value, change, register]);
|
|
259
|
+
return {
|
|
260
|
+
value,
|
|
261
|
+
change: setValue,
|
|
262
|
+
focus,
|
|
263
|
+
blur
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function Control(props) {
|
|
267
|
+
var control = useControl(props.meta);
|
|
268
|
+
return props.render(control);
|
|
209
269
|
}
|
|
210
270
|
|
|
211
|
-
export { createDummySelect, getEventTarget, getFieldElements, getFormElement, isDummySelect, updateFieldValue, useInputControl };
|
|
271
|
+
export { Control, createDummySelect, getEventTarget, getFieldElements, getFormElement, isDummySelect, updateFieldValue, useControl, useInputControl, useInputEvent, useInputValue };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Conform view adapter for react",
|
|
4
4
|
"homepage": "https://conform.guide",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.3",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"module": "index.mjs",
|
|
9
9
|
"types": "index.d.ts",
|
|
@@ -30,14 +30,16 @@
|
|
|
30
30
|
"url": "https://github.com/edmundhung/conform/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@conform-to/dom": "1.0.
|
|
33
|
+
"@conform-to/dom": "1.0.3"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/react": "^18.2.
|
|
36
|
+
"@types/react": "^18.2.64",
|
|
37
|
+
"@types/react-dom": "^18.2.20",
|
|
37
38
|
"react": "^18.2.0"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
|
-
"react": ">=18"
|
|
41
|
+
"react": ">=18",
|
|
42
|
+
"react-dom": ">=18"
|
|
41
43
|
},
|
|
42
44
|
"keywords": [
|
|
43
45
|
"constraint-validation",
|