@reformer/core 10.2.0 → 11.0.0-beta.2
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/dist/behaviors.js +134 -134
- package/dist/form/form-submitter.d.ts +0 -4
- package/dist/form/hooks/types.d.ts +3 -3
- package/dist/form/index.d.ts +0 -3
- package/dist/form/nodes/array-node.d.ts +0 -84
- package/dist/form/nodes/form-node.d.ts +0 -14
- package/dist/form/nodes/group-node.d.ts +0 -4
- package/dist/form/status-machine.d.ts +0 -38
- package/dist/form/types/contracts.d.ts +0 -6
- package/dist/form/types/deep-schema.d.ts +0 -9
- package/dist/form/types/index.d.ts +4 -38
- package/dist/form/types/schema-node.d.ts +13 -16
- package/dist/form/types/validation-schema.d.ts +0 -25
- package/dist/form/unique-id.d.ts +3 -11
- package/dist/form/validators.d.ts +8 -3
- package/dist/form-model-DhW2HZOB.js +323 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +448 -636
- package/dist/runtime-token.d.ts +23 -0
- package/dist/state/form-model.d.ts +14 -0
- package/dist/state/index.d.ts +2 -1
- package/dist/state/types.d.ts +39 -11
- package/dist/state.js +18 -18
- package/dist/validation.js +1 -1
- package/dist/validators.d.ts +0 -4
- package/dist/validators.js +88 -122
- package/docs/llms/01-api-reference.md +63 -0
- package/docs/llms/02-quick-start.md +143 -0
- package/docs/llms/03-api-signatures.md +273 -0
- package/docs/llms/04-common-patterns.md +202 -0
- package/docs/llms/05-common-mistakes.md +167 -0
- package/docs/llms/06-troubleshooting.md +11 -0
- package/docs/llms/07-complete-import.md +99 -0
- package/docs/llms/08-form-types.md +47 -0
- package/docs/llms/09-formschema.md +143 -0
- package/docs/llms/10-arrays.md +161 -0
- package/docs/llms/11-async-watchfield.md +53 -0
- package/docs/llms/12-array-cleanup.md +31 -0
- package/docs/llms/13-multi-step.md +91 -0
- package/docs/llms/14-extended-mistakes.md +98 -0
- package/docs/llms/15-project-structure.md +125 -0
- package/docs/llms/16-ui-components.md +189 -0
- package/docs/llms/17-nonexistent-api.md +93 -0
- package/docs/llms/18-conditional-fields.md +183 -0
- package/docs/llms/19-reading-values.md +88 -0
- package/docs/llms/20-compute-vs-watch.md +147 -0
- package/docs/llms/21-array-operations.md +113 -0
- package/docs/llms/22-cycle-detection.md +86 -0
- package/docs/llms/23-copy-from.md +141 -0
- package/docs/llms/24-sync-fields.md +114 -0
- package/docs/llms/25-reset-when.md +115 -0
- package/docs/llms/26-transform-value.md +136 -0
- package/docs/llms/27-revalidate-when.md +132 -0
- package/docs/llms/28-submit-and-reset.md +259 -0
- package/docs/llms/29-async-preload.md +193 -0
- package/docs/llms/30-type-safety-recipes.md +159 -0
- package/docs/llms/31-async-validator-debounce.md +135 -0
- package/docs/llms/32-async-options-loading.md +108 -0
- package/docs/llms/33-validation-strategy.md +193 -0
- package/llms.txt +219 -1533
- package/package.json +33 -10
- package/dist/derived-registry-CluZCQ7U.js +0 -16
- package/dist/form-model-DYCzGGKF.js +0 -286
package/llms.txt
CHANGED
|
@@ -2259,9 +2259,38 @@ model.$.email.peek(); // нереактивный снимок
|
|
|
2259
2259
|
model.$.address.city.value; // сигнал вложенного поля (≡ model.address.$.city у под-модели)
|
|
2260
2260
|
|
|
2261
2261
|
// весь объект
|
|
2262
|
-
model.get(); // снимок { email, address: { city }, ... } — для submit
|
|
2262
|
+
model.get(); // НЕреактивный снимок { email, address: { city }, ... } — для submit
|
|
2263
2263
|
```
|
|
2264
2264
|
|
|
2265
|
+
> ⚠️ `model.get()` и `model.isDirty()` читают через `peek()` — внутри `effect`/`computed` они НЕ
|
|
2266
|
+
> создают зависимостей. `computed(() => model.get())` никогда не пересчитается. Для реактивного
|
|
2267
|
+
> чтения всего объекта — узел дерева `$` (ниже).
|
|
2268
|
+
|
|
2269
|
+
### Подписка на группу и на модель целиком
|
|
2270
|
+
|
|
2271
|
+
Каждый узел дерева `$` — сигнал: лист отдаёт `PathAwareSignal`, а корень, вложенные объекты-группы
|
|
2272
|
+
и массивы — `ReadonlySignal` агрегированного значения поддерева. Поэтому подписаться можно на любом
|
|
2273
|
+
уровне, а не только на конкретном поле.
|
|
2274
|
+
|
|
2275
|
+
```typescript
|
|
2276
|
+
model.$.subscribe((all) => autosave(all)); // любое изменение модели; all: T целиком
|
|
2277
|
+
model.$.address.subscribe((addr) => ...); // только поддерево address
|
|
2278
|
+
model.$.address.value; // реактивный снимок группы
|
|
2279
|
+
model.$.address.peek(); // нереактивный снимок группы
|
|
2280
|
+
model.$.items.subscribe((rows) => ...); // массив: и правка элемента, и push/removeAt/move
|
|
2281
|
+
|
|
2282
|
+
// узел — обычный ReadonlySignal, поэтому принимается операциями слоя данных
|
|
2283
|
+
watchField(model.$.address, (addr) => geocode(addr));
|
|
2284
|
+
```
|
|
2285
|
+
|
|
2286
|
+
Дети узла доступны как раньше — `model.$.address.city` по-прежнему сигнал поля. Подписчик вызывается
|
|
2287
|
+
сразу с текущим значением (семантика `Signal.subscribe`), а `model.set(...)`/`model.reset()`
|
|
2288
|
+
уведомляют один раз, а не по разу на поле.
|
|
2289
|
+
|
|
2290
|
+
> ⚠️ Доступ к полю выигрывает у свойства сигнала: если в форме есть поле с именем `value`, `peek`,
|
|
2291
|
+
> `subscribe`, `valueOf`, `toString`, `toJSON` или `brand`, то `model.$.<группа>.<это имя>` вернёт
|
|
2292
|
+
> сигнал поля. `subscribe` при этом продолжает работать.
|
|
2293
|
+
|
|
2265
2294
|
### В behaviors — читаем model напрямую
|
|
2266
2295
|
|
|
2267
2296
|
`compute`/`onChange`/условия `when` читают значения из value-модели (`model.field`) —
|
|
@@ -2411,6 +2440,14 @@ import { watchField } from '@reformer/core';
|
|
|
2411
2440
|
const stop = watchField(model.$.country, () => { model.city = ''; });
|
|
2412
2441
|
```
|
|
2413
2442
|
|
|
2443
|
+
Источником может быть не только поле: узлы-контейнеры дерева `$` (корень, группы, массивы) — тоже
|
|
2444
|
+
`ReadonlySignal`, поэтому за поддеревом целиком следят без перечисления полей.
|
|
2445
|
+
|
|
2446
|
+
```typescript
|
|
2447
|
+
watchField(model.$.address, (addr) => geocode(addr)); // любое поле address
|
|
2448
|
+
watchField(model.$, (all) => autosave(all)); // любое поле формы
|
|
2449
|
+
```
|
|
2450
|
+
|
|
2414
2451
|
### Rule of Thumb
|
|
2415
2452
|
|
|
2416
2453
|
| Scenario | Use |
|
|
@@ -2419,6 +2456,7 @@ const stop = watchField(model.$.country, () => { model.city = ''; });
|
|
|
2419
2456
|
| Производное с явными зависимостями | `computeFrom` |
|
|
2420
2457
|
| Async-реакция, обновление componentProps | `onChange` (debounce + AbortSignal) |
|
|
2421
2458
|
| Простая синхронная реакция (примитив) | `watchField` |
|
|
2459
|
+
| Реакция на любое изменение группы/формы | `watchField(model.$.<группа>)` или `.subscribe` |
|
|
2422
2460
|
|
|
2423
2461
|
### Chained computeds
|
|
2424
2462
|
|
|
@@ -4324,22 +4362,6 @@ export type AnyFunction = (...args: never[]) => unknown;
|
|
|
4324
4362
|
|
|
4325
4363
|
_Source: src/form/types/index.ts_
|
|
4326
4364
|
|
|
4327
|
-
### ArrayConfig
|
|
4328
|
-
|
|
4329
|
-
**Kind:** `interface`
|
|
4330
|
-
|
|
4331
|
-
Конфигурация массива
|
|
4332
|
-
|
|
4333
|
-
**Signature:**
|
|
4334
|
-
```typescript
|
|
4335
|
-
export interface ArrayConfig<T extends object> {
|
|
4336
|
-
itemSchema: FormSchema<T>;
|
|
4337
|
-
initial?: Partial<T>[];
|
|
4338
|
-
}
|
|
4339
|
-
```
|
|
4340
|
-
|
|
4341
|
-
_Source: src/form/types/deep-schema.ts_
|
|
4342
|
-
|
|
4343
4365
|
### ArrayControlState
|
|
4344
4366
|
|
|
4345
4367
|
**Kind:** `interface`
|
|
@@ -4484,7 +4506,7 @@ return (
|
|
|
4484
4506
|
<PhoneItem
|
|
4485
4507
|
key={item.id}
|
|
4486
4508
|
control={item}
|
|
4487
|
-
onRemove={() => control.
|
|
4509
|
+
onRemove={() => control.removeAt(index)}
|
|
4488
4510
|
/>
|
|
4489
4511
|
))}
|
|
4490
4512
|
|
|
@@ -4552,28 +4574,6 @@ export interface ArrayNodeLike {
|
|
|
4552
4574
|
|
|
4553
4575
|
_Source: src/form/types/index.ts_
|
|
4554
4576
|
|
|
4555
|
-
### AsyncValidator
|
|
4556
|
-
|
|
4557
|
-
**Kind:** `type`
|
|
4558
|
-
|
|
4559
|
-
Чистый асинхронный валидатор поля. Та же тройка аргументов `(value, scope, root)`, что у
|
|
4560
|
-
{@link Validator}, но возвращает `Promise`.
|
|
4561
|
-
|
|
4562
|
-
**Signature:**
|
|
4563
|
-
```typescript
|
|
4564
|
-
export type AsyncValidator<TForm, TField> = (
|
|
4565
|
-
value: TField,
|
|
4566
|
-
scope: unknown,
|
|
4567
|
-
root: FormModel<TForm>
|
|
4568
|
-
) => Promise<ValidationError | null>;
|
|
4569
|
-
```
|
|
4570
|
-
|
|
4571
|
-
**Deprecated:** Осиротевший остаток удалённого оператора `validateAsync` (Ф7). Рантаймом не
|
|
4572
|
-
потребляется — живой async-путь узла поля использует `AsyncValidatorFn` `(value, { signal })`.
|
|
4573
|
-
Экспортируется только ради обратной совместимости.
|
|
4574
|
-
|
|
4575
|
-
_Source: src/form/types/validation-schema.ts_
|
|
4576
|
-
|
|
4577
4577
|
### AsyncValidatorFn
|
|
4578
4578
|
|
|
4579
4579
|
**Kind:** `type`
|
|
@@ -4677,22 +4677,6 @@ computeFrom([model.$.price, model.$.qty], model.$.total, (price, qty) => price *
|
|
|
4677
4677
|
|
|
4678
4678
|
_Source: src/state/behaviors-value.ts_
|
|
4679
4679
|
|
|
4680
|
-
### ConditionFn
|
|
4681
|
-
|
|
4682
|
-
**Kind:** `type`
|
|
4683
|
-
|
|
4684
|
-
Функция-предикат `(value) => boolean`.
|
|
4685
|
-
|
|
4686
|
-
**Signature:**
|
|
4687
|
-
```typescript
|
|
4688
|
-
export type ConditionFn<T> = (value: T) => boolean;
|
|
4689
|
-
```
|
|
4690
|
-
|
|
4691
|
-
**Deprecated:** Осиротевший остаток удалённого оператора `applyWhen` (Ф7). Рантаймом не
|
|
4692
|
-
потребляется; экспортируется только ради обратной совместимости.
|
|
4693
|
-
|
|
4694
|
-
_Source: src/form/types/validation-schema.ts_
|
|
4695
|
-
|
|
4696
4680
|
### ConfigWithSchema
|
|
4697
4681
|
|
|
4698
4682
|
**Kind:** `interface`
|
|
@@ -4747,6 +4731,40 @@ copyFrom(model.$.email, model.$.emailAdditional, { when: () => model.sameEmail }
|
|
|
4747
4731
|
|
|
4748
4732
|
_Source: src/state/behaviors-value.ts_
|
|
4749
4733
|
|
|
4734
|
+
### CORE_RUNTIME_TOKEN
|
|
4735
|
+
|
|
4736
|
+
**Kind:** `const`
|
|
4737
|
+
|
|
4738
|
+
Штамп копии рантайма ядра.
|
|
4739
|
+
|
|
4740
|
+
Единственное назначение — быть объектом, уникальным в пределах ОДНОЙ копии модуля. Две
|
|
4741
|
+
независимо загруженные копии `@reformer/core` дадут два разных объекта, и по их несовпадению
|
|
4742
|
+
guard распознаёт дубль рантайма.
|
|
4743
|
+
|
|
4744
|
+
Почему именно объект, а не строка с версией: две копии ОДНОЙ версии ломают всё ровно так же,
|
|
4745
|
+
как две копии разных версий, — раздваиваются модульные `WeakMap` (`derived-registry`,
|
|
4746
|
+
`signal-node-registry`) и перестают работать проверки `instanceof Signal`. Сравнение версий
|
|
4747
|
+
такой случай пропустило бы.
|
|
4748
|
+
|
|
4749
|
+
**Signature:**
|
|
4750
|
+
```typescript
|
|
4751
|
+
export const CORE_RUNTIME_TOKEN: object
|
|
4752
|
+
```
|
|
4753
|
+
|
|
4754
|
+
**Examples:**
|
|
4755
|
+
|
|
4756
|
+
```ts
|
|
4757
|
+
import { CORE_RUNTIME_TOKEN } from '@reformer/core';
|
|
4758
|
+
import { stampRuntime } from '@reformer/form-registry/guard';
|
|
4759
|
+
|
|
4760
|
+
stampRuntime('@reformer/core', CORE_RUNTIME_TOKEN);
|
|
4761
|
+
```
|
|
4762
|
+
|
|
4763
|
+
**See also:**
|
|
4764
|
+
- `@reformer/form-registry/guard`
|
|
4765
|
+
|
|
4766
|
+
_Source: src/runtime-token.ts_
|
|
4767
|
+
|
|
4750
4768
|
### createForm
|
|
4751
4769
|
|
|
4752
4770
|
**Kind:** `function`
|
|
@@ -4952,43 +4970,6 @@ disableWhen(model.$.discount, () => model.plan !== 'promo', { resetOnDisable: tr
|
|
|
4952
4970
|
|
|
4953
4971
|
_Source: src/form/behaviors-node.ts_
|
|
4954
4972
|
|
|
4955
|
-
### email
|
|
4956
|
-
|
|
4957
|
-
**Kind:** `function`
|
|
4958
|
-
|
|
4959
|
-
Фабрика валидатора формата email.
|
|
4960
|
-
|
|
4961
|
-
Проверяет по упрощённому regex `^[^\s@]+@[^\s@]+\.[^\s@]+$`. Пустые значения
|
|
4962
|
-
(`''`/`null`/`undefined`) пропускаются (используйте {@link required} для обязательности).
|
|
4963
|
-
|
|
4964
|
-
**Signature:**
|
|
4965
|
-
```typescript
|
|
4966
|
-
export function email<TForm = unknown, TField extends string | null | undefined = string>(
|
|
4967
|
-
options?: ValidateOptions
|
|
4968
|
-
): Validator<TForm, TField>
|
|
4969
|
-
```
|
|
4970
|
-
|
|
4971
|
-
**Parameters:**
|
|
4972
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
4973
|
-
|
|
4974
|
-
**Returns:** Чистый валидатор {@link Validator} для строкового поля
|
|
4975
|
-
|
|
4976
|
-
**Examples:**
|
|
4977
|
-
|
|
4978
|
-
Проверка формата email
|
|
4979
|
-
```typescript
|
|
4980
|
-
import { required, email } from '@reformer/core/validators';
|
|
4981
|
-
|
|
4982
|
-
// Внутри FieldConfig схемы формы:
|
|
4983
|
-
email: {
|
|
4984
|
-
value: model.$.email,
|
|
4985
|
-
component: Input,
|
|
4986
|
-
validators: [required(), email({ message: 'Введите корректный email' })],
|
|
4987
|
-
},
|
|
4988
|
-
```
|
|
4989
|
-
|
|
4990
|
-
_Source: src/form/validation/validators/email.ts_
|
|
4991
|
-
|
|
4992
4973
|
### enableWhen
|
|
4993
4974
|
|
|
4994
4975
|
**Kind:** `function`
|
|
@@ -5278,12 +5259,12 @@ export interface FieldControlState<T> {
|
|
|
5278
5259
|
|
|
5279
5260
|
/**
|
|
5280
5261
|
* Пользовательские props для передачи в UI-компоненты.
|
|
5281
|
-
* Устанавливаются через {@link FieldNode.
|
|
5262
|
+
* Устанавливаются через {@link FieldNode.updateComponentProps}.
|
|
5282
5263
|
*
|
|
5283
5264
|
* @example
|
|
5284
5265
|
* ```tsx
|
|
5285
5266
|
* // Установка props
|
|
5286
|
-
* field.
|
|
5267
|
+
* field.updateComponentProps({
|
|
5287
5268
|
* placeholder: 'Enter email...',
|
|
5288
5269
|
* maxLength: 100,
|
|
5289
5270
|
* autoComplete: 'email'
|
|
@@ -5383,23 +5364,6 @@ console.log(field.valid.value); // true
|
|
|
5383
5364
|
|
|
5384
5365
|
_Source: src/form/nodes/field-node.ts_
|
|
5385
5366
|
|
|
5386
|
-
### FieldPathSegment
|
|
5387
|
-
|
|
5388
|
-
**Kind:** `type`
|
|
5389
|
-
|
|
5390
|
-
Тип для путей к полям (field paths)
|
|
5391
|
-
Используется в навигации по полям вместо any
|
|
5392
|
-
|
|
5393
|
-
**Signature:**
|
|
5394
|
-
```typescript
|
|
5395
|
-
export type FieldPathSegment = {
|
|
5396
|
-
key: string;
|
|
5397
|
-
index?: number;
|
|
5398
|
-
};
|
|
5399
|
-
```
|
|
5400
|
-
|
|
5401
|
-
_Source: src/form/types/index.ts_
|
|
5402
|
-
|
|
5403
5367
|
### FieldStatus
|
|
5404
5368
|
|
|
5405
5369
|
**Kind:** `type`
|
|
@@ -5413,70 +5377,6 @@ export type FieldStatus = 'valid' | 'invalid' | 'pending' | 'disabled';
|
|
|
5413
5377
|
|
|
5414
5378
|
_Source: src/form/types/contracts.ts_
|
|
5415
5379
|
|
|
5416
|
-
### FileLike
|
|
5417
|
-
|
|
5418
|
-
**Kind:** `interface`
|
|
5419
|
-
|
|
5420
|
-
Минимальный файлоподобный контракт, с которым работают file-валидаторы:
|
|
5421
|
-
нативный `File`, сериализуемый дескриптор загруженного файла и т.п.
|
|
5422
|
-
|
|
5423
|
-
**Signature:**
|
|
5424
|
-
```typescript
|
|
5425
|
-
export interface FileLike {
|
|
5426
|
-
name: string;
|
|
5427
|
-
size?: number;
|
|
5428
|
-
type?: string;
|
|
5429
|
-
}
|
|
5430
|
-
```
|
|
5431
|
-
|
|
5432
|
-
_Source: src/form/validation/validators/file-utils.ts_
|
|
5433
|
-
|
|
5434
|
-
### fileType
|
|
5435
|
-
|
|
5436
|
-
**Kind:** `function`
|
|
5437
|
-
|
|
5438
|
-
Фабрика валидатора типа файла.
|
|
5439
|
-
|
|
5440
|
-
Проверяет каждый файл против accept-строки в синтаксисе нативного атрибута
|
|
5441
|
-
`<input type="file" accept>`: расширения (`.pdf`), точные MIME (`image/png`),
|
|
5442
|
-
wildcard-категории (`image/*`), список через запятую. Матчинг регистронезависимый,
|
|
5443
|
-
по `type` и/или расширению из `name` ({@link matchesFileAccept}).
|
|
5444
|
-
|
|
5445
|
-
Нужен потому, что нативный `accept` — только подсказка пикеру: на drag-and-drop
|
|
5446
|
-
и «All files» он не действует. Пустые значения (`null`/`undefined`/`''`/`[]`)
|
|
5447
|
-
пропускаются (используйте {@link required} для обязательности).
|
|
5448
|
-
|
|
5449
|
-
**Signature:**
|
|
5450
|
-
```typescript
|
|
5451
|
-
export function fileType<TForm = unknown, TField = unknown>(
|
|
5452
|
-
accept: string,
|
|
5453
|
-
options?: ValidateOptions
|
|
5454
|
-
): Validator<TForm, TField>
|
|
5455
|
-
```
|
|
5456
|
-
|
|
5457
|
-
**Parameters:**
|
|
5458
|
-
- `accept` — - Accept-строка допустимых типов, например `'image/*,.pdf'`
|
|
5459
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
5460
|
-
попадают `accept` и `fileName` (первый нарушивший файл).
|
|
5461
|
-
|
|
5462
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
5463
|
-
|
|
5464
|
-
**Examples:**
|
|
5465
|
-
|
|
5466
|
-
Только изображения и PDF
|
|
5467
|
-
```typescript
|
|
5468
|
-
import { fileType } from '@reformer/core/validators';
|
|
5469
|
-
|
|
5470
|
-
// Внутри FieldConfig схемы формы:
|
|
5471
|
-
documents: {
|
|
5472
|
-
value: model.$.documents,
|
|
5473
|
-
component: FileUploadField,
|
|
5474
|
-
validators: [fileType('image/*,.pdf', { message: 'Только изображения или PDF' })],
|
|
5475
|
-
},
|
|
5476
|
-
```
|
|
5477
|
-
|
|
5478
|
-
_Source: src/form/validation/validators/file-type.ts_
|
|
5479
|
-
|
|
5480
5380
|
### FormArrayProxy
|
|
5481
5381
|
|
|
5482
5382
|
**Kind:** `type`
|
|
@@ -5857,19 +5757,25 @@ export interface FormSchemaNode {
|
|
|
5857
5757
|
component?: ElementType;
|
|
5858
5758
|
/** Props компонента. Также «клапан» для вложенности под-узлов (напр. steps визарда). */
|
|
5859
5759
|
componentProps?: Record<string, unknown>;
|
|
5860
|
-
validators?: SchemaValidator[];
|
|
5861
|
-
asyncValidators?: SchemaValidator[];
|
|
5862
5760
|
updateOn?: 'change' | 'blur' | 'submit';
|
|
5863
5761
|
disabled?: boolean;
|
|
5864
5762
|
/** Задержка (мс) перед запуском асинхронной валидации. */
|
|
5865
5763
|
debounce?: number;
|
|
5866
5764
|
/** Идентификатор узла (для wizard/tabs/renderBehavior). */
|
|
5867
5765
|
selector?: string;
|
|
5766
|
+
/**
|
|
5767
|
+
* ⚠️ Рантайм этого поля НЕ ЧИТАЕТ — `renderer-react` берёт testId из `componentProps.testId`
|
|
5768
|
+
* (иначе выводит из пути сигнала). Поле оставлено только потому, что `RenderSchemaNode`
|
|
5769
|
+
* рендерера объявляет свой одноимённый; пишите `componentProps: { testId: '…' }`.
|
|
5770
|
+
*/
|
|
5868
5771
|
testId?: string;
|
|
5869
|
-
/**
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5772
|
+
/**
|
|
5773
|
+
* Содержимое узла: под-узлы (даёт контекстную типизацию вложенным литералам — value/validators/when)
|
|
5774
|
+
* и текстовые части. Текст (литерал, число, сигнал модели) — такой же ребёнок, как узел: core его
|
|
5775
|
+
* не интерпретирует (обход пропускает примитивы и не спускается внутрь сигнала), а рендерер
|
|
5776
|
+
* выводит на своём месте в порядке следования.
|
|
5777
|
+
*/
|
|
5778
|
+
children?: readonly (FormSchemaNode | string | number | Signal<any>)[];
|
|
5873
5779
|
/** Реактивный массив модели (`model.<path>`) — маркер узла-массива (вместе с `item`). */
|
|
5874
5780
|
array?: SchemaArrayControl;
|
|
5875
5781
|
/** Схема элемента массива: под-модель элемента → узел поддерева. */
|
|
@@ -5887,43 +5793,6 @@ export interface FormSchemaNode {
|
|
|
5887
5793
|
|
|
5888
5794
|
_Source: src/form/types/schema-node.ts_
|
|
5889
5795
|
|
|
5890
|
-
### FormStatusMachine
|
|
5891
|
-
|
|
5892
|
-
**Kind:** `class`
|
|
5893
|
-
|
|
5894
|
-
FormStatusMachine - управляет состоянием поля формы
|
|
5895
|
-
|
|
5896
|
-
Предоставляет:
|
|
5897
|
-
- Единый источник истины для статуса
|
|
5898
|
-
- Computed signals для derived состояний (valid, invalid, pending, disabled)
|
|
5899
|
-
- Валидацию переходов между состояниями
|
|
5900
|
-
|
|
5901
|
-
**Signature:**
|
|
5902
|
-
```typescript
|
|
5903
|
-
export class FormStatusMachine {
|
|
5904
|
-
/** Внутренний сигнал статуса */ /* … */ }
|
|
5905
|
-
```
|
|
5906
|
-
|
|
5907
|
-
**Examples:**
|
|
5908
|
-
|
|
5909
|
-
```typescript
|
|
5910
|
-
const statusMachine = new FormStatusMachine('valid');
|
|
5911
|
-
|
|
5912
|
-
// Начало валидации
|
|
5913
|
-
statusMachine.startValidation();
|
|
5914
|
-
console.log(statusMachine.pending.value); // true
|
|
5915
|
-
|
|
5916
|
-
// Завершение валидации с ошибками
|
|
5917
|
-
statusMachine.completeValidation(true);
|
|
5918
|
-
console.log(statusMachine.invalid.value); // true
|
|
5919
|
-
|
|
5920
|
-
// Отключение поля
|
|
5921
|
-
statusMachine.disable();
|
|
5922
|
-
console.log(statusMachine.disabled.value); // true
|
|
5923
|
-
```
|
|
5924
|
-
|
|
5925
|
-
_Source: src/form/status-machine.ts_
|
|
5926
|
-
|
|
5927
5796
|
### FormSubmitter
|
|
5928
5797
|
|
|
5929
5798
|
**Kind:** `class`
|
|
@@ -5977,44 +5846,6 @@ export type FormValue =
|
|
|
5977
5846
|
|
|
5978
5847
|
_Source: src/form/types/contracts.ts_
|
|
5979
5848
|
|
|
5980
|
-
### futureDate
|
|
5981
|
-
|
|
5982
|
-
**Kind:** `function`
|
|
5983
|
-
|
|
5984
|
-
Фабрика валидатора, проверяющего что дата не в прошлом.
|
|
5985
|
-
|
|
5986
|
-
Дата не должна быть раньше сегодняшнего дня (сравнение по нормализованным датам).
|
|
5987
|
-
Пустые и невалидные даты пропускаются (используйте {@link required} и {@link isDate}).
|
|
5988
|
-
|
|
5989
|
-
**Signature:**
|
|
5990
|
-
```typescript
|
|
5991
|
-
export function futureDate<
|
|
5992
|
-
TForm = unknown,
|
|
5993
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
5994
|
-
>(options?: ValidateOptions): Validator<TForm, TField>
|
|
5995
|
-
```
|
|
5996
|
-
|
|
5997
|
-
**Parameters:**
|
|
5998
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
5999
|
-
|
|
6000
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты (`string | Date`)
|
|
6001
|
-
|
|
6002
|
-
**Examples:**
|
|
6003
|
-
|
|
6004
|
-
Дата не в прошлом
|
|
6005
|
-
```typescript
|
|
6006
|
-
import { required, futureDate } from '@reformer/core/validators';
|
|
6007
|
-
|
|
6008
|
-
// Внутри FieldConfig схемы формы:
|
|
6009
|
-
appointmentDate: {
|
|
6010
|
-
value: model.$.appointmentDate,
|
|
6011
|
-
component: DatePicker,
|
|
6012
|
-
validators: [required(), futureDate({ message: 'Дата записи должна быть в будущем' })],
|
|
6013
|
-
},
|
|
6014
|
-
```
|
|
6015
|
-
|
|
6016
|
-
_Source: src/form/validation/validators/future-date.ts_
|
|
6017
|
-
|
|
6018
5849
|
### getNodeForSignal
|
|
6019
5850
|
|
|
6020
5851
|
**Kind:** `function`
|
|
@@ -6130,42 +5961,6 @@ export interface GroupNodeConfig<T> {
|
|
|
6130
5961
|
|
|
6131
5962
|
_Source: src/form/types/index.ts_
|
|
6132
5963
|
|
|
6133
|
-
### integer
|
|
6134
|
-
|
|
6135
|
-
**Kind:** `function`
|
|
6136
|
-
|
|
6137
|
-
Фабрика валидатора, проверяющего что число — целое.
|
|
6138
|
-
|
|
6139
|
-
Пустые значения и не-числа пропускаются (используйте {@link required} и {@link isNumber}).
|
|
6140
|
-
|
|
6141
|
-
**Signature:**
|
|
6142
|
-
```typescript
|
|
6143
|
-
export function integer<TForm = unknown, TField extends number | null | undefined = number>(
|
|
6144
|
-
options?: ValidateOptions
|
|
6145
|
-
): Validator<TForm, TField>
|
|
6146
|
-
```
|
|
6147
|
-
|
|
6148
|
-
**Parameters:**
|
|
6149
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
6150
|
-
|
|
6151
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
6152
|
-
|
|
6153
|
-
**Examples:**
|
|
6154
|
-
|
|
6155
|
-
Проверка целого числа
|
|
6156
|
-
```typescript
|
|
6157
|
-
import { required, integer } from '@reformer/core/validators';
|
|
6158
|
-
|
|
6159
|
-
// Внутри FieldConfig схемы формы:
|
|
6160
|
-
count: {
|
|
6161
|
-
value: model.$.count,
|
|
6162
|
-
component: Input,
|
|
6163
|
-
validators: [required(), integer({ message: 'Должно быть целым числом' })],
|
|
6164
|
-
},
|
|
6165
|
-
```
|
|
6166
|
-
|
|
6167
|
-
_Source: src/form/validation/validators/integer.ts_
|
|
6168
|
-
|
|
6169
5964
|
### isArrayNode
|
|
6170
5965
|
|
|
6171
5966
|
**Kind:** `function`
|
|
@@ -6197,44 +5992,6 @@ if (isArrayNode(node)) {
|
|
|
6197
5992
|
|
|
6198
5993
|
_Source: src/form/type-guards.ts_
|
|
6199
5994
|
|
|
6200
|
-
### isDate
|
|
6201
|
-
|
|
6202
|
-
**Kind:** `function`
|
|
6203
|
-
|
|
6204
|
-
Фабрика валидатора, проверяющего что значение — валидная дата.
|
|
6205
|
-
|
|
6206
|
-
Принимает `Date` или строку, парсимую в дату. Пустые значения (`''`/`null`/`undefined`)
|
|
6207
|
-
пропускаются (используйте {@link required} для обязательности).
|
|
6208
|
-
|
|
6209
|
-
**Signature:**
|
|
6210
|
-
```typescript
|
|
6211
|
-
export function isDate<
|
|
6212
|
-
TForm = unknown,
|
|
6213
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
6214
|
-
>(options?: ValidateOptions): Validator<TForm, TField>
|
|
6215
|
-
```
|
|
6216
|
-
|
|
6217
|
-
**Parameters:**
|
|
6218
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
6219
|
-
|
|
6220
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты (`string | Date`)
|
|
6221
|
-
|
|
6222
|
-
**Examples:**
|
|
6223
|
-
|
|
6224
|
-
Проверка валидности даты
|
|
6225
|
-
```typescript
|
|
6226
|
-
import { required, isDate } from '@reformer/core/validators';
|
|
6227
|
-
|
|
6228
|
-
// Внутри FieldConfig схемы формы:
|
|
6229
|
-
eventDate: {
|
|
6230
|
-
value: model.$.eventDate,
|
|
6231
|
-
component: DatePicker,
|
|
6232
|
-
validators: [required(), isDate({ message: 'Введите корректную дату' })],
|
|
6233
|
-
},
|
|
6234
|
-
```
|
|
6235
|
-
|
|
6236
|
-
_Source: src/form/validation/validators/is-date.ts_
|
|
6237
|
-
|
|
6238
5995
|
### isDerived
|
|
6239
5996
|
|
|
6240
5997
|
**Kind:** `function`
|
|
@@ -6300,25 +6057,6 @@ if (isFieldNode(node)) {
|
|
|
6300
6057
|
|
|
6301
6058
|
_Source: src/form/type-guards.ts_
|
|
6302
6059
|
|
|
6303
|
-
### isFileLike
|
|
6304
|
-
|
|
6305
|
-
**Kind:** `function`
|
|
6306
|
-
|
|
6307
|
-
Проверяет, что значение файлоподобно: объект со строковым `name` и опциональными
|
|
6308
|
-
числовым `size` / строковым `type`.
|
|
6309
|
-
|
|
6310
|
-
**Signature:**
|
|
6311
|
-
```typescript
|
|
6312
|
-
export function isFileLike(value: unknown): value is FileLike
|
|
6313
|
-
```
|
|
6314
|
-
|
|
6315
|
-
**Parameters:**
|
|
6316
|
-
- `value` — - Проверяемое значение
|
|
6317
|
-
|
|
6318
|
-
**Returns:** `true`, если значение соответствует {@link FileLike}
|
|
6319
|
-
|
|
6320
|
-
_Source: src/form/validation/validators/file-utils.ts_
|
|
6321
|
-
|
|
6322
6060
|
### isFormNode
|
|
6323
6061
|
|
|
6324
6062
|
**Kind:** `function`
|
|
@@ -6377,43 +6115,28 @@ if (isGroupNode(node)) {
|
|
|
6377
6115
|
|
|
6378
6116
|
_Source: src/form/type-guards.ts_
|
|
6379
6117
|
|
|
6380
|
-
###
|
|
6118
|
+
### isModelContainerSignal
|
|
6381
6119
|
|
|
6382
6120
|
**Kind:** `function`
|
|
6383
6121
|
|
|
6384
|
-
|
|
6122
|
+
Узел дерева `model.$` — контейнер (группа/массив), а не лист?
|
|
6385
6123
|
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6124
|
+
Контейнерный узел структурно совместим с `ReadonlySignal` (`peek`/`value`/`subscribe`), поэтому
|
|
6125
|
+
duck-typing «есть `peek` ⇒ это лист» на нём даёт ложное срабатывание. Этот guard — надёжный
|
|
6126
|
+
способ различить: обходчикам дерева нужно спускаться в контейнер, а не читать его целиком.
|
|
6389
6127
|
|
|
6390
6128
|
**Signature:**
|
|
6391
6129
|
```typescript
|
|
6392
|
-
export function
|
|
6393
|
-
options?: ValidateOptions
|
|
6394
|
-
): Validator<TForm, TField>
|
|
6130
|
+
export function isModelContainerSignal(value: unknown): boolean
|
|
6395
6131
|
```
|
|
6396
6132
|
|
|
6397
|
-
**Parameters:**
|
|
6398
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
6399
|
-
|
|
6400
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
6401
|
-
|
|
6402
6133
|
**Examples:**
|
|
6403
6134
|
|
|
6404
|
-
Проверка, что значение — число
|
|
6405
6135
|
```typescript
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
// Внутри FieldConfig схемы формы:
|
|
6409
|
-
amount: {
|
|
6410
|
-
value: model.$.amount,
|
|
6411
|
-
component: Input,
|
|
6412
|
-
validators: [required(), isNumber({ message: 'Введите число' })],
|
|
6413
|
-
},
|
|
6136
|
+
const isLeaf = (v: unknown) => isSignalLike(v) && !isModelContainerSignal(v);
|
|
6414
6137
|
```
|
|
6415
6138
|
|
|
6416
|
-
_Source: src/form
|
|
6139
|
+
_Source: src/state/form-model.ts_
|
|
6417
6140
|
|
|
6418
6141
|
### markDerived
|
|
6419
6142
|
|
|
@@ -6451,577 +6174,23 @@ markDerived(model.$.total);
|
|
|
6451
6174
|
|
|
6452
6175
|
_Source: src/state/derived-registry.ts_
|
|
6453
6176
|
|
|
6454
|
-
###
|
|
6455
|
-
|
|
6456
|
-
**Kind:** `function`
|
|
6457
|
-
|
|
6458
|
-
Проверяет файл против accept-паттерна в синтаксисе нативного атрибута
|
|
6459
|
-
`<input type="file" accept>`: список через запятую из расширений (`.pdf`),
|
|
6460
|
-
точных MIME (`image/png`) и wildcard-категорий (`image/*`). Регистронезависимо.
|
|
6461
|
-
|
|
6462
|
-
Нужен собственный матчер, потому что `accept` у нативного input — только подсказка
|
|
6463
|
-
пикеру: на drag-and-drop и на программное значение он не действует.
|
|
6464
|
-
|
|
6465
|
-
**Signature:**
|
|
6466
|
-
```typescript
|
|
6467
|
-
export function matchesFileAccept(file: Pick<FileLike, 'name' | 'type'>, accept: string): boolean
|
|
6468
|
-
```
|
|
6469
|
-
|
|
6470
|
-
**Parameters:**
|
|
6471
|
-
- `file` — - Файлоподобное значение (`name` + опциональный `type`)
|
|
6472
|
-
- `accept` — - Accept-строка; пустая/пробельная строка матчит всё
|
|
6473
|
-
|
|
6474
|
-
**Returns:** `true`, если файл подходит хотя бы под один паттерн
|
|
6475
|
-
|
|
6476
|
-
_Source: src/form/validation/validators/file-utils.ts_
|
|
6477
|
-
|
|
6478
|
-
### max
|
|
6177
|
+
### ModelApi
|
|
6479
6178
|
|
|
6480
|
-
**Kind:** `
|
|
6179
|
+
**Kind:** `interface`
|
|
6481
6180
|
|
|
6482
|
-
|
|
6181
|
+
API уровня модели (доступно на корне, под-моделях вложенных объектов-групп и элементов массива).
|
|
6483
6182
|
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
**Signature:**
|
|
6487
|
-
```typescript
|
|
6488
|
-
export function max<TForm = unknown, TField extends number | null | undefined = number>(
|
|
6489
|
-
maxValue: number,
|
|
6490
|
-
options?: ValidateOptions
|
|
6491
|
-
): Validator<TForm, TField>
|
|
6492
|
-
```
|
|
6493
|
-
|
|
6494
|
-
**Parameters:**
|
|
6495
|
-
- `maxValue` — - Максимально допустимое значение (включительно)
|
|
6496
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6497
|
-
попадают `max` и `actual`.
|
|
6498
|
-
|
|
6499
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
6500
|
-
|
|
6501
|
-
**Examples:**
|
|
6502
|
-
|
|
6503
|
-
Максимальное значение числового поля
|
|
6504
|
-
```typescript
|
|
6505
|
-
import { required, max } from '@reformer/core/validators';
|
|
6506
|
-
|
|
6507
|
-
// Внутри FieldConfig схемы формы:
|
|
6508
|
-
quantity: { value: model.$.quantity, component: Input, validators: [max(100)] },
|
|
6509
|
-
discount: {
|
|
6510
|
-
value: model.$.discount,
|
|
6511
|
-
component: Input,
|
|
6512
|
-
validators: [required(), max(50, { message: 'Не более 50%' })],
|
|
6513
|
-
},
|
|
6514
|
-
```
|
|
6515
|
-
|
|
6516
|
-
_Source: src/form/validation/validators/max.ts_
|
|
6517
|
-
|
|
6518
|
-
### maxAge
|
|
6519
|
-
|
|
6520
|
-
**Kind:** `function`
|
|
6521
|
-
|
|
6522
|
-
Фабрика валидатора максимального возраста (по дате рождения).
|
|
6523
|
-
|
|
6524
|
-
Возраст вычисляется по дате рождения относительно сегодняшнего дня. Пустые и невалидные
|
|
6525
|
-
даты пропускаются (используйте {@link required} и {@link isDate}).
|
|
6526
|
-
|
|
6527
|
-
**Signature:**
|
|
6528
|
-
```typescript
|
|
6529
|
-
export function maxAge<
|
|
6530
|
-
TForm = unknown,
|
|
6531
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
6532
|
-
>(maxAgeValue: number, options?: ValidateOptions): Validator<TForm, TField>
|
|
6533
|
-
```
|
|
6534
|
-
|
|
6535
|
-
**Parameters:**
|
|
6536
|
-
- `maxAgeValue` — - Максимально допустимый возраст (в полных годах)
|
|
6537
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6538
|
-
попадают `maxAge` и `currentAge`.
|
|
6539
|
-
|
|
6540
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты рождения (`string | Date`)
|
|
6541
|
-
|
|
6542
|
-
**Examples:**
|
|
6543
|
-
|
|
6544
|
-
Максимальный возраст
|
|
6545
|
-
```typescript
|
|
6546
|
-
import { maxAge } from '@reformer/core/validators';
|
|
6547
|
-
|
|
6548
|
-
// Внутри FieldConfig схемы формы:
|
|
6549
|
-
birthDate: {
|
|
6550
|
-
value: model.$.birthDate,
|
|
6551
|
-
component: DatePicker,
|
|
6552
|
-
validators: [maxAge(100, { message: 'Проверьте дату рождения' })],
|
|
6553
|
-
},
|
|
6554
|
-
```
|
|
6555
|
-
|
|
6556
|
-
_Source: src/form/validation/validators/max-age.ts_
|
|
6557
|
-
|
|
6558
|
-
### maxDate
|
|
6559
|
-
|
|
6560
|
-
**Kind:** `function`
|
|
6561
|
-
|
|
6562
|
-
Фабрика валидатора максимальной даты (включительно).
|
|
6563
|
-
|
|
6564
|
-
Сравнение по нормализованным датам (время обнуляется). Пустые и невалидные даты
|
|
6565
|
-
пропускаются (используйте {@link required} и {@link isDate}).
|
|
6566
|
-
|
|
6567
|
-
**Signature:**
|
|
6568
|
-
```typescript
|
|
6569
|
-
export function maxDate<
|
|
6570
|
-
TForm = unknown,
|
|
6571
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
6572
|
-
>(maxDateValue: Date, options?: ValidateOptions): Validator<TForm, TField>
|
|
6573
|
-
```
|
|
6574
|
-
|
|
6575
|
-
**Parameters:**
|
|
6576
|
-
- `maxDateValue` — - Максимально допустимая дата (включительно)
|
|
6577
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6578
|
-
попадает `maxDate`.
|
|
6579
|
-
|
|
6580
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты (`string | Date`)
|
|
6581
|
-
|
|
6582
|
-
**Examples:**
|
|
6583
|
-
|
|
6584
|
-
Максимальная дата
|
|
6585
|
-
```typescript
|
|
6586
|
-
import { maxDate } from '@reformer/core/validators';
|
|
6587
|
-
|
|
6588
|
-
// Внутри FieldConfig схемы формы:
|
|
6589
|
-
birthDate: {
|
|
6590
|
-
value: model.$.birthDate,
|
|
6591
|
-
component: DatePicker,
|
|
6592
|
-
validators: [maxDate(new Date(), { message: 'Дата не может быть в будущем' })],
|
|
6593
|
-
},
|
|
6594
|
-
```
|
|
6595
|
-
|
|
6596
|
-
_Source: src/form/validation/validators/max-date.ts_
|
|
6597
|
-
|
|
6598
|
-
### maxFiles
|
|
6599
|
-
|
|
6600
|
-
**Kind:** `function`
|
|
6601
|
-
|
|
6602
|
-
Фабрика валидатора максимального количества файлов.
|
|
6603
|
-
|
|
6604
|
-
Работает с массивом файлов (одиночный файл считается как 1). Пустые значения
|
|
6605
|
-
(`null`/`undefined`/`''`/`[]`) пропускаются (используйте {@link required}
|
|
6606
|
-
для обязательности).
|
|
6607
|
-
|
|
6608
|
-
**Signature:**
|
|
6609
|
-
```typescript
|
|
6610
|
-
export function maxFiles<TForm = unknown, TField = unknown>(
|
|
6611
|
-
max: number,
|
|
6612
|
-
options?: ValidateOptions
|
|
6613
|
-
): Validator<TForm, TField>
|
|
6614
|
-
```
|
|
6615
|
-
|
|
6616
|
-
**Parameters:**
|
|
6617
|
-
- `max` — - Максимально допустимое количество файлов (включительно)
|
|
6618
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6619
|
-
попадают `maxFiles` и `actualCount`.
|
|
6620
|
-
|
|
6621
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
6622
|
-
|
|
6623
|
-
**Examples:**
|
|
6624
|
-
|
|
6625
|
-
Не более трёх вложений
|
|
6626
|
-
```typescript
|
|
6627
|
-
import { maxFiles } from '@reformer/core/validators';
|
|
6628
|
-
|
|
6629
|
-
// Внутри FieldConfig схемы формы:
|
|
6630
|
-
documents: {
|
|
6631
|
-
value: model.$.documents,
|
|
6632
|
-
component: FileUploadField,
|
|
6633
|
-
validators: [maxFiles(3, { message: 'Максимум 3 файла' })],
|
|
6634
|
-
},
|
|
6635
|
-
```
|
|
6636
|
-
|
|
6637
|
-
_Source: src/form/validation/validators/max-files.ts_
|
|
6638
|
-
|
|
6639
|
-
### maxFileSize
|
|
6640
|
-
|
|
6641
|
-
**Kind:** `function`
|
|
6642
|
-
|
|
6643
|
-
Фабрика валидатора максимального размера файла.
|
|
6644
|
-
|
|
6645
|
-
Работает с одиночным файлом или массивом (`File` либо файлоподобный дескриптор с
|
|
6646
|
-
`name`/`size`). Проверяется каждый файл; в ошибку попадает первый нарушивший.
|
|
6647
|
-
Пустые значения (`null`/`undefined`/`''`/`[]`) и элементы без числового `size`
|
|
6648
|
-
(например, дескриптор загруженного файла без размера) пропускаются
|
|
6649
|
-
(используйте {@link required} для обязательности).
|
|
6650
|
-
|
|
6651
|
-
**Signature:**
|
|
6652
|
-
```typescript
|
|
6653
|
-
export function maxFileSize<TForm = unknown, TField = unknown>(
|
|
6654
|
-
maxSize: number,
|
|
6655
|
-
options?: ValidateOptions
|
|
6656
|
-
): Validator<TForm, TField>
|
|
6657
|
-
```
|
|
6658
|
-
|
|
6659
|
-
**Parameters:**
|
|
6660
|
-
- `maxSize` — - Максимально допустимый размер файла в байтах (включительно)
|
|
6661
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6662
|
-
попадают `maxFileSize`, `fileName` и `actualSize`.
|
|
6663
|
-
|
|
6664
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
6665
|
-
|
|
6666
|
-
**Examples:**
|
|
6667
|
-
|
|
6668
|
-
Ограничение размера вложений
|
|
6669
|
-
```typescript
|
|
6670
|
-
import { maxFileSize } from '@reformer/core/validators';
|
|
6671
|
-
|
|
6672
|
-
// Внутри FieldConfig схемы формы:
|
|
6673
|
-
documents: {
|
|
6674
|
-
value: model.$.documents,
|
|
6675
|
-
component: FileUploadField,
|
|
6676
|
-
validators: [maxFileSize(5 * 1024 * 1024, { message: 'Файл больше 5 МБ' })],
|
|
6677
|
-
},
|
|
6678
|
-
```
|
|
6679
|
-
|
|
6680
|
-
_Source: src/form/validation/validators/max-file-size.ts_
|
|
6681
|
-
|
|
6682
|
-
### maxLength
|
|
6683
|
-
|
|
6684
|
-
**Kind:** `function`
|
|
6685
|
-
|
|
6686
|
-
Фабрика валидатора максимальной длины строки или массива.
|
|
6687
|
-
|
|
6688
|
-
Работает со строкой или массивом (проверяется `value.length`). Пустые значения
|
|
6689
|
-
(`null`/`undefined`/`''`) и значения без числового `length` пропускаются
|
|
6690
|
-
(используйте {@link required} для обязательности).
|
|
6691
|
-
|
|
6692
|
-
**Signature:**
|
|
6693
|
-
```typescript
|
|
6694
|
-
export function maxLength<TForm = unknown, TField = unknown>(
|
|
6695
|
-
maxLen: number,
|
|
6696
|
-
options?: ValidateOptions
|
|
6697
|
-
): Validator<TForm, TField>
|
|
6698
|
-
```
|
|
6699
|
-
|
|
6700
|
-
**Parameters:**
|
|
6701
|
-
- `maxLen` — - Максимально допустимая длина (включительно)
|
|
6702
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6703
|
-
попадают `maxLength` и `actualLength`.
|
|
6704
|
-
|
|
6705
|
-
**Returns:** Чистый валидатор {@link Validator} для строки или массива
|
|
6706
|
-
|
|
6707
|
-
**Examples:**
|
|
6708
|
-
|
|
6709
|
-
Максимальная длина строки
|
|
6710
|
-
```typescript
|
|
6711
|
-
import { maxLength } from '@reformer/core/validators';
|
|
6712
|
-
|
|
6713
|
-
// Внутри FieldConfig схемы формы:
|
|
6714
|
-
name: { value: model.$.name, component: Input, validators: [maxLength(50)] },
|
|
6715
|
-
bio: {
|
|
6716
|
-
value: model.$.bio,
|
|
6717
|
-
component: Textarea,
|
|
6718
|
-
validators: [maxLength(500, { message: 'Максимум 500 символов' })],
|
|
6719
|
-
},
|
|
6720
|
-
```
|
|
6721
|
-
|
|
6722
|
-
_Source: src/form/validation/validators/max-length.ts_
|
|
6723
|
-
|
|
6724
|
-
### maxTotalFileSize
|
|
6725
|
-
|
|
6726
|
-
**Kind:** `function`
|
|
6727
|
-
|
|
6728
|
-
Фабрика валидатора суммарного размера всех файлов.
|
|
6729
|
-
|
|
6730
|
-
Складывает `size` всех файлов значения (элементы без числового `size` в сумму
|
|
6731
|
-
не входят). Пустые значения (`null`/`undefined`/`''`/`[]`) пропускаются
|
|
6732
|
-
(используйте {@link required} для обязательности).
|
|
6733
|
-
|
|
6734
|
-
**Signature:**
|
|
6735
|
-
```typescript
|
|
6736
|
-
export function maxTotalFileSize<TForm = unknown, TField = unknown>(
|
|
6737
|
-
maxTotal: number,
|
|
6738
|
-
options?: ValidateOptions
|
|
6739
|
-
): Validator<TForm, TField>
|
|
6740
|
-
```
|
|
6741
|
-
|
|
6742
|
-
**Parameters:**
|
|
6743
|
-
- `maxTotal` — - Максимально допустимый суммарный размер в байтах (включительно)
|
|
6744
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6745
|
-
попадают `maxTotalFileSize` и `actualTotal`.
|
|
6746
|
-
|
|
6747
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
6748
|
-
|
|
6749
|
-
**Examples:**
|
|
6750
|
-
|
|
6751
|
-
Суммарно не более 20 МБ
|
|
6752
|
-
```typescript
|
|
6753
|
-
import { maxTotalFileSize } from '@reformer/core/validators';
|
|
6754
|
-
|
|
6755
|
-
// Внутри FieldConfig схемы формы:
|
|
6756
|
-
documents: {
|
|
6757
|
-
value: model.$.documents,
|
|
6758
|
-
component: FileUploadField,
|
|
6759
|
-
validators: [maxTotalFileSize(20 * 1024 * 1024, { message: 'Суммарно не более 20 МБ' })],
|
|
6760
|
-
},
|
|
6761
|
-
```
|
|
6762
|
-
|
|
6763
|
-
_Source: src/form/validation/validators/max-total-file-size.ts_
|
|
6764
|
-
|
|
6765
|
-
### min
|
|
6766
|
-
|
|
6767
|
-
**Kind:** `function`
|
|
6768
|
-
|
|
6769
|
-
Фабрика валидатора минимального числового значения.
|
|
6770
|
-
|
|
6771
|
-
Пустые значения (`null`/`undefined`) пропускаются (используйте {@link required} для обязательности).
|
|
6772
|
-
|
|
6773
|
-
**Signature:**
|
|
6774
|
-
```typescript
|
|
6775
|
-
export function min<TForm = unknown, TField extends number | null | undefined = number>(
|
|
6776
|
-
minValue: number,
|
|
6777
|
-
options?: ValidateOptions
|
|
6778
|
-
): Validator<TForm, TField>
|
|
6779
|
-
```
|
|
6780
|
-
|
|
6781
|
-
**Parameters:**
|
|
6782
|
-
- `minValue` — - Минимально допустимое значение (включительно)
|
|
6783
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6784
|
-
попадают `min` и `actual`.
|
|
6785
|
-
|
|
6786
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
6787
|
-
|
|
6788
|
-
**Examples:**
|
|
6789
|
-
|
|
6790
|
-
Минимальное значение числового поля
|
|
6791
|
-
```typescript
|
|
6792
|
-
import { required, min } from '@reformer/core/validators';
|
|
6793
|
-
|
|
6794
|
-
// Внутри FieldConfig схемы формы:
|
|
6795
|
-
age: { value: model.$.age, component: Input, validators: [min(18)] },
|
|
6796
|
-
quantity: {
|
|
6797
|
-
value: model.$.quantity,
|
|
6798
|
-
component: Input,
|
|
6799
|
-
validators: [required(), min(1, { message: 'Минимум 1' })],
|
|
6800
|
-
},
|
|
6801
|
-
```
|
|
6802
|
-
|
|
6803
|
-
_Source: src/form/validation/validators/min.ts_
|
|
6804
|
-
|
|
6805
|
-
### minAge
|
|
6806
|
-
|
|
6807
|
-
**Kind:** `function`
|
|
6808
|
-
|
|
6809
|
-
Фабрика валидатора минимального возраста (по дате рождения).
|
|
6810
|
-
|
|
6811
|
-
Возраст вычисляется по дате рождения относительно сегодняшнего дня. Пустые и невалидные
|
|
6812
|
-
даты пропускаются (используйте {@link required} и {@link isDate}).
|
|
6813
|
-
|
|
6814
|
-
**Signature:**
|
|
6815
|
-
```typescript
|
|
6816
|
-
export function minAge<
|
|
6817
|
-
TForm = unknown,
|
|
6818
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
6819
|
-
>(minAgeValue: number, options?: ValidateOptions): Validator<TForm, TField>
|
|
6820
|
-
```
|
|
6821
|
-
|
|
6822
|
-
**Parameters:**
|
|
6823
|
-
- `minAgeValue` — - Минимально допустимый возраст (в полных годах)
|
|
6824
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6825
|
-
попадают `minAge` и `currentAge`.
|
|
6826
|
-
|
|
6827
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты рождения (`string | Date`)
|
|
6828
|
-
|
|
6829
|
-
**Examples:**
|
|
6830
|
-
|
|
6831
|
-
Минимальный возраст
|
|
6832
|
-
```typescript
|
|
6833
|
-
import { required, minAge } from '@reformer/core/validators';
|
|
6834
|
-
|
|
6835
|
-
// Внутри FieldConfig схемы формы:
|
|
6836
|
-
birthDate: {
|
|
6837
|
-
value: model.$.birthDate,
|
|
6838
|
-
component: DatePicker,
|
|
6839
|
-
validators: [required(), minAge(18, { message: 'Вам должно быть не менее 18 лет' })],
|
|
6840
|
-
},
|
|
6841
|
-
```
|
|
6842
|
-
|
|
6843
|
-
_Source: src/form/validation/validators/min-age.ts_
|
|
6844
|
-
|
|
6845
|
-
### minDate
|
|
6846
|
-
|
|
6847
|
-
**Kind:** `function`
|
|
6848
|
-
|
|
6849
|
-
Фабрика валидатора минимальной даты (включительно).
|
|
6850
|
-
|
|
6851
|
-
Сравнение по нормализованным датам (время обнуляется). Пустые и невалидные даты
|
|
6852
|
-
пропускаются (используйте {@link required} и {@link isDate}).
|
|
6853
|
-
|
|
6854
|
-
**Signature:**
|
|
6855
|
-
```typescript
|
|
6856
|
-
export function minDate<
|
|
6857
|
-
TForm = unknown,
|
|
6858
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
6859
|
-
>(minDateValue: Date, options?: ValidateOptions): Validator<TForm, TField>
|
|
6860
|
-
```
|
|
6861
|
-
|
|
6862
|
-
**Parameters:**
|
|
6863
|
-
- `minDateValue` — - Минимально допустимая дата (включительно)
|
|
6864
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6865
|
-
попадает `minDate`.
|
|
6866
|
-
|
|
6867
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты (`string | Date`)
|
|
6868
|
-
|
|
6869
|
-
**Examples:**
|
|
6870
|
-
|
|
6871
|
-
Минимальная дата
|
|
6872
|
-
```typescript
|
|
6873
|
-
import { required, minDate } from '@reformer/core/validators';
|
|
6874
|
-
|
|
6875
|
-
// Внутри FieldConfig схемы формы:
|
|
6876
|
-
startDate: {
|
|
6877
|
-
value: model.$.startDate,
|
|
6878
|
-
component: DatePicker,
|
|
6879
|
-
validators: [required(), minDate(new Date(), { message: 'Дата не раньше сегодня' })],
|
|
6880
|
-
},
|
|
6881
|
-
```
|
|
6882
|
-
|
|
6883
|
-
_Source: src/form/validation/validators/min-date.ts_
|
|
6884
|
-
|
|
6885
|
-
### minFiles
|
|
6886
|
-
|
|
6887
|
-
**Kind:** `function`
|
|
6888
|
-
|
|
6889
|
-
Фабрика валидатора минимального количества файлов.
|
|
6890
|
-
|
|
6891
|
-
Работает с массивом файлов (одиночный файл считается как 1). Пустые значения
|
|
6892
|
-
(`null`/`undefined`/`''`/`[]`) пропускаются — «нужен хотя бы один файл» выражается
|
|
6893
|
-
связкой `required()` + `minFiles(n)`, как и у {@link minLength}.
|
|
6894
|
-
|
|
6895
|
-
**Signature:**
|
|
6896
|
-
```typescript
|
|
6897
|
-
export function minFiles<TForm = unknown, TField = unknown>(
|
|
6898
|
-
min: number,
|
|
6899
|
-
options?: ValidateOptions
|
|
6900
|
-
): Validator<TForm, TField>
|
|
6901
|
-
```
|
|
6902
|
-
|
|
6903
|
-
**Parameters:**
|
|
6904
|
-
- `min` — - Минимально допустимое количество файлов (включительно)
|
|
6905
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6906
|
-
попадают `minFiles` и `actualCount`.
|
|
6907
|
-
|
|
6908
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
6909
|
-
|
|
6910
|
-
**Examples:**
|
|
6911
|
-
|
|
6912
|
-
Не менее двух документов
|
|
6913
|
-
```typescript
|
|
6914
|
-
import { required, minFiles } from '@reformer/core/validators';
|
|
6915
|
-
|
|
6916
|
-
// Внутри FieldConfig схемы формы:
|
|
6917
|
-
documents: {
|
|
6918
|
-
value: model.$.documents,
|
|
6919
|
-
component: FileUploadField,
|
|
6920
|
-
validators: [required(), minFiles(2, { message: 'Приложите минимум 2 документа' })],
|
|
6921
|
-
},
|
|
6922
|
-
```
|
|
6923
|
-
|
|
6924
|
-
_Source: src/form/validation/validators/min-files.ts_
|
|
6925
|
-
|
|
6926
|
-
### minFileSize
|
|
6927
|
-
|
|
6928
|
-
**Kind:** `function`
|
|
6929
|
-
|
|
6930
|
-
Фабрика валидатора минимального размера файла.
|
|
6931
|
-
|
|
6932
|
-
Работает с одиночным файлом или массивом (`File` либо файлоподобный дескриптор с
|
|
6933
|
-
`name`/`size`). Проверяется каждый файл; в ошибку попадает первый нарушивший.
|
|
6934
|
-
Типовой сценарий — отсев пустых (0-байтовых) файлов: `minFileSize(1)`.
|
|
6935
|
-
Пустые значения (`null`/`undefined`/`''`/`[]`) и элементы без числового `size`
|
|
6936
|
-
пропускаются (используйте {@link required} для обязательности).
|
|
6937
|
-
|
|
6938
|
-
**Signature:**
|
|
6939
|
-
```typescript
|
|
6940
|
-
export function minFileSize<TForm = unknown, TField = unknown>(
|
|
6941
|
-
minSize: number,
|
|
6942
|
-
options?: ValidateOptions
|
|
6943
|
-
): Validator<TForm, TField>
|
|
6944
|
-
```
|
|
6945
|
-
|
|
6946
|
-
**Parameters:**
|
|
6947
|
-
- `minSize` — - Минимально допустимый размер файла в байтах (включительно)
|
|
6948
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6949
|
-
попадают `minFileSize`, `fileName` и `actualSize`.
|
|
6950
|
-
|
|
6951
|
-
**Returns:** Чистый валидатор {@link Validator} для файла или массива файлов
|
|
6952
|
-
|
|
6953
|
-
**Examples:**
|
|
6954
|
-
|
|
6955
|
-
Отсев пустых файлов
|
|
6956
|
-
```typescript
|
|
6957
|
-
import { minFileSize } from '@reformer/core/validators';
|
|
6958
|
-
|
|
6959
|
-
// Внутри FieldConfig схемы формы:
|
|
6960
|
-
documents: {
|
|
6961
|
-
value: model.$.documents,
|
|
6962
|
-
component: FileUploadField,
|
|
6963
|
-
validators: [minFileSize(1, { message: 'Файл пустой' })],
|
|
6964
|
-
},
|
|
6965
|
-
```
|
|
6966
|
-
|
|
6967
|
-
_Source: src/form/validation/validators/min-file-size.ts_
|
|
6968
|
-
|
|
6969
|
-
### minLength
|
|
6970
|
-
|
|
6971
|
-
**Kind:** `function`
|
|
6972
|
-
|
|
6973
|
-
Фабрика валидатора минимальной длины строки или массива.
|
|
6974
|
-
|
|
6975
|
-
Работает со строкой или массивом (проверяется `value.length`). Пустые значения
|
|
6976
|
-
(`null`/`undefined`/`''`) и значения без числового `length` пропускаются
|
|
6977
|
-
(используйте {@link required} для обязательности).
|
|
6978
|
-
|
|
6979
|
-
**Signature:**
|
|
6980
|
-
```typescript
|
|
6981
|
-
export function minLength<TForm = unknown, TField = unknown>(
|
|
6982
|
-
minLen: number,
|
|
6983
|
-
options?: ValidateOptions
|
|
6984
|
-
): Validator<TForm, TField>
|
|
6985
|
-
```
|
|
6986
|
-
|
|
6987
|
-
**Parameters:**
|
|
6988
|
-
- `minLen` — - Минимально допустимая длина (включительно)
|
|
6989
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
6990
|
-
попадают `minLength` и `actualLength`.
|
|
6991
|
-
|
|
6992
|
-
**Returns:** Чистый валидатор {@link Validator} для строки или массива
|
|
6993
|
-
|
|
6994
|
-
**Examples:**
|
|
6995
|
-
|
|
6996
|
-
Минимальная длина строки
|
|
6997
|
-
```typescript
|
|
6998
|
-
import { required, minLength } from '@reformer/core/validators';
|
|
6999
|
-
|
|
7000
|
-
// Внутри FieldConfig схемы формы:
|
|
7001
|
-
name: { value: model.$.name, component: Input, validators: [minLength(2)] },
|
|
7002
|
-
password: {
|
|
7003
|
-
value: model.$.password,
|
|
7004
|
-
component: Input,
|
|
7005
|
-
validators: [required(), minLength(8, { message: 'Минимум 8 символов' })],
|
|
7006
|
-
},
|
|
7007
|
-
```
|
|
7008
|
-
|
|
7009
|
-
_Source: src/form/validation/validators/min-length.ts_
|
|
7010
|
-
|
|
7011
|
-
### ModelApi
|
|
7012
|
-
|
|
7013
|
-
**Kind:** `interface`
|
|
7014
|
-
|
|
7015
|
-
API уровня модели (доступно на корне, под-моделях вложенных объектов-групп и элементов массива).
|
|
7016
|
-
|
|
7017
|
-
⚠️ Имена методов (`$`/`get`/`set`/`patch`/`isDirty`/`reset`/`signalAt`/`captureInitial`)
|
|
7018
|
-
зарезервированы: одноимённое поле формы их затеняет (редкий краевой случай).
|
|
6183
|
+
⚠️ Имена методов (`$`/`get`/`set`/`patch`/`isDirty`/`reset`/`signalAt`/`captureInitial`)
|
|
6184
|
+
зарезервированы: одноимённое поле формы их затеняет (редкий краевой случай).
|
|
7019
6185
|
|
|
7020
6186
|
**Signature:**
|
|
7021
6187
|
```typescript
|
|
7022
6188
|
export interface ModelApi<T> {
|
|
7023
|
-
/**
|
|
7024
|
-
|
|
6189
|
+
/**
|
|
6190
|
+
* Escape-hatch к сигналам: `model.$.loanType` → `PathAwareSignal<LoanType>`.
|
|
6191
|
+
* Сам узел — {@link ReadonlySignal} модели целиком: `model.$.subscribe(v => …)`.
|
|
6192
|
+
*/
|
|
6193
|
+
readonly $: ModelGroupSignals<T>;
|
|
7025
6194
|
/** Снимок значений (без подписки) — для submit. */
|
|
7026
6195
|
get(): T;
|
|
7027
6196
|
/**
|
|
@@ -7165,403 +6334,185 @@ rows.length.value; // 1 (реактивная длина)
|
|
|
7165
6334
|
|
|
7166
6335
|
_Source: src/form/nodes/model-array-node.ts_
|
|
7167
6336
|
|
|
7168
|
-
###
|
|
6337
|
+
### ModelArraySignals
|
|
7169
6338
|
|
|
7170
6339
|
**Kind:** `type`
|
|
7171
6340
|
|
|
7172
|
-
|
|
7173
|
-
(
|
|
7174
|
-
|
|
6341
|
+
Узел-массив дерева `model.$`: индексируемый доступ к под-сигналам элементов, реактивная `length`
|
|
6342
|
+
и {@link ReadonlySignal} значения массива целиком (реагирует и на правку элемента, и на изменение
|
|
6343
|
+
состава — push/removeAt/move).
|
|
7175
6344
|
|
|
7176
6345
|
**Signature:**
|
|
7177
6346
|
```typescript
|
|
7178
|
-
export type
|
|
7179
|
-
|
|
6347
|
+
export type ModelArraySignals<U, V> = ContainerSignal<V, 'length'> & {
|
|
6348
|
+
readonly length: number;
|
|
6349
|
+
readonly [index: number]: ModelSignalNode<U>;
|
|
7180
6350
|
};
|
|
7181
6351
|
```
|
|
7182
6352
|
|
|
7183
6353
|
_Source: src/state/types.ts_
|
|
7184
6354
|
|
|
7185
|
-
###
|
|
6355
|
+
### ModelGroupSignals
|
|
7186
6356
|
|
|
7187
6357
|
**Kind:** `type`
|
|
7188
6358
|
|
|
7189
|
-
|
|
7190
|
-
|
|
6359
|
+
Узел-группа дерева `model.$`: доступ к под-сигналам полей ({@link ModelSignals}) И одновременно
|
|
6360
|
+
{@link ReadonlySignal} агрегированного значения группы — `.value`/`.peek()`/`.subscribe()`.
|
|
7191
6361
|
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
export type ModelSignals<T> = {
|
|
7195
|
-
[K in keyof T]: ModelSignalNode<T[K]>;
|
|
7196
|
-
};
|
|
7197
|
-
```
|
|
7198
|
-
|
|
7199
|
-
_Source: src/state/types.ts_
|
|
7200
|
-
|
|
7201
|
-
### ModelValue
|
|
7202
|
-
|
|
7203
|
-
**Kind:** `type`
|
|
7204
|
-
|
|
7205
|
-
Значение поля в value-доступе модели:
|
|
7206
|
-
- массив → {@link ModelArray}
|
|
7207
|
-
- спец-объект (Date/File/Blob) → как есть
|
|
7208
|
-
- объект → под-модель {@link FormModel} (value-доступ + `.$`-сигналы + API get/set/patch/…);
|
|
7209
|
-
промоутится рантаймом (`makeFormModel`); сигналы идентичны `model.$.<path>`
|
|
7210
|
-
- примитив → значение
|
|
6362
|
+
⚠️ Поле формы с именем `value`/`peek`/`subscribe`/`valueOf`/`toString`/`toJSON`/`brand` затеняет
|
|
6363
|
+
одноимённое свойство сигнала (редкий краевой случай); `subscribe` при этом продолжает работать.
|
|
7211
6364
|
|
|
7212
6365
|
**Signature:**
|
|
7213
6366
|
```typescript
|
|
7214
|
-
export type
|
|
7215
|
-
NonNullable<V> extends ReadonlyArray<infer U>
|
|
7216
|
-
? ModelArray<U>
|
|
7217
|
-
: NonNullable<V> extends Opaque
|
|
7218
|
-
? V
|
|
7219
|
-
: NonNullable<V> extends object
|
|
7220
|
-
? FormModel<NonNullable<V>>
|
|
7221
|
-
: V;
|
|
6367
|
+
export type ModelGroupSignals<T> = ModelSignals<T> & ContainerSignal<T, keyof T>;
|
|
7222
6368
|
```
|
|
7223
6369
|
|
|
7224
6370
|
_Source: src/state/types.ts_
|
|
7225
6371
|
|
|
7226
|
-
###
|
|
7227
|
-
|
|
7228
|
-
**Kind:** `function`
|
|
7229
|
-
|
|
7230
|
-
Фабрика валидатора, проверяющего что число кратно заданному.
|
|
7231
|
-
|
|
7232
|
-
Пустые значения и не-числа пропускаются (используйте {@link required} и {@link isNumber}).
|
|
7233
|
-
|
|
7234
|
-
**Signature:**
|
|
7235
|
-
```typescript
|
|
7236
|
-
export function multipleOf<TForm = unknown, TField extends number | null | undefined = number>(
|
|
7237
|
-
divisor: number,
|
|
7238
|
-
options?: ValidateOptions
|
|
7239
|
-
): Validator<TForm, TField>
|
|
7240
|
-
```
|
|
7241
|
-
|
|
7242
|
-
**Parameters:**
|
|
7243
|
-
- `divisor` — - Делитель: значение должно быть кратно ему
|
|
7244
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
7245
|
-
попадает `multipleOf` (делитель).
|
|
7246
|
-
|
|
7247
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
7248
|
-
|
|
7249
|
-
**Examples:**
|
|
7250
|
-
|
|
7251
|
-
Проверка кратности
|
|
7252
|
-
```typescript
|
|
7253
|
-
import { multipleOf } from '@reformer/core/validators';
|
|
7254
|
-
|
|
7255
|
-
// Внутри FieldConfig схемы формы:
|
|
7256
|
-
rating: {
|
|
7257
|
-
value: model.$.rating,
|
|
7258
|
-
component: Input,
|
|
7259
|
-
validators: [multipleOf(0.5, { message: 'Только шаг 0.5' })],
|
|
7260
|
-
},
|
|
7261
|
-
```
|
|
7262
|
-
|
|
7263
|
-
_Source: src/form/validation/validators/multiple-of.ts_
|
|
7264
|
-
|
|
7265
|
-
### NodeFactory
|
|
7266
|
-
|
|
7267
|
-
**Kind:** `class`
|
|
7268
|
-
|
|
7269
|
-
Фабрика для создания узлов формы.
|
|
7270
|
-
|
|
7271
|
-
Определяет тип конфига и создаёт соответствующий узел (FieldNode, GroupNode, ArrayNode).
|
|
7272
|
-
Используется внутри `getReformerForm`/`group`/`array` — явно вызывать обычно не нужно.
|
|
7273
|
-
|
|
7274
|
-
**Signature:**
|
|
7275
|
-
```typescript
|
|
7276
|
-
export class NodeFactory {
|
|
7277
|
-
/**
|
|
7278
|
-
* Создает узел формы на основе конфигурации
|
|
7279
|
-
*
|
|
7280
|
-
* ✅ ОБНОВЛЕНО: Теперь поддерживает массивы напрямую
|
|
7281
|
-
*
|
|
7282
|
-
* Автоматически определяет тип узла:
|
|
7283
|
-
* - FieldNode: имеет value и component
|
|
7284
|
-
* - ArrayNode: массив [schema, ...items] или { schema, initialItems }
|
|
7285
|
-
* - GroupNode: объект без value, component, schema
|
|
7286
|
-
*
|
|
7287
|
-
* @param config Конфигурация узла
|
|
7288
|
-
* @returns Экземпляр FieldNode, GroupNode или ArrayNode
|
|
7289
|
-
* @throws Error если конфиг не соответствует ни одному типу
|
|
7290
|
-
*
|
|
7291
|
-
* @example
|
|
7292
|
-
* ```typescript
|
|
7293
|
-
* const factory = new NodeFactory();
|
|
7294
|
-
*
|
|
7295
|
-
* // FieldNode
|
|
7296
|
-
* const field = factory.createNode({
|
|
7297
|
-
* value: 'test@mail.com',
|
|
7298
|
-
* component: Input,
|
|
7299
|
-
* validators: [required, email]
|
|
7300
|
-
* });
|
|
7301
|
-
*
|
|
7302
|
-
* // GroupNode
|
|
7303
|
-
* const group = factory.createNode({
|
|
7304
|
-
* email: { value: '', component: Input },
|
|
7305
|
-
* password: { value: '', component: Input }
|
|
7306
|
-
* });
|
|
7307
|
-
*
|
|
7308
|
-
* // ArrayNode (объект)
|
|
7309
|
-
* const array = factory.createNode({
|
|
7310
|
-
* schema: { title: { value: '', component: Input } },
|
|
7311
|
-
* initialItems: [{ title: 'Item 1' }]
|
|
7312
|
-
* });
|
|
7313
|
-
*
|
|
7314
|
-
* // ArrayNode (массив) - новый формат
|
|
7315
|
-
* const array2 = factory.createNode([
|
|
7316
|
-
* { title: { value: '', component: Input } }, // schema
|
|
7317
|
-
* { title: 'Item 1' }, // initial item 1
|
|
7318
|
-
* { title: 'Item 2' } // initial item 2
|
|
7319
|
-
* ]);
|
|
7320
|
-
* ```
|
|
7321
|
-
*/ /* … */ }
|
|
7322
|
-
```
|
|
7323
|
-
|
|
7324
|
-
**Examples:**
|
|
7325
|
-
|
|
7326
|
-
```typescript
|
|
7327
|
-
import { NodeFactory } from '@reformer/core';
|
|
7328
|
-
|
|
7329
|
-
const factory = new NodeFactory();
|
|
7330
|
-
const node = factory.createNode({ value: '', component: Input }); // → FieldNode<string>
|
|
7331
|
-
```
|
|
7332
|
-
|
|
7333
|
-
_Source: src/form/factories/node-factory.ts_
|
|
7334
|
-
|
|
7335
|
-
### nonNegative
|
|
7336
|
-
|
|
7337
|
-
**Kind:** `function`
|
|
7338
|
-
|
|
7339
|
-
Фабрика валидатора, проверяющего что число неотрицательное (`≥ 0`).
|
|
7340
|
-
|
|
7341
|
-
Пустые значения и не-числа пропускаются (используйте {@link required} и {@link isNumber}).
|
|
7342
|
-
|
|
7343
|
-
**Signature:**
|
|
7344
|
-
```typescript
|
|
7345
|
-
export function nonNegative<TForm = unknown, TField extends number | null | undefined = number>(
|
|
7346
|
-
options?: ValidateOptions
|
|
7347
|
-
): Validator<TForm, TField>
|
|
7348
|
-
```
|
|
7349
|
-
|
|
7350
|
-
**Parameters:**
|
|
7351
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
7352
|
-
|
|
7353
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
7354
|
-
|
|
7355
|
-
**Examples:**
|
|
7356
|
-
|
|
7357
|
-
Проверка неотрицательности
|
|
7358
|
-
```typescript
|
|
7359
|
-
import { nonNegative } from '@reformer/core/validators';
|
|
7360
|
-
|
|
7361
|
-
// Внутри FieldConfig схемы формы:
|
|
7362
|
-
balance: {
|
|
7363
|
-
value: model.$.balance,
|
|
7364
|
-
component: Input,
|
|
7365
|
-
validators: [nonNegative({ message: 'Баланс не может быть отрицательным' })],
|
|
7366
|
-
},
|
|
7367
|
-
```
|
|
7368
|
-
|
|
7369
|
-
_Source: src/form/validation/validators/non-negative.ts_
|
|
7370
|
-
|
|
7371
|
-
### nonZero
|
|
7372
|
-
|
|
7373
|
-
**Kind:** `function`
|
|
7374
|
-
|
|
7375
|
-
Фабрика валидатора, проверяющего что число не равно нулю.
|
|
7376
|
-
|
|
7377
|
-
Пустые значения и не-числа пропускаются (используйте {@link required} и {@link isNumber}).
|
|
7378
|
-
|
|
7379
|
-
**Signature:**
|
|
7380
|
-
```typescript
|
|
7381
|
-
export function nonZero<TForm = unknown, TField extends number | null | undefined = number>(
|
|
7382
|
-
options?: ValidateOptions
|
|
7383
|
-
): Validator<TForm, TField>
|
|
7384
|
-
```
|
|
7385
|
-
|
|
7386
|
-
**Parameters:**
|
|
7387
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
7388
|
-
|
|
7389
|
-
**Returns:** Чистый валидатор {@link Validator} для числового поля
|
|
7390
|
-
|
|
7391
|
-
**Examples:**
|
|
7392
|
-
|
|
7393
|
-
Проверка «не ноль»
|
|
7394
|
-
```typescript
|
|
7395
|
-
import { nonZero } from '@reformer/core/validators';
|
|
7396
|
-
|
|
7397
|
-
// Внутри FieldConfig схемы формы:
|
|
7398
|
-
divisor: {
|
|
7399
|
-
value: model.$.divisor,
|
|
7400
|
-
component: Input,
|
|
7401
|
-
validators: [nonZero({ message: 'Не может быть нулём' })],
|
|
7402
|
-
},
|
|
7403
|
-
```
|
|
7404
|
-
|
|
7405
|
-
_Source: src/form/validation/validators/non-zero.ts_
|
|
7406
|
-
|
|
7407
|
-
### pastDate
|
|
7408
|
-
|
|
7409
|
-
**Kind:** `function`
|
|
7410
|
-
|
|
7411
|
-
Фабрика валидатора, проверяющего что дата не в будущем.
|
|
7412
|
-
|
|
7413
|
-
Дата не должна быть позже сегодняшнего дня (сравнение по нормализованным датам).
|
|
7414
|
-
Пустые и невалидные даты пропускаются (используйте {@link required} и {@link isDate}).
|
|
7415
|
-
|
|
7416
|
-
**Signature:**
|
|
7417
|
-
```typescript
|
|
7418
|
-
export function pastDate<
|
|
7419
|
-
TForm = unknown,
|
|
7420
|
-
TField extends string | Date | null | undefined = string | Date,
|
|
7421
|
-
>(options?: ValidateOptions): Validator<TForm, TField>
|
|
7422
|
-
```
|
|
7423
|
-
|
|
7424
|
-
**Parameters:**
|
|
7425
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
7426
|
-
|
|
7427
|
-
**Returns:** Чистый валидатор {@link Validator} для поля даты (`string | Date`)
|
|
7428
|
-
|
|
7429
|
-
**Examples:**
|
|
7430
|
-
|
|
7431
|
-
Дата не в будущем
|
|
7432
|
-
```typescript
|
|
7433
|
-
import { required, pastDate } from '@reformer/core/validators';
|
|
7434
|
-
|
|
7435
|
-
// Внутри FieldConfig схемы формы:
|
|
7436
|
-
birthDate: {
|
|
7437
|
-
value: model.$.birthDate,
|
|
7438
|
-
component: DatePicker,
|
|
7439
|
-
validators: [required(), pastDate({ message: 'Дата рождения не может быть в будущем' })],
|
|
7440
|
-
},
|
|
7441
|
-
```
|
|
7442
|
-
|
|
7443
|
-
_Source: src/form/validation/validators/past-date.ts_
|
|
7444
|
-
|
|
7445
|
-
### PathAwareSignal
|
|
6372
|
+
### ModelObject
|
|
7446
6373
|
|
|
7447
6374
|
**Kind:** `type`
|
|
7448
6375
|
|
|
7449
|
-
|
|
7450
|
-
|
|
6376
|
+
Карта value-полей объекта (value-половина {@link FormModel}): поля доступны как обычные свойства
|
|
6377
|
+
(чтение реактивно внутри `effect`/`computed`, запись — присваиванием). Вложенные объекты-поля
|
|
6378
|
+
резолвятся в под-модели {@link FormModel} (см. {@link ModelValue}), массивы — в {@link ModelArray}.
|
|
7451
6379
|
|
|
7452
6380
|
**Signature:**
|
|
7453
6381
|
```typescript
|
|
7454
|
-
export type
|
|
7455
|
-
|
|
7456
|
-
readonly __path: string;
|
|
6382
|
+
export type ModelObject<T> = {
|
|
6383
|
+
[K in keyof T]: ModelValue<T[K]>;
|
|
7457
6384
|
};
|
|
7458
6385
|
```
|
|
7459
6386
|
|
|
7460
6387
|
_Source: src/state/types.ts_
|
|
7461
6388
|
|
|
7462
|
-
###
|
|
7463
|
-
|
|
7464
|
-
**Kind:** `function`
|
|
6389
|
+
### ModelSignals
|
|
7465
6390
|
|
|
7466
|
-
|
|
6391
|
+
**Kind:** `type`
|
|
7467
6392
|
|
|
7468
|
-
|
|
7469
|
-
|
|
6393
|
+
Карта под-сигналов объекта в дереве `model.$` (без свойств самого узла — их добавляет
|
|
6394
|
+
{@link ModelGroupSignals}).
|
|
7470
6395
|
|
|
7471
6396
|
**Signature:**
|
|
7472
6397
|
```typescript
|
|
7473
|
-
export
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
): Validator<TForm, TField>
|
|
6398
|
+
export type ModelSignals<T> = {
|
|
6399
|
+
[K in keyof T]: ModelSignalNode<T[K]>;
|
|
6400
|
+
};
|
|
7477
6401
|
```
|
|
7478
6402
|
|
|
7479
|
-
|
|
7480
|
-
- `regex` — - Регулярное выражение для проверки значения
|
|
7481
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}). В `params` ошибки автоматически
|
|
7482
|
-
попадает `pattern` (строка-источник regex).
|
|
6403
|
+
_Source: src/state/types.ts_
|
|
7483
6404
|
|
|
7484
|
-
|
|
6405
|
+
### ModelValue
|
|
7485
6406
|
|
|
7486
|
-
**
|
|
6407
|
+
**Kind:** `type`
|
|
7487
6408
|
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
6409
|
+
Значение поля в value-доступе модели:
|
|
6410
|
+
- массив → {@link ModelArray}
|
|
6411
|
+
- спец-объект (Date/File/Blob) → как есть
|
|
6412
|
+
- объект → под-модель {@link FormModel} (value-доступ + `.$`-сигналы + API get/set/patch/…);
|
|
6413
|
+
промоутится рантаймом (`makeFormModel`); сигналы идентичны `model.$.<path>`
|
|
6414
|
+
- примитив → значение
|
|
7491
6415
|
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
required(),
|
|
7503
|
-
pattern(/^\+7 \(\d{3}\) \d{3}-\d{2}-\d{2}$/, { message: 'Формат +7 (999) 123-45-67' }),
|
|
7504
|
-
],
|
|
7505
|
-
},
|
|
6416
|
+
**Signature:**
|
|
6417
|
+
```typescript
|
|
6418
|
+
export type ModelValue<V> =
|
|
6419
|
+
NonNullable<V> extends ReadonlyArray<infer U>
|
|
6420
|
+
? ModelArray<U>
|
|
6421
|
+
: NonNullable<V> extends Opaque
|
|
6422
|
+
? V
|
|
6423
|
+
: NonNullable<V> extends object
|
|
6424
|
+
? FormModel<NonNullable<V>>
|
|
6425
|
+
: V;
|
|
7506
6426
|
```
|
|
7507
6427
|
|
|
7508
|
-
_Source: src/
|
|
6428
|
+
_Source: src/state/types.ts_
|
|
7509
6429
|
|
|
7510
|
-
###
|
|
6430
|
+
### NodeFactory
|
|
7511
6431
|
|
|
7512
|
-
**Kind:** `
|
|
6432
|
+
**Kind:** `class`
|
|
7513
6433
|
|
|
7514
|
-
Фабрика
|
|
6434
|
+
Фабрика для создания узлов формы.
|
|
7515
6435
|
|
|
7516
|
-
|
|
7517
|
-
|
|
6436
|
+
Определяет тип конфига и создаёт соответствующий узел (FieldNode, GroupNode, ArrayNode).
|
|
6437
|
+
Используется внутри `getReformerForm`/`group`/`array` — явно вызывать обычно не нужно.
|
|
7518
6438
|
|
|
7519
6439
|
**Signature:**
|
|
7520
6440
|
```typescript
|
|
7521
|
-
export
|
|
7522
|
-
|
|
7523
|
-
|
|
6441
|
+
export class NodeFactory {
|
|
6442
|
+
/**
|
|
6443
|
+
* Создает узел формы на основе конфигурации
|
|
6444
|
+
*
|
|
6445
|
+
* ✅ ОБНОВЛЕНО: Теперь поддерживает массивы напрямую
|
|
6446
|
+
*
|
|
6447
|
+
* Автоматически определяет тип узла:
|
|
6448
|
+
* - FieldNode: имеет value и component
|
|
6449
|
+
* - ArrayNode: массив [schema, ...items] или { schema, initialItems }
|
|
6450
|
+
* - GroupNode: объект без value, component, schema
|
|
6451
|
+
*
|
|
6452
|
+
* @param config Конфигурация узла
|
|
6453
|
+
* @returns Экземпляр FieldNode, GroupNode или ArrayNode
|
|
6454
|
+
* @throws Error если конфиг не соответствует ни одному типу
|
|
6455
|
+
*
|
|
6456
|
+
* @example
|
|
6457
|
+
* ```typescript
|
|
6458
|
+
* const factory = new NodeFactory();
|
|
6459
|
+
*
|
|
6460
|
+
* // FieldNode
|
|
6461
|
+
* const field = factory.createNode({
|
|
6462
|
+
* value: 'test@mail.com',
|
|
6463
|
+
* component: Input,
|
|
6464
|
+
* validators: [required, email]
|
|
6465
|
+
* });
|
|
6466
|
+
*
|
|
6467
|
+
* // GroupNode
|
|
6468
|
+
* const group = factory.createNode({
|
|
6469
|
+
* email: { value: '', component: Input },
|
|
6470
|
+
* password: { value: '', component: Input }
|
|
6471
|
+
* });
|
|
6472
|
+
*
|
|
6473
|
+
* // ArrayNode (объект)
|
|
6474
|
+
* const array = factory.createNode({
|
|
6475
|
+
* schema: { title: { value: '', component: Input } },
|
|
6476
|
+
* initialItems: [{ title: 'Item 1' }]
|
|
6477
|
+
* });
|
|
6478
|
+
*
|
|
6479
|
+
* // ArrayNode (массив) - новый формат
|
|
6480
|
+
* const array2 = factory.createNode([
|
|
6481
|
+
* { title: { value: '', component: Input } }, // schema
|
|
6482
|
+
* { title: 'Item 1' }, // initial item 1
|
|
6483
|
+
* { title: 'Item 2' } // initial item 2
|
|
6484
|
+
* ]);
|
|
6485
|
+
* ```
|
|
6486
|
+
*/ /* … */ }
|
|
7524
6487
|
```
|
|
7525
6488
|
|
|
7526
|
-
**Parameters:**
|
|
7527
|
-
- `options` — - Опции валидатора {@link PhoneValidatorOptions}. В `params` ошибки
|
|
7528
|
-
автоматически попадает выбранный `format`.
|
|
7529
|
-
|
|
7530
|
-
**Returns:** Чистый валидатор {@link Validator} для строкового поля
|
|
7531
|
-
|
|
7532
6489
|
**Examples:**
|
|
7533
6490
|
|
|
7534
|
-
Проверка номера телефона
|
|
7535
6491
|
```typescript
|
|
7536
|
-
import {
|
|
6492
|
+
import { NodeFactory } from '@reformer/core';
|
|
7537
6493
|
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
value: model.$.phone,
|
|
7541
|
-
component: Input,
|
|
7542
|
-
validators: [required(), phone({ format: 'ru' })],
|
|
7543
|
-
},
|
|
6494
|
+
const factory = new NodeFactory();
|
|
6495
|
+
const node = factory.createNode({ value: '', component: Input }); // → FieldNode<string>
|
|
7544
6496
|
```
|
|
7545
6497
|
|
|
7546
|
-
_Source: src/form/
|
|
6498
|
+
_Source: src/form/factories/node-factory.ts_
|
|
7547
6499
|
|
|
7548
|
-
###
|
|
6500
|
+
### PathAwareSignal
|
|
7549
6501
|
|
|
7550
6502
|
**Kind:** `type`
|
|
7551
6503
|
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
- `international` — международный формат E.164 (`+?[1-9]\d{1,14}`);
|
|
7555
|
-
- `ru` — российские номера (`+7`/`7`/`8`, коды `4`/`8`/`9`, с разделителями);
|
|
7556
|
-
- `us` — североамериканские номера (NANP);
|
|
7557
|
-
- `any` — свободный формат: цифры, скобки и разделители (по умолчанию).
|
|
6504
|
+
Сигнал, который знает свой путь в модели (`'personalData.lastName'`).
|
|
6505
|
+
Используется как «ручка поля»: и привязка value в схеме, и идентичность для testId/devtools.
|
|
7558
6506
|
|
|
7559
6507
|
**Signature:**
|
|
7560
6508
|
```typescript
|
|
7561
|
-
export type
|
|
6509
|
+
export type PathAwareSignal<T> = Signal<T> & {
|
|
6510
|
+
/** Путь поля в модели (dot-нотация). На элементах массива включает индекс. */
|
|
6511
|
+
readonly __path: string;
|
|
6512
|
+
};
|
|
7562
6513
|
```
|
|
7563
6514
|
|
|
7564
|
-
_Source: src/
|
|
6515
|
+
_Source: src/state/types.ts_
|
|
7565
6516
|
|
|
7566
6517
|
### registerSignalNode
|
|
7567
6518
|
|
|
@@ -7597,52 +6548,6 @@ if (sig && node) registerSignalNode(sig, node);
|
|
|
7597
6548
|
|
|
7598
6549
|
_Source: src/form/signal-node-registry.ts_
|
|
7599
6550
|
|
|
7600
|
-
### required
|
|
7601
|
-
|
|
7602
|
-
**Kind:** `function`
|
|
7603
|
-
|
|
7604
|
-
Фабрика валидатора обязательного поля.
|
|
7605
|
-
|
|
7606
|
-
Возвращает чистую функцию-валидатор `(value, control, root)`. Передаётся в `validate()`.
|
|
7607
|
-
|
|
7608
|
-
Пустыми считаются: `null`, `undefined`, `''` (пустая строка), `[]` (пустой массив —
|
|
7609
|
-
обязательный multi-select / FormArray без выбранных элементов).
|
|
7610
|
-
Для boolean полей требуется значение `true`.
|
|
7611
|
-
|
|
7612
|
-
**Signature:**
|
|
7613
|
-
```typescript
|
|
7614
|
-
export function required<TForm = unknown, TField = unknown>(
|
|
7615
|
-
options?: ValidateOptions
|
|
7616
|
-
): Validator<TForm, TField>
|
|
7617
|
-
```
|
|
7618
|
-
|
|
7619
|
-
**Parameters:**
|
|
7620
|
-
- `options` — - Опции валидатора ({@link ValidateOptions}): `message`, `params`
|
|
7621
|
-
|
|
7622
|
-
**Returns:** Чистый валидатор {@link Validator} для поля схемы
|
|
7623
|
-
|
|
7624
|
-
**Examples:**
|
|
7625
|
-
|
|
7626
|
-
Обязательные поля в схеме формы
|
|
7627
|
-
```typescript
|
|
7628
|
-
import { required } from '@reformer/core/validators';
|
|
7629
|
-
|
|
7630
|
-
// Внутри FieldConfig схемы формы:
|
|
7631
|
-
email: { value: model.$.email, component: Input, validators: [required()] },
|
|
7632
|
-
phone: {
|
|
7633
|
-
value: model.$.phone,
|
|
7634
|
-
component: Input,
|
|
7635
|
-
validators: [required({ message: 'Укажите номер телефона' })],
|
|
7636
|
-
},
|
|
7637
|
-
agreeToTerms: {
|
|
7638
|
-
value: model.$.agreeToTerms,
|
|
7639
|
-
component: Checkbox,
|
|
7640
|
-
validators: [required({ message: 'Необходимо принять условия' })],
|
|
7641
|
-
},
|
|
7642
|
-
```
|
|
7643
|
-
|
|
7644
|
-
_Source: src/form/validation/validators/required.ts_
|
|
7645
|
-
|
|
7646
6551
|
### resetWhen
|
|
7647
6552
|
|
|
7648
6553
|
**Kind:** `function`
|
|
@@ -7666,19 +6571,6 @@ resetWhen(model.$.cardNumber, () => model.paymentType !== 'card', { resetValue:
|
|
|
7666
6571
|
|
|
7667
6572
|
_Source: src/state/behaviors-value.ts_
|
|
7668
6573
|
|
|
7669
|
-
### ResourceLoadResult
|
|
7670
|
-
|
|
7671
|
-
**Kind:** `type`
|
|
7672
|
-
|
|
7673
|
-
Тип для результатов загрузки ресурсов
|
|
7674
|
-
|
|
7675
|
-
**Signature:**
|
|
7676
|
-
```typescript
|
|
7677
|
-
export type ResourceLoadResult = unknown;
|
|
7678
|
-
```
|
|
7679
|
-
|
|
7680
|
-
_Source: src/form/types/index.ts_
|
|
7681
|
-
|
|
7682
6574
|
### revalidateWhen
|
|
7683
6575
|
|
|
7684
6576
|
**Kind:** `function`
|
|
@@ -7836,25 +6728,6 @@ export interface SchemaArrayControl {
|
|
|
7836
6728
|
|
|
7837
6729
|
_Source: src/form/types/schema-node.ts_
|
|
7838
6730
|
|
|
7839
|
-
### SchemaValidator
|
|
7840
|
-
|
|
7841
|
-
**Kind:** `type`
|
|
7842
|
-
|
|
7843
|
-
Валидатор поля схемы (legacy). Дерево-движок, вызывавший `validators` узла как
|
|
7844
|
-
`(value, scope, root)`, удалён — живые правила это `Rule<T>` в `validate(sig, [...])`
|
|
7845
|
-
(`@reformer/core/validation`). Тип остаётся широким по параметрам для совместимости
|
|
7846
|
-
узлов, всё ещё несущих `validators` (гетерогенные контракты `ValidatorFn`/`Validator`).
|
|
7847
|
-
|
|
7848
|
-
**Signature:**
|
|
7849
|
-
```typescript
|
|
7850
|
-
export type SchemaValidator = (
|
|
7851
|
-
value: any,
|
|
7852
|
-
...rest: any[]
|
|
7853
|
-
) => ValidationError | null | Promise<ValidationError | null>;
|
|
7854
|
-
```
|
|
7855
|
-
|
|
7856
|
-
_Source: src/form/types/schema-node.ts_
|
|
7857
|
-
|
|
7858
6731
|
### SetValueOptions
|
|
7859
6732
|
|
|
7860
6733
|
**Kind:** `interface`
|
|
@@ -7866,32 +6739,13 @@ _Source: src/form/types/schema-node.ts_
|
|
|
7866
6739
|
export interface SetValueOptions {
|
|
7867
6740
|
/** Не вызывать событие изменения (не триггерить валидацию) */
|
|
7868
6741
|
emitEvent?: boolean;
|
|
7869
|
-
|
|
7870
|
-
|
|
6742
|
+
// onlySelf удалён в 7.0: опция объявлялась, но не была реализована ни одной из четырёх
|
|
6743
|
+
// реализаций setValue — передача значения ни на что не влияла.
|
|
7871
6744
|
}
|
|
7872
6745
|
```
|
|
7873
6746
|
|
|
7874
6747
|
_Source: src/form/nodes/form-node.ts_
|
|
7875
6748
|
|
|
7876
|
-
### StatusEvent
|
|
7877
|
-
|
|
7878
|
-
**Kind:** `type`
|
|
7879
|
-
|
|
7880
|
-
События для State Machine
|
|
7881
|
-
|
|
7882
|
-
**Signature:**
|
|
7883
|
-
```typescript
|
|
7884
|
-
export type StatusEvent =
|
|
7885
|
-
| { type: 'START_VALIDATION' }
|
|
7886
|
-
| { type: 'VALIDATION_SUCCESS' }
|
|
7887
|
-
| { type: 'VALIDATION_FAILURE' }
|
|
7888
|
-
| { type: 'DISABLE' }
|
|
7889
|
-
| { type: 'ENABLE'; hasErrors?: boolean }
|
|
7890
|
-
| { type: 'SET_ERRORS'; hasErrors: boolean };
|
|
7891
|
-
```
|
|
7892
|
-
|
|
7893
|
-
_Source: src/form/status-machine.ts_
|
|
7894
|
-
|
|
7895
6749
|
### SubmitOptions
|
|
7896
6750
|
|
|
7897
6751
|
**Kind:** `interface`
|
|
@@ -8018,27 +6872,6 @@ syncFields(model.$.field1, model.$.field2);
|
|
|
8018
6872
|
|
|
8019
6873
|
_Source: src/state/behaviors-value.ts_
|
|
8020
6874
|
|
|
8021
|
-
### toFileArray
|
|
8022
|
-
|
|
8023
|
-
**Kind:** `function`
|
|
8024
|
-
|
|
8025
|
-
Нормализует значение file-поля в массив файлоподобных элементов.
|
|
8026
|
-
|
|
8027
|
-
Одиночный {@link FileLike} оборачивается в массив; из массива отбираются только
|
|
8028
|
-
файлоподобные элементы. Для прочих значений — `null` (валидатор пропускает).
|
|
8029
|
-
|
|
8030
|
-
**Signature:**
|
|
8031
|
-
```typescript
|
|
8032
|
-
export function toFileArray(value: unknown): FileLike[] | null
|
|
8033
|
-
```
|
|
8034
|
-
|
|
8035
|
-
**Parameters:**
|
|
8036
|
-
- `value` — - Значение поля (`FileLike`, `FileLike[]` или что-то ещё)
|
|
8037
|
-
|
|
8038
|
-
**Returns:** Массив файлоподобных элементов или `null`
|
|
8039
|
-
|
|
8040
|
-
_Source: src/form/validation/validators/file-utils.ts_
|
|
8041
|
-
|
|
8042
6875
|
### transformValue
|
|
8043
6876
|
|
|
8044
6877
|
**Kind:** `function`
|
|
@@ -8062,61 +6895,6 @@ transformValue(model.$.promoCode, (v) => (v ?? '').toUpperCase());
|
|
|
8062
6895
|
|
|
8063
6896
|
_Source: src/state/behaviors-value.ts_
|
|
8064
6897
|
|
|
8065
|
-
### uniqueId
|
|
8066
|
-
|
|
8067
|
-
**Kind:** `function`
|
|
8068
|
-
|
|
8069
|
-
Генерирует уникальный идентификатор с указанным префиксом.
|
|
8070
|
-
|
|
8071
|
-
**Signature:**
|
|
8072
|
-
```typescript
|
|
8073
|
-
export function uniqueId(prefix: SubscriptionKeyType): string
|
|
8074
|
-
```
|
|
8075
|
-
|
|
8076
|
-
**Parameters:**
|
|
8077
|
-
- `prefix` — - Префикс для идентификатора (используйте {@link SubscriptionKey}).
|
|
8078
|
-
|
|
8079
|
-
**Returns:** Уникальный идентификатор в формате `${prefix}-${counter}`.
|
|
8080
|
-
|
|
8081
|
-
**Examples:**
|
|
8082
|
-
|
|
8083
|
-
```typescript
|
|
8084
|
-
import { uniqueId, SubscriptionKey } from '@reformer/core';
|
|
8085
|
-
|
|
8086
|
-
uniqueId(SubscriptionKey.WatchField); // → 'watchField-1'
|
|
8087
|
-
uniqueId(SubscriptionKey.WatchField); // → 'watchField-2'
|
|
8088
|
-
```
|
|
8089
|
-
|
|
8090
|
-
_Source: src/form/unique-id.ts_
|
|
8091
|
-
|
|
8092
|
-
### UnknownCallback
|
|
8093
|
-
|
|
8094
|
-
**Kind:** `type`
|
|
8095
|
-
|
|
8096
|
-
Тип для коллбэков и обработчиков событий
|
|
8097
|
-
Используется вместо (...args: any[]) => any
|
|
8098
|
-
|
|
8099
|
-
**Signature:**
|
|
8100
|
-
```typescript
|
|
8101
|
-
export type UnknownCallback = (...args: unknown[]) => unknown;
|
|
8102
|
-
```
|
|
8103
|
-
|
|
8104
|
-
_Source: src/form/types/index.ts_
|
|
8105
|
-
|
|
8106
|
-
### UnknownFormValue
|
|
8107
|
-
|
|
8108
|
-
**Kind:** `type`
|
|
8109
|
-
|
|
8110
|
-
Type-safe alternative to 'any' for unknown form values
|
|
8111
|
-
Requires explicit type checking before use
|
|
8112
|
-
|
|
8113
|
-
**Signature:**
|
|
8114
|
-
```typescript
|
|
8115
|
-
export type UnknownFormValue = unknown;
|
|
8116
|
-
```
|
|
8117
|
-
|
|
8118
|
-
_Source: src/form/types/contracts.ts_
|
|
8119
|
-
|
|
8120
6898
|
### UnknownRecord
|
|
8121
6899
|
|
|
8122
6900
|
**Kind:** `type`
|
|
@@ -8167,50 +6945,6 @@ onDispose(() => unmarkDerived(model.$.total)); // при снятии compute с
|
|
|
8167
6945
|
|
|
8168
6946
|
_Source: src/state/derived-registry.ts_
|
|
8169
6947
|
|
|
8170
|
-
### url
|
|
8171
|
-
|
|
8172
|
-
**Kind:** `function`
|
|
8173
|
-
|
|
8174
|
-
Фабрика валидатора URL.
|
|
8175
|
-
|
|
8176
|
-
Пустые значения (`''`/`null`/`undefined`) пропускаются (используйте {@link required}
|
|
8177
|
-
для обязательности). При `requireProtocol` протокол обязателен; `allowedProtocols`
|
|
8178
|
-
дополнительно ограничивает набор допустимых протоколов.
|
|
8179
|
-
|
|
8180
|
-
**Signature:**
|
|
8181
|
-
```typescript
|
|
8182
|
-
export function url<TForm = unknown, TField extends string | null | undefined = string>(
|
|
8183
|
-
options?: UrlValidatorOptions
|
|
8184
|
-
): Validator<TForm, TField>
|
|
8185
|
-
```
|
|
8186
|
-
|
|
8187
|
-
**Parameters:**
|
|
8188
|
-
- `options` — - Опции валидатора {@link UrlValidatorOptions}
|
|
8189
|
-
|
|
8190
|
-
**Returns:** Чистый валидатор {@link Validator} для строкового поля
|
|
8191
|
-
|
|
8192
|
-
**Examples:**
|
|
8193
|
-
|
|
8194
|
-
Проверка URL
|
|
8195
|
-
```typescript
|
|
8196
|
-
import { required, url } from '@reformer/core/validators';
|
|
8197
|
-
|
|
8198
|
-
// Внутри FieldConfig схемы формы:
|
|
8199
|
-
website: {
|
|
8200
|
-
value: model.$.website,
|
|
8201
|
-
component: Input,
|
|
8202
|
-
validators: [required(), url({ message: 'Введите корректный URL' })],
|
|
8203
|
-
},
|
|
8204
|
-
// Требовать протокол и ограничить схему только https:
|
|
8205
|
-
homepage: {
|
|
8206
|
-
value: model.$.homepage,
|
|
8207
|
-
component: Input,
|
|
8208
|
-
validators: [url({ requireProtocol: true, allowedProtocols: ['https'] })],
|
|
8209
|
-
},
|
|
8210
|
-
```
|
|
8211
|
-
|
|
8212
|
-
_Source: src/form/validation/validators/url.ts_
|
|
8213
|
-
|
|
8214
6948
|
### useArrayLength
|
|
8215
6949
|
|
|
8216
6950
|
**Kind:** `function`
|
|
@@ -8359,7 +7093,7 @@ onChange={e => control.setValue(e.target.checked)}
|
|
|
8359
7093
|
}
|
|
8360
7094
|
|
|
8361
7095
|
// Использование
|
|
8362
|
-
control.
|
|
7096
|
+
control.updateComponentProps({
|
|
8363
7097
|
label: 'Accept terms and conditions',
|
|
8364
7098
|
hint: 'Required to continue'
|
|
8365
7099
|
});
|
|
@@ -8415,7 +7149,7 @@ control.push({ street: '', city: '' });
|
|
|
8415
7149
|
};
|
|
8416
7150
|
|
|
8417
7151
|
const handleRemove = (index: number) => {
|
|
8418
|
-
control.
|
|
7152
|
+
control.removeAt(index);
|
|
8419
7153
|
};
|
|
8420
7154
|
|
|
8421
7155
|
return (
|
|
@@ -8739,24 +7473,6 @@ export interface UseFormValidationResult {
|
|
|
8739
7473
|
|
|
8740
7474
|
_Source: src/form/hooks/use-form-validation.ts_
|
|
8741
7475
|
|
|
8742
|
-
### ValidateAsyncOptions
|
|
8743
|
-
|
|
8744
|
-
**Kind:** `interface`
|
|
8745
|
-
|
|
8746
|
-
**Signature:**
|
|
8747
|
-
```typescript
|
|
8748
|
-
export interface ValidateAsyncOptions extends ValidateOptions {
|
|
8749
|
-
/** Задержка перед выполнением валидации (в мс). */
|
|
8750
|
-
debounce?: number;
|
|
8751
|
-
}
|
|
8752
|
-
```
|
|
8753
|
-
|
|
8754
|
-
**Deprecated:** Осиротевший остаток удалённого оператора `validateAsync` (Ф7): опция `debounce`
|
|
8755
|
-
подключалась тем оператором, которого больше нет. Рантаймом не потребляется; экспортируется
|
|
8756
|
-
только ради обратной совместимости.
|
|
8757
|
-
|
|
8758
|
-
_Source: src/form/types/validation-schema.ts_
|
|
8759
|
-
|
|
8760
7476
|
### ValidateOptions
|
|
8761
7477
|
|
|
8762
7478
|
**Kind:** `interface`
|
|
@@ -8859,33 +7575,3 @@ watchField(model.$.country, async (country) => {
|
|
|
8859
7575
|
```
|
|
8860
7576
|
|
|
8861
7577
|
_Source: src/state/behaviors-value.ts_
|
|
8862
|
-
|
|
8863
|
-
### WithBehaviorSchema
|
|
8864
|
-
|
|
8865
|
-
**Kind:** `interface`
|
|
8866
|
-
|
|
8867
|
-
Интерфейс для узлов с методом applyBehaviorSchema
|
|
8868
|
-
|
|
8869
|
-
**Signature:**
|
|
8870
|
-
```typescript
|
|
8871
|
-
export interface WithBehaviorSchema {
|
|
8872
|
-
applyBehaviorSchema(schemaFn: unknown): void;
|
|
8873
|
-
}
|
|
8874
|
-
```
|
|
8875
|
-
|
|
8876
|
-
_Source: src/form/types/index.ts_
|
|
8877
|
-
|
|
8878
|
-
### WithValidationSchema
|
|
8879
|
-
|
|
8880
|
-
**Kind:** `interface`
|
|
8881
|
-
|
|
8882
|
-
Интерфейс для узлов с методом applyValidationSchema
|
|
8883
|
-
|
|
8884
|
-
**Signature:**
|
|
8885
|
-
```typescript
|
|
8886
|
-
export interface WithValidationSchema {
|
|
8887
|
-
applyValidationSchema(schemaFn: unknown): void;
|
|
8888
|
-
}
|
|
8889
|
-
```
|
|
8890
|
-
|
|
8891
|
-
_Source: src/form/types/index.ts_
|