@reformer/core 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/behaviors.d.ts +2 -0
- package/dist/behaviors.js +230 -0
- package/dist/core/behavior/behavior-applicator.d.ts +71 -0
- package/dist/core/behavior/behavior-applicator.js +92 -0
- package/dist/core/behavior/behavior-context.d.ts +29 -0
- package/dist/core/behavior/behavior-context.js +38 -0
- package/dist/core/behavior/behavior-registry.d.ts +97 -0
- package/dist/core/behavior/behavior-registry.js +198 -0
- package/dist/core/behavior/behaviors/compute-from.d.ts +41 -0
- package/dist/core/behavior/behaviors/compute-from.js +84 -0
- package/dist/core/behavior/behaviors/copy-from.d.ts +31 -0
- package/dist/core/behavior/behaviors/copy-from.js +64 -0
- package/dist/core/behavior/behaviors/enable-when.d.ts +49 -0
- package/dist/core/behavior/behaviors/enable-when.js +81 -0
- package/dist/core/behavior/behaviors/index.d.ts +11 -0
- package/dist/core/behavior/behaviors/index.js +11 -0
- package/dist/core/behavior/behaviors/reset-when.d.ts +51 -0
- package/dist/core/behavior/behaviors/reset-when.js +63 -0
- package/dist/core/behavior/behaviors/revalidate-when.d.ts +30 -0
- package/dist/core/behavior/behaviors/revalidate-when.js +51 -0
- package/dist/core/behavior/behaviors/sync-fields.d.ts +28 -0
- package/dist/core/behavior/behaviors/sync-fields.js +66 -0
- package/dist/core/behavior/behaviors/transform-value.d.ts +120 -0
- package/dist/core/behavior/behaviors/transform-value.js +110 -0
- package/dist/core/behavior/behaviors/watch-field.d.ts +35 -0
- package/dist/core/behavior/behaviors/watch-field.js +56 -0
- package/dist/core/behavior/compose-behavior.d.ts +106 -0
- package/dist/core/behavior/compose-behavior.js +166 -0
- package/dist/core/behavior/create-field-path.d.ts +20 -0
- package/dist/core/behavior/create-field-path.js +69 -0
- package/dist/core/behavior/index.d.ts +12 -0
- package/dist/core/behavior/index.js +17 -0
- package/dist/core/behavior/types.d.ts +152 -0
- package/dist/core/behavior/types.js +7 -0
- package/dist/core/context/form-context-impl.d.ts +29 -0
- package/dist/core/context/form-context-impl.js +37 -0
- package/dist/core/factories/index.d.ts +6 -0
- package/dist/core/factories/index.js +6 -0
- package/dist/core/factories/node-factory.d.ts +209 -0
- package/dist/core/factories/node-factory.js +281 -0
- package/dist/core/nodes/array-node.d.ts +308 -0
- package/dist/core/nodes/array-node.js +534 -0
- package/dist/core/nodes/field-node.d.ts +269 -0
- package/dist/core/nodes/field-node.js +510 -0
- package/dist/core/nodes/form-node.d.ts +342 -0
- package/dist/core/nodes/form-node.js +343 -0
- package/dist/core/nodes/group-node/field-registry.d.ts +191 -0
- package/dist/core/nodes/group-node/field-registry.js +215 -0
- package/dist/core/nodes/group-node/index.d.ts +11 -0
- package/dist/core/nodes/group-node/index.js +11 -0
- package/dist/core/nodes/group-node/proxy-builder.d.ts +71 -0
- package/dist/core/nodes/group-node/proxy-builder.js +161 -0
- package/dist/core/nodes/group-node/state-manager.d.ts +184 -0
- package/dist/core/nodes/group-node/state-manager.js +265 -0
- package/dist/core/nodes/group-node.d.ts +494 -0
- package/dist/core/nodes/group-node.js +770 -0
- package/dist/core/types/deep-schema.d.ts +78 -0
- package/dist/core/types/deep-schema.js +11 -0
- package/dist/core/types/field-path.d.ts +42 -0
- package/dist/core/types/field-path.js +4 -0
- package/dist/core/types/form-context.d.ts +83 -0
- package/dist/core/types/form-context.js +25 -0
- package/dist/core/types/group-node-proxy.d.ts +135 -0
- package/dist/core/types/group-node-proxy.js +31 -0
- package/dist/core/types/index.d.ts +163 -0
- package/dist/core/types/index.js +4 -0
- package/dist/core/types/validation-schema.d.ts +104 -0
- package/dist/core/types/validation-schema.js +10 -0
- package/dist/core/utils/create-form.d.ts +61 -0
- package/dist/core/utils/create-form.js +24 -0
- package/dist/core/utils/debounce.d.ts +160 -0
- package/dist/core/utils/debounce.js +197 -0
- package/dist/core/utils/error-handler.d.ts +180 -0
- package/dist/core/utils/error-handler.js +226 -0
- package/dist/core/utils/field-path-navigator.d.ts +240 -0
- package/dist/core/utils/field-path-navigator.js +374 -0
- package/dist/core/utils/index.d.ts +14 -0
- package/dist/core/utils/index.js +14 -0
- package/dist/core/utils/registry-helpers.d.ts +50 -0
- package/dist/core/utils/registry-helpers.js +79 -0
- package/dist/core/utils/registry-stack.d.ts +69 -0
- package/dist/core/utils/registry-stack.js +86 -0
- package/dist/core/utils/resources.d.ts +41 -0
- package/dist/core/utils/resources.js +69 -0
- package/dist/core/utils/subscription-manager.d.ts +180 -0
- package/dist/core/utils/subscription-manager.js +214 -0
- package/dist/core/utils/type-guards.d.ts +116 -0
- package/dist/core/utils/type-guards.js +169 -0
- package/dist/core/validation/core/apply-when.d.ts +28 -0
- package/dist/core/validation/core/apply-when.js +41 -0
- package/dist/core/validation/core/apply.d.ts +63 -0
- package/dist/core/validation/core/apply.js +38 -0
- package/dist/core/validation/core/index.d.ts +8 -0
- package/dist/core/validation/core/index.js +8 -0
- package/dist/core/validation/core/validate-async.d.ts +42 -0
- package/dist/core/validation/core/validate-async.js +45 -0
- package/dist/core/validation/core/validate-tree.d.ts +35 -0
- package/dist/core/validation/core/validate-tree.js +37 -0
- package/dist/core/validation/core/validate.d.ts +32 -0
- package/dist/core/validation/core/validate.js +38 -0
- package/dist/core/validation/field-path.d.ts +43 -0
- package/dist/core/validation/field-path.js +147 -0
- package/dist/core/validation/index.d.ts +21 -0
- package/dist/core/validation/index.js +33 -0
- package/dist/core/validation/validate-form.d.ts +85 -0
- package/dist/core/validation/validate-form.js +152 -0
- package/dist/core/validation/validation-applicator.d.ts +89 -0
- package/dist/core/validation/validation-applicator.js +217 -0
- package/dist/core/validation/validation-context.d.ts +47 -0
- package/dist/core/validation/validation-context.js +75 -0
- package/dist/core/validation/validation-registry.d.ts +156 -0
- package/dist/core/validation/validation-registry.js +298 -0
- package/dist/core/validation/validators/array-validators.d.ts +63 -0
- package/dist/core/validation/validators/array-validators.js +86 -0
- package/dist/core/validation/validators/date.d.ts +38 -0
- package/dist/core/validation/validators/date.js +117 -0
- package/dist/core/validation/validators/email.d.ts +44 -0
- package/dist/core/validation/validators/email.js +60 -0
- package/dist/core/validation/validators/index.d.ts +14 -0
- package/dist/core/validation/validators/index.js +14 -0
- package/dist/core/validation/validators/max-length.d.ts +45 -0
- package/dist/core/validation/validators/max-length.js +60 -0
- package/dist/core/validation/validators/max.d.ts +45 -0
- package/dist/core/validation/validators/max.js +60 -0
- package/dist/core/validation/validators/min-length.d.ts +45 -0
- package/dist/core/validation/validators/min-length.js +60 -0
- package/dist/core/validation/validators/min.d.ts +45 -0
- package/dist/core/validation/validators/min.js +60 -0
- package/dist/core/validation/validators/number.d.ts +38 -0
- package/dist/core/validation/validators/number.js +90 -0
- package/dist/core/validation/validators/pattern.d.ts +47 -0
- package/dist/core/validation/validators/pattern.js +62 -0
- package/dist/core/validation/validators/phone.d.ts +34 -0
- package/dist/core/validation/validators/phone.js +58 -0
- package/dist/core/validation/validators/required.d.ts +48 -0
- package/dist/core/validation/validators/required.js +69 -0
- package/dist/core/validation/validators/url.d.ts +29 -0
- package/dist/core/validation/validators/url.js +55 -0
- package/dist/create-field-path-CdPF3lIK.js +704 -0
- package/dist/hooks/useFormControl.d.ts +48 -0
- package/dist/hooks/useFormControl.js +298 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +8 -0
- package/dist/node-factory-D7DOnSSN.js +3200 -0
- package/dist/validators.d.ts +2 -0
- package/dist/validators.js +298 -0
- package/llms.txt +847 -0
- package/package.json +86 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FieldNode - узел поля формы
|
|
3
|
+
*
|
|
4
|
+
* Представляет одно поле формы с валидацией и состоянием
|
|
5
|
+
* Наследует от FormNode и реализует все его абстрактные методы
|
|
6
|
+
*
|
|
7
|
+
* @group Nodes
|
|
8
|
+
*/
|
|
9
|
+
import type { ReadonlySignal } from '@preact/signals-core';
|
|
10
|
+
import { FormNode } from './form-node';
|
|
11
|
+
import type { SetValueOptions } from './form-node';
|
|
12
|
+
import type { FieldConfig, ValidationError } from '../types';
|
|
13
|
+
/**
|
|
14
|
+
* FieldNode - узел для отдельного поля формы
|
|
15
|
+
*
|
|
16
|
+
* @group Nodes
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const field = new FieldNode({
|
|
21
|
+
* value: '',
|
|
22
|
+
* component: Input,
|
|
23
|
+
* validators: [required, email],
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* field.setValue('test@mail.com');
|
|
27
|
+
* await field.validate();
|
|
28
|
+
* console.log(field.valid.value); // true
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class FieldNode<T> extends FormNode<T> {
|
|
32
|
+
private _value;
|
|
33
|
+
private _errors;
|
|
34
|
+
private _pending;
|
|
35
|
+
private _componentProps;
|
|
36
|
+
readonly value: ReadonlySignal<T>;
|
|
37
|
+
readonly valid: ReadonlySignal<boolean>;
|
|
38
|
+
readonly invalid: ReadonlySignal<boolean>;
|
|
39
|
+
readonly pending: ReadonlySignal<boolean>;
|
|
40
|
+
readonly errors: ReadonlySignal<ValidationError[]>;
|
|
41
|
+
readonly componentProps: ReadonlySignal<Record<string, any>>;
|
|
42
|
+
/**
|
|
43
|
+
* Вычисляемое свойство: нужно ли показывать ошибку
|
|
44
|
+
* Ошибка показывается если поле невалидно И (touched ИЛИ dirty)
|
|
45
|
+
*/
|
|
46
|
+
readonly shouldShowError: ReadonlySignal<boolean>;
|
|
47
|
+
private validators;
|
|
48
|
+
private asyncValidators;
|
|
49
|
+
private updateOn;
|
|
50
|
+
private initialValue;
|
|
51
|
+
private currentValidationId;
|
|
52
|
+
private debounceMs;
|
|
53
|
+
private validateDebounceTimer?;
|
|
54
|
+
private validateDebounceResolve?;
|
|
55
|
+
/**
|
|
56
|
+
* Менеджер подписок для централизованного cleanup
|
|
57
|
+
* Использует SubscriptionManager вместо массива для управления подписками
|
|
58
|
+
*/
|
|
59
|
+
private disposers;
|
|
60
|
+
readonly component: FieldConfig<T>['component'];
|
|
61
|
+
constructor(config: FieldConfig<T>);
|
|
62
|
+
getValue(): T;
|
|
63
|
+
setValue(value: T, options?: SetValueOptions): void;
|
|
64
|
+
patchValue(value: Partial<T>): void;
|
|
65
|
+
/**
|
|
66
|
+
* Сбросить поле к указанному значению (или к initialValue)
|
|
67
|
+
*
|
|
68
|
+
* @param value - опциональное значение для сброса. Если не указано, используется initialValue
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* Этот метод:
|
|
72
|
+
* - Устанавливает значение в value или initialValue
|
|
73
|
+
* - Очищает ошибки валидации
|
|
74
|
+
* - Сбрасывает touched/dirty флаги
|
|
75
|
+
* - Устанавливает статус в 'valid'
|
|
76
|
+
*
|
|
77
|
+
* Если вам нужно сбросить к исходному значению, используйте resetToInitial()
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Сброс к initialValue
|
|
82
|
+
* field.reset();
|
|
83
|
+
*
|
|
84
|
+
* // Сброс к новому значению
|
|
85
|
+
* field.reset('new value');
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
reset(value?: T): void;
|
|
89
|
+
/**
|
|
90
|
+
* Сбросить поле к исходному значению (initialValue)
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* Алиас для reset() без параметров, но более явный:
|
|
94
|
+
* - resetToInitial() - явно показывает намерение вернуться к начальному значению
|
|
95
|
+
* - reset() - может принимать новое значение
|
|
96
|
+
*
|
|
97
|
+
* Полезно когда:
|
|
98
|
+
* - Пользователь нажал "Cancel" - вернуть форму в исходное состояние
|
|
99
|
+
* - Форма была изменена через reset(newValue), но нужно вернуться к самому началу
|
|
100
|
+
* - Явное намерение показать "отмену всех изменений"
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const field = new FieldNode({ value: 'initial', component: Input });
|
|
105
|
+
*
|
|
106
|
+
* field.setValue('changed');
|
|
107
|
+
* field.reset('temp value');
|
|
108
|
+
* console.log(field.value.value); // 'temp value'
|
|
109
|
+
*
|
|
110
|
+
* field.resetToInitial();
|
|
111
|
+
* console.log(field.value.value); // 'initial'
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
resetToInitial(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Запустить валидацию поля
|
|
117
|
+
* @param options - опции валидации
|
|
118
|
+
* @returns `Promise<boolean>` - true если поле валидно
|
|
119
|
+
*
|
|
120
|
+
* @remarks
|
|
121
|
+
* Метод защищен от race conditions через validationId.
|
|
122
|
+
* При быстром вводе только последняя валидация применяет результаты.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* // Обычная валидация
|
|
127
|
+
* await field.validate();
|
|
128
|
+
*
|
|
129
|
+
* // С debounce
|
|
130
|
+
* await field.validate({ debounce: 300 });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
validate(options?: {
|
|
134
|
+
debounce?: number;
|
|
135
|
+
}): Promise<boolean>;
|
|
136
|
+
/**
|
|
137
|
+
* Немедленная валидация без debounce
|
|
138
|
+
* @private
|
|
139
|
+
* @remarks
|
|
140
|
+
* Защищена от race conditions:
|
|
141
|
+
* - Проверка validationId после синхронной валидации
|
|
142
|
+
* - Проверка перед установкой pending
|
|
143
|
+
* - Проверка после Promise.all
|
|
144
|
+
* - Проверка перед обработкой async результатов
|
|
145
|
+
* - Проверка перед очисткой errors
|
|
146
|
+
*/
|
|
147
|
+
private validateImmediate;
|
|
148
|
+
setErrors(errors: ValidationError[]): void;
|
|
149
|
+
clearErrors(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Hook: вызывается после markAsTouched()
|
|
152
|
+
*
|
|
153
|
+
* Для FieldNode: если updateOn === 'blur', запускаем валидацию
|
|
154
|
+
*/
|
|
155
|
+
protected onMarkAsTouched(): void;
|
|
156
|
+
/**
|
|
157
|
+
* Hook: вызывается после disable()
|
|
158
|
+
*
|
|
159
|
+
* Для FieldNode: очищаем ошибки валидации
|
|
160
|
+
*/
|
|
161
|
+
protected onDisable(): void;
|
|
162
|
+
/**
|
|
163
|
+
* Hook: вызывается после enable()
|
|
164
|
+
*
|
|
165
|
+
* Для FieldNode: запускаем валидацию
|
|
166
|
+
*/
|
|
167
|
+
protected onEnable(): void;
|
|
168
|
+
/**
|
|
169
|
+
* Обновляет свойства компонента (например, опции для Select)
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* // Обновление опций для Select после загрузки справочников
|
|
174
|
+
* form.registrationAddress.city.updateComponentProps({
|
|
175
|
+
* options: cities
|
|
176
|
+
* });
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
updateComponentProps(props: Partial<Record<string, any>>): void;
|
|
180
|
+
/**
|
|
181
|
+
* Динамически изменяет триггер валидации (updateOn)
|
|
182
|
+
* Полезно для адаптивной валидации - например, переключиться на instant feedback после первого submit
|
|
183
|
+
*
|
|
184
|
+
* @param updateOn - новый триггер валидации: 'change' | 'blur' | 'submit'
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* // Сценарий 1: Instant feedback после submit
|
|
189
|
+
* const form = new GroupNode({
|
|
190
|
+
* email: {
|
|
191
|
+
* value: '',
|
|
192
|
+
* component: Input,
|
|
193
|
+
* updateOn: 'submit', // Изначально валидация только при submit
|
|
194
|
+
* validators: [required, email]
|
|
195
|
+
* }
|
|
196
|
+
* });
|
|
197
|
+
*
|
|
198
|
+
* await form.submit(async (values) => {
|
|
199
|
+
* // После submit переключаем на instant feedback
|
|
200
|
+
* form.email.setUpdateOn('change');
|
|
201
|
+
* await api.save(values);
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* // Теперь валидация происходит при каждом изменении
|
|
205
|
+
*
|
|
206
|
+
* // Сценарий 2: Прогрессивное улучшение
|
|
207
|
+
* form.email.setUpdateOn('blur'); // Сначала только при blur
|
|
208
|
+
* // ... пользователь начинает вводить ...
|
|
209
|
+
* form.email.setUpdateOn('change'); // Переключаем на change для real-time feedback
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
setUpdateOn(updateOn: 'change' | 'blur' | 'submit'): void;
|
|
213
|
+
getUpdateOn(): 'change' | 'blur' | 'submit';
|
|
214
|
+
/**
|
|
215
|
+
* Подписка на изменения значения поля
|
|
216
|
+
* Автоматически отслеживает изменения через @preact/signals effect
|
|
217
|
+
*
|
|
218
|
+
* @param callback - Функция, вызываемая при изменении значения
|
|
219
|
+
* @returns Функция отписки для cleanup
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const unsubscribe = form.email.watch((value) => {
|
|
224
|
+
* console.log('Email changed:', value);
|
|
225
|
+
* });
|
|
226
|
+
*
|
|
227
|
+
* // Cleanup
|
|
228
|
+
* useEffect(() => unsubscribe, []);
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
watch(callback: (value: T) => void | Promise<void>): () => void;
|
|
232
|
+
/**
|
|
233
|
+
* Вычисляемое значение из других полей
|
|
234
|
+
* Автоматически обновляет текущее поле при изменении источников
|
|
235
|
+
*
|
|
236
|
+
* @param sources - Массив ReadonlySignal для отслеживания
|
|
237
|
+
* @param computeFn - Функция вычисления нового значения
|
|
238
|
+
* @returns Функция отписки для cleanup
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* // Автоматический расчет первоначального взноса (20% от стоимости)
|
|
243
|
+
* const dispose = form.initialPayment.computeFrom(
|
|
244
|
+
* [form.propertyValue.value],
|
|
245
|
+
* (propertyValue) => {
|
|
246
|
+
* return propertyValue ? propertyValue * 0.2 : null;
|
|
247
|
+
* }
|
|
248
|
+
* );
|
|
249
|
+
*
|
|
250
|
+
* // Cleanup
|
|
251
|
+
* useEffect(() => dispose, []);
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
computeFrom<TSource extends readonly unknown[]>(sources: ReadonlySignal<TSource[number]>[], computeFn: (...values: TSource) => T): () => void;
|
|
255
|
+
/**
|
|
256
|
+
* Очистить все ресурсы и таймеры
|
|
257
|
+
* Должен вызываться при unmount компонента
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* useEffect(() => {
|
|
262
|
+
* return () => {
|
|
263
|
+
* field.dispose();
|
|
264
|
+
* };
|
|
265
|
+
* }, []);
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
dispose(): void;
|
|
269
|
+
}
|