indicator-ui 1.0.33 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import { ExtendFormPath, FormErrorsType, FormErrorType, FormPath, FormValue, UseFormServices } from '../types';
|
|
2
2
|
import { Form } from '../classes';
|
|
3
|
-
|
|
3
|
+
import { Nullable, Undefinable } from '../../../types';
|
|
4
|
+
export declare function createFormServices<F, T = Nullable<Undefinable<F>>>(deps: {
|
|
5
|
+
/** Form */
|
|
4
6
|
getForm: () => Form<T>;
|
|
5
7
|
setFormData: (data: T) => void;
|
|
8
|
+
getValidForm: () => Promise<F | null>;
|
|
9
|
+
/** Fields */
|
|
6
10
|
getField: <P extends FormPath<T>>(path: P) => FormValue<T, P> | null | undefined;
|
|
7
11
|
getFieldSync: <P extends FormPath<T>>(path: P) => FormValue<T, P> | undefined;
|
|
8
12
|
setField: <P extends FormPath<T>>(path: P, value: FormValue<T, P> | undefined) => void;
|
|
9
13
|
clearField: (path: FormPath<T> | FormPath<T>[]) => void;
|
|
14
|
+
/** Errors */
|
|
10
15
|
getError: <P extends FormPath<T>>(path: P) => FormErrorType | undefined;
|
|
11
16
|
setError: <P extends FormPath<T>>(path: P, error: FormErrorType) => void;
|
|
12
17
|
setErrors: (errors: FormErrorsType<T>) => void;
|
|
13
18
|
clearErrors: () => void;
|
|
19
|
+
/** Validation */
|
|
14
20
|
isFieldValid: <P extends ExtendFormPath<T>>(path: P) => Promise<boolean>;
|
|
15
21
|
areFieldsValid: (paths: ExtendFormPath<T>[]) => Promise<boolean>;
|
|
16
22
|
isFormValid: () => Promise<boolean>;
|
|
17
|
-
|
|
23
|
+
/** Highlight (side-effect validation) */
|
|
24
|
+
highlightField: <P extends ExtendFormPath<T>>(path: P) => Promise<boolean>;
|
|
25
|
+
highlightFields: (paths: ExtendFormPath<T>[]) => Promise<boolean>;
|
|
26
|
+
highlightFormErrors: () => Promise<boolean>;
|
|
27
|
+
}): UseFormServices<F, T>;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { ExtendFormPath, FormErrorsType, FormErrorType, FormPath, FormValue } from './formTypes';
|
|
2
2
|
import { Form } from '../classes';
|
|
3
|
-
|
|
3
|
+
import { Nullable, Undefinable } from '../../../types';
|
|
4
|
+
export type UseFormServices<F, T = Nullable<Undefinable<F>>> = {
|
|
4
5
|
/** Работа с данными формы */
|
|
5
6
|
form: {
|
|
6
7
|
/** Получить актуальные данные формы */
|
|
7
8
|
getData: () => Form<T>;
|
|
8
9
|
/** Полностью заменить данные формы */
|
|
9
10
|
setData: (data: T) => void;
|
|
11
|
+
getValidData: () => Promise<F | null>;
|
|
10
12
|
};
|
|
11
13
|
/** Работа с полями */
|
|
12
14
|
fields: {
|
|
@@ -39,4 +41,13 @@ export type UseFormServices<T> = {
|
|
|
39
41
|
/** Проверить валидность всей формы */
|
|
40
42
|
isFormValid: () => Promise<boolean>;
|
|
41
43
|
};
|
|
44
|
+
/** Подсветка ошибок (side-effect валидации) */
|
|
45
|
+
highlight: {
|
|
46
|
+
/** Подсветить ошибку конкретного поля */
|
|
47
|
+
field: <P extends ExtendFormPath<T>>(path: P) => Promise<boolean>;
|
|
48
|
+
/** Подсветить ошибки нескольких полей */
|
|
49
|
+
fields: (paths: ExtendFormPath<T>[]) => Promise<boolean>;
|
|
50
|
+
/** Подсветить все ошибки формы */
|
|
51
|
+
form: () => Promise<boolean>;
|
|
52
|
+
};
|
|
42
53
|
};
|
|
@@ -6,317 +6,207 @@ type PropsType<T, Form> = [
|
|
|
6
6
|
props?: {
|
|
7
7
|
initFormData?: T;
|
|
8
8
|
scheme?: FormSchemeType<T>;
|
|
9
|
-
onSubmit?: (data: Form, event: FormEvent<HTMLFormElement>, services: UseFormServices<T>) => void | Promise<void>;
|
|
9
|
+
onSubmit?: (data: Form, event: FormEvent<HTMLFormElement>, services: UseFormServices<Form, T>) => void | Promise<void>;
|
|
10
10
|
/** Callback при ошибки валидации полей */
|
|
11
11
|
onSubmitError?: (event: {
|
|
12
12
|
errors: FormErrorsType<T>;
|
|
13
|
-
}, services: UseFormServices<T>) => void;
|
|
13
|
+
}, services: UseFormServices<Form, T>) => void;
|
|
14
|
+
onSubmitAttempt?: (data: T | undefined | null, event: FormEvent<HTMLFormElement>, services: UseFormServices<Form, T>) => void;
|
|
14
15
|
}
|
|
15
16
|
];
|
|
16
17
|
/**
|
|
17
|
-
*
|
|
18
|
-
* с глубокой статической типизацией и расширяемым API.
|
|
18
|
+
* `useForm` — типобезопасный хук для управления состоянием и валидации форм.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* -
|
|
25
|
-
* -
|
|
26
|
-
* - правила валидации;
|
|
27
|
-
* - интеграцию с `<form>` и полями.
|
|
28
|
-
*
|
|
29
|
-
* При этом предоставляет:
|
|
30
|
-
* - декларативную работу через `register` / `registerForm`;
|
|
31
|
-
* - императивные сервисы для бизнес-логики (`services`);
|
|
32
|
-
* - строгую типизацию всех путей формы.
|
|
20
|
+
* Предоставляет:
|
|
21
|
+
* - централизованное управление данными формы;
|
|
22
|
+
* - декларативную регистрацию полей;
|
|
23
|
+
* - схемную и кастомную валидацию;
|
|
24
|
+
* - контролируемый submit lifecycle;
|
|
25
|
+
* - безопасный императивный API (`services`) для бизнес-логики.
|
|
33
26
|
*
|
|
34
27
|
* ---
|
|
35
|
-
* ##
|
|
28
|
+
* ## 🧠 Основная идея
|
|
36
29
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* вы получаете:
|
|
44
|
-
* - строгую типизацию `path` для всех полей;
|
|
45
|
-
* - корректные типы значений и ошибок;
|
|
46
|
-
* - защиту от обращения к несуществующим полям.
|
|
30
|
+
* Хук полностью управляет состоянием формы и ошибками,
|
|
31
|
+
* а наружу отдаёт:
|
|
32
|
+
* - **декларативный API** (`register`, `registerForm`);
|
|
33
|
+
* - **императивные команды** (clear, validate, highlight);
|
|
34
|
+
* - **изолированные сервисы** для submit-логики.
|
|
47
35
|
*
|
|
48
36
|
* ---
|
|
49
|
-
* ##
|
|
50
|
-
*
|
|
51
|
-
* Валидация может быть задана двумя способами:
|
|
52
|
-
*
|
|
53
|
-
* ### 1️⃣ Через `register`
|
|
54
|
-
*
|
|
55
|
-
* ```tsx
|
|
56
|
-
* <FormField
|
|
57
|
-
* {...register('email', {
|
|
58
|
-
* required: { setting: true, message: 'Обязательное поле' }
|
|
59
|
-
* })}
|
|
60
|
-
* />
|
|
61
|
-
* ```
|
|
37
|
+
* ## 🔁 Submit lifecycle
|
|
62
38
|
*
|
|
63
|
-
*
|
|
39
|
+
* Порядок вызова callbacks при submit:
|
|
64
40
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* custom: value => value.includes('@') || 'Некорректный email',
|
|
70
|
-
* },
|
|
71
|
-
* };
|
|
72
|
-
* ```
|
|
73
|
-
*
|
|
74
|
-
* Схема применяется один раз и синхронизируется с формой автоматически.
|
|
41
|
+
* 1. `onSubmitAttempt` — всегда
|
|
42
|
+
* 2. Валидация формы
|
|
43
|
+
* 3. `onSubmit` — если форма валидна
|
|
44
|
+
* 4. `onSubmitError` — если есть ошибки
|
|
75
45
|
*
|
|
76
46
|
* ---
|
|
77
|
-
* ##
|
|
47
|
+
* ## 🔌 Callbacks
|
|
78
48
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* <form {...registerForm()}>
|
|
83
|
-
* ```
|
|
84
|
-
*
|
|
85
|
-
* Поведение:
|
|
86
|
-
* - `onSubmit`:
|
|
87
|
-
* - предотвращает нативный submit;
|
|
88
|
-
* - проверяет валидность формы;
|
|
89
|
-
* - вызывает пользовательский `onSubmit` или `onSubmitError`;
|
|
90
|
-
* - `onReset`:
|
|
91
|
-
* - предотвращает нативный reset;
|
|
92
|
-
* - очищает форму и ошибки;
|
|
93
|
-
* - `noValidate: true`:
|
|
94
|
-
* - отключает HTML5-валидацию.
|
|
49
|
+
* Все callbacks получают объект `services` —
|
|
50
|
+
* стабильный набор команд для работы с формой
|
|
51
|
+
* (без реактивных значений и возможности вызвать submit повторно).
|
|
95
52
|
*
|
|
96
53
|
* ---
|
|
97
|
-
* ##
|
|
54
|
+
* ## 📥 Входные параметры
|
|
98
55
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
56
|
+
* | Параметр | Тип | Описание |
|
|
57
|
+
* |---------|-----|----------|
|
|
58
|
+
* | `initFormData` | `T` | Начальные данные формы |
|
|
59
|
+
* | `scheme` | `FormSchemeType<T>` | Схема валидации |
|
|
60
|
+
* | `onSubmitAttempt` | `(data, event, services) => void` | Вызывается при любой попытке submit |
|
|
61
|
+
* | `onSubmit` | `(data, event, services) => void \| Promise<void>` | Вызывается при успешной валидации |
|
|
62
|
+
* | `onSubmitError` | `({ errors }, services) => void` | Вызывается при ошибках валидации |
|
|
103
63
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
64
|
+
* ---
|
|
65
|
+
* ## 📤 Возвращаемое API
|
|
66
|
+
*
|
|
67
|
+
* | Поле | Тип | Назначение |
|
|
68
|
+
* |------|-----|------------|
|
|
69
|
+
* | `formData` | `T` | Реактивные данные формы |
|
|
70
|
+
* | `errors` | `FormErrorsType<T>` | Реактивные ошибки |
|
|
71
|
+
* | `register` | `(path, config?) => FieldProps` | Регистрация поля |
|
|
72
|
+
* | `registerForm` | `() => form props` | Подключение `<form>` |
|
|
73
|
+
* | `setFormData` | `(data) => void` | Полная замена данных формы |
|
|
74
|
+
* | `getFormData` | `() => T` | Получить актуальные данные |
|
|
75
|
+
* | `getField` | `(path) => value` | Получить значение поля |
|
|
76
|
+
* | `getFieldSync` | `(path) => value` | Получить актуальное значение поля |
|
|
77
|
+
* | `setField` | `(path, value) => void` | Установить значение поля |
|
|
78
|
+
* | `getError` | `(path) => error` | Получить ошибку поля |
|
|
79
|
+
* | `setError` | `(path, error) => void` | Установить ошибку поля |
|
|
80
|
+
* | `clearField` | `(path \| paths) => void` | Очистить поле(я) |
|
|
81
|
+
* | `clearForm` | `() => void` | Очистить форму |
|
|
82
|
+
* | `clearErrors` | `() => void` | Очистить все ошибки |
|
|
83
|
+
* | `highlightField` | `(path) => Promise<boolean>` | Валидировать поле с ошибками |
|
|
84
|
+
* | `highlightFields` | `(paths) => Promise<boolean>` | Валидировать несколько полей |
|
|
85
|
+
* | `highlightFormErrors` | `() => Promise<boolean>` | Валидировать всю форму |
|
|
86
|
+
* | `isFieldValid` | `(path) => Promise<boolean>` | Проверка поля без ошибок |
|
|
87
|
+
* | `areFieldsValid` | `(paths) => Promise<boolean>` | Проверка полей без ошибок |
|
|
88
|
+
* | `isFormValid` | `() => Promise<boolean>` | Проверка формы без ошибок |
|
|
89
|
+
* | `getValidForm` | `() => Promise<T \| null>` | Получить форму, если валидна |
|
|
90
|
+
* | `submitForm` | `() => void` | Программный submit |
|
|
91
|
+
* | `resetForm` | `() => void` | Программный reset |
|
|
106
92
|
*
|
|
107
93
|
* ---
|
|
108
94
|
* ## 🛠 `services`
|
|
109
95
|
*
|
|
110
|
-
* `services`
|
|
111
|
-
*
|
|
96
|
+
* `services` доступны **только внутри submit-callbacks**
|
|
97
|
+
* и предоставляют императивный API:
|
|
112
98
|
*
|
|
113
|
-
*
|
|
114
|
-
* -
|
|
115
|
-
* -
|
|
116
|
-
* -
|
|
117
|
-
* -
|
|
118
|
-
*
|
|
119
|
-
* ### ❌ Чего в `services` НЕТ принципиально:
|
|
120
|
-
* - реактивных значений (`formData`, `errors`);
|
|
121
|
-
* - методов `submit`, `reset`, `register`;
|
|
122
|
-
* - UX-логики (подсветка, фокус, скролл);
|
|
123
|
-
* - возможностей повторно инициировать submit.
|
|
124
|
-
*
|
|
125
|
-
* Это гарантирует:
|
|
126
|
-
* - отсутствие циклов;
|
|
127
|
-
* - предсказуемость side-effect’ов;
|
|
128
|
-
* - стабильность публичного API.
|
|
99
|
+
* - `form` — чтение и замена данных формы;
|
|
100
|
+
* - `fields` — работа с полями;
|
|
101
|
+
* - `errors` — управление ошибками;
|
|
102
|
+
* - `validation` — проверки без side-effects;
|
|
103
|
+
* - `highlight` — валидация с обновлением ошибок.
|
|
129
104
|
*
|
|
130
105
|
* ---
|
|
131
|
-
|
|
132
|
-
* @template T — тип начальных данных (может быть частичным).
|
|
133
|
-
*
|
|
134
|
-
* @param params
|
|
135
|
-
* @param params.initFormData — начальные данные формы.
|
|
136
|
-
* @param params.scheme — схема валидации.
|
|
137
|
-
* @param params.onSubmit — вызывается при успешной валидации формы.
|
|
138
|
-
* @param params.onSubmitError — вызывается при ошибках валидации.
|
|
139
|
-
*
|
|
140
|
-
* @returns API управления формой.
|
|
106
|
+
;
|
|
141
107
|
* @example
|
|
142
108
|
*
|
|
143
|
-
* ### Полноценный пример использования `useForm`
|
|
144
|
-
*
|
|
145
|
-
* Форма демонстрирует:
|
|
146
|
-
* - вложенные структуры данных;
|
|
147
|
-
* - массивы и tuple-поля;
|
|
148
|
-
* - кастомную и схемную валидацию;
|
|
149
|
-
* - работу с датами и диапазонами;
|
|
150
|
-
* - проверку валидности формы и отдельных полей;
|
|
151
|
-
* - императивные действия (очистка, валидация).
|
|
152
|
-
*
|
|
153
|
-
* ---
|
|
154
|
-
*
|
|
155
109
|
* ```tsx
|
|
156
|
-
* type
|
|
110
|
+
* type FormType = {
|
|
157
111
|
* phone: string;
|
|
158
|
-
*
|
|
159
|
-
* textarea: string;
|
|
160
|
-
* date: string;
|
|
161
|
-
* time: string;
|
|
162
|
-
* datetime: string;
|
|
163
|
-
* dateRange: [string | undefined, string | undefined];
|
|
112
|
+
* message: string;
|
|
164
113
|
* selects: {
|
|
165
|
-
*
|
|
166
|
-
*
|
|
114
|
+
* category: 'a' | 'b' | 'c';
|
|
115
|
+
* tags: ('a' | 'b' | 'c')[];
|
|
167
116
|
* };
|
|
168
|
-
*
|
|
169
|
-
* {
|
|
170
|
-
* {
|
|
117
|
+
* settings: [
|
|
118
|
+
* { enabled: boolean },
|
|
119
|
+
* { mode: { value: string } },
|
|
171
120
|
* ];
|
|
172
|
-
* array: { test1: string; test2: string }[];
|
|
173
121
|
* };
|
|
174
122
|
*
|
|
175
|
-
* const scheme: FormSchemeType<
|
|
123
|
+
* const scheme: FormSchemeType<FormType> = {
|
|
176
124
|
* phone: {
|
|
125
|
+
* required: { setting: true, message: 'Обязательное поле' },
|
|
177
126
|
* custom: value =>
|
|
178
|
-
* value && value.length > 5 ? false : '
|
|
179
|
-
* },
|
|
180
|
-
*
|
|
181
|
-
* baseInput: {
|
|
182
|
-
* default: 'test string',
|
|
183
|
-
* minStr: { setting: 3, message: 'Больше 3 символов' },
|
|
184
|
-
* maxStr: 15,
|
|
127
|
+
* value && value.length > 5 ? false : 'Некорректный номер',
|
|
185
128
|
* },
|
|
186
129
|
*
|
|
187
|
-
*
|
|
188
|
-
* default: 'test/textarea',
|
|
130
|
+
* message: {
|
|
189
131
|
* noSpace: true,
|
|
190
132
|
* custom: (value, options) => {
|
|
191
|
-
* const
|
|
192
|
-
* return value
|
|
193
|
-
* ? '
|
|
133
|
+
* const enabled = options.getField('settings[0].enabled');
|
|
134
|
+
* return enabled && !value
|
|
135
|
+
* ? 'Сообщение обязательно'
|
|
194
136
|
* : false;
|
|
195
137
|
* },
|
|
196
138
|
* },
|
|
197
139
|
*
|
|
198
|
-
* 'selects.
|
|
199
|
-
* required:
|
|
200
|
-
* },
|
|
201
|
-
*
|
|
202
|
-
* 'array[*]': {
|
|
203
|
-
* custom: {
|
|
204
|
-
* fun: () => '',
|
|
205
|
-
* },
|
|
140
|
+
* 'selects.category': {
|
|
141
|
+
* required: true,
|
|
206
142
|
* },
|
|
207
143
|
* };
|
|
208
144
|
*
|
|
209
|
-
* export function
|
|
145
|
+
* export function ExampleForm() {
|
|
210
146
|
* const {
|
|
211
147
|
* formData,
|
|
212
|
-
* clearForm,
|
|
213
|
-
* clearErrors,
|
|
214
|
-
* highlightFormErrors,
|
|
215
|
-
* highlightField,
|
|
216
|
-
* isFormValid,
|
|
217
|
-
* isFieldValid,
|
|
218
148
|
* register,
|
|
219
149
|
* registerForm,
|
|
220
|
-
*
|
|
150
|
+
* highlightField,
|
|
151
|
+
* isFormValid,
|
|
152
|
+
* } = useForm<FormType>({
|
|
221
153
|
* scheme,
|
|
222
|
-
* onSubmit: data => {
|
|
223
|
-
* console.log('Submit data:', data);
|
|
224
|
-
* },
|
|
225
|
-
* });
|
|
226
154
|
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
155
|
+
* onSubmitAttempt: (data, event, services) => {
|
|
156
|
+
* console.log('Submit attempt:', data);
|
|
157
|
+
* },
|
|
229
158
|
*
|
|
230
|
-
*
|
|
159
|
+
* onSubmit: async (data, event, services) => {
|
|
160
|
+
* // бизнес-валидация без UI-эффектов
|
|
161
|
+
* const isValid = await services.validation.isFormValid();
|
|
162
|
+
* if (!isValid) return;
|
|
231
163
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* inputFormat="dd.MM.yyyy HH:mm"
|
|
235
|
-
* outFormat="yyyy-MM-dd'T'HH:mmXXX"
|
|
236
|
-
* label="Дата и время"
|
|
237
|
-
* />
|
|
164
|
+
* console.log('Submit success:', data);
|
|
165
|
+
* },
|
|
238
166
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
167
|
+
* onSubmitError: ({ errors }, services) => {
|
|
168
|
+
* // UI-валидация с подсветкой
|
|
169
|
+
* services.highlight.form();
|
|
170
|
+
* console.log('Submit errors:', errors);
|
|
171
|
+
* },
|
|
172
|
+
* });
|
|
245
173
|
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* label="Номер телефона"
|
|
249
|
-
* mask="+7 000 000-00-00"
|
|
250
|
-
* />
|
|
174
|
+
* return (
|
|
175
|
+
* <form {...registerForm()}>
|
|
251
176
|
*
|
|
252
|
-
* <
|
|
253
|
-
* {...register('baseInput')}
|
|
254
|
-
* label="Base input"
|
|
255
|
-
* />
|
|
177
|
+
* <input {...register('phone')} />
|
|
256
178
|
*
|
|
257
|
-
* <
|
|
179
|
+
* <textarea {...register('message')} />
|
|
258
180
|
*
|
|
259
|
-
* <
|
|
181
|
+
* <select {...register('selects.category')}>
|
|
182
|
+
* <option value="a">A</option>
|
|
183
|
+
* <option value="b">B</option>
|
|
184
|
+
* <option value="c">C</option>
|
|
185
|
+
* </select>
|
|
260
186
|
*
|
|
261
|
-
* <
|
|
262
|
-
*
|
|
263
|
-
*
|
|
187
|
+
* <input
|
|
188
|
+
* type="checkbox"
|
|
189
|
+
* {...register('settings[0].enabled')}
|
|
264
190
|
* />
|
|
265
191
|
*
|
|
266
|
-
* <
|
|
267
|
-
* {...register('addition[1].radio.multi')}
|
|
268
|
-
* options={radioOptions}
|
|
269
|
-
* multiple
|
|
270
|
-
* />
|
|
192
|
+
* <input {...register('settings[1].mode.value')} />
|
|
271
193
|
*
|
|
272
|
-
* <
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* required
|
|
276
|
-
* />
|
|
194
|
+
* <button type="button" onClick={() => highlightField('phone')}>
|
|
195
|
+
* Validate phone
|
|
196
|
+
* </button>
|
|
277
197
|
*
|
|
278
|
-
* <
|
|
279
|
-
* {...register('date')}
|
|
280
|
-
* inputFormat="dd.MM.yyyy"
|
|
281
|
-
* outFormat="yyyy-MM-dd"
|
|
282
|
-
* />
|
|
198
|
+
* <button type="submit">Submit</button>
|
|
283
199
|
*
|
|
284
|
-
* <
|
|
285
|
-
* {...register('time')}
|
|
286
|
-
* inputFormat="HH:mm"
|
|
287
|
-
* outFormat="HH:mmXXX"
|
|
288
|
-
* />
|
|
200
|
+
* <pre>{JSON.stringify(formData, null, 2)}</pre>
|
|
289
201
|
*
|
|
290
|
-
* <button type="submit">Отправить</button>
|
|
291
|
-
* <button type="reset">Сбросить</button>
|
|
292
202
|
* </form>
|
|
293
203
|
* );
|
|
294
204
|
* }
|
|
295
205
|
* ```
|
|
296
206
|
*
|
|
297
207
|
* ---
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* ```ts
|
|
302
|
-
* clearForm(); // очистить все значения формы
|
|
303
|
-
* clearErrors(); // очистить все ошибки
|
|
304
|
-
* await highlightFormErrors(); // подсветить ошибки всех полей
|
|
305
|
-
* await highlightField('selects.select');
|
|
306
|
-
*
|
|
307
|
-
* const isValid = await isFormValid();
|
|
308
|
-
* const isTextareaValid = await isFieldValid('textarea');
|
|
309
|
-
* ```
|
|
310
|
-
*
|
|
311
|
-
* ---
|
|
312
|
-
*
|
|
313
|
-
* ### Просмотр текущего состояния формы
|
|
314
|
-
*
|
|
315
|
-
* ```tsx
|
|
316
|
-
* <pre>
|
|
317
|
-
* {JSON.stringify(formData, null, 2)}
|
|
318
|
-
* </pre>
|
|
319
|
-
* ```
|
|
208
|
+
* @template Form Полный тип формы
|
|
209
|
+
* @template T Тип начальных данных
|
|
320
210
|
*/
|
|
321
211
|
export declare function useForm<Form, T extends Nullable<Undefinable<Form>> = Nullable<Undefinable<Form>>>(...args: PropsType<T, Form>): {
|
|
322
212
|
formData: T | undefined;
|