@reformer/core 1.1.0 → 2.0.0-beta.10

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.
Files changed (221) hide show
  1. package/dist/behaviors/compute-from.d.ts +2 -0
  2. package/dist/behaviors/compute-from.js +31 -0
  3. package/dist/behaviors/copy-from.d.ts +2 -0
  4. package/dist/behaviors/copy-from.js +29 -0
  5. package/dist/behaviors/enable-when.d.ts +2 -0
  6. package/dist/behaviors/enable-when.js +25 -0
  7. package/dist/behaviors/reset-when.d.ts +2 -0
  8. package/dist/behaviors/reset-when.js +24 -0
  9. package/dist/behaviors/revalidate-when.d.ts +2 -0
  10. package/dist/behaviors/revalidate-when.js +18 -0
  11. package/dist/behaviors/sync-fields.d.ts +2 -0
  12. package/dist/behaviors/sync-fields.js +41 -0
  13. package/dist/behaviors/transform-value.d.ts +2 -0
  14. package/dist/behaviors/transform-value.js +45 -0
  15. package/dist/behaviors/watch-field.d.ts +2 -0
  16. package/dist/behaviors/watch-field.js +21 -0
  17. package/dist/behaviors.d.ts +6 -2
  18. package/dist/behaviors.js +27 -228
  19. package/dist/core/behavior/behavior-context.d.ts +32 -14
  20. package/dist/core/behavior/behavior-registry.d.ts +15 -27
  21. package/dist/core/behavior/behaviors/compute-from.d.ts +50 -21
  22. package/dist/core/behavior/behaviors/copy-from.d.ts +39 -14
  23. package/dist/core/behavior/behaviors/enable-when.d.ts +88 -19
  24. package/dist/core/behavior/behaviors/reset-when.d.ts +31 -18
  25. package/dist/core/behavior/behaviors/revalidate-when.d.ts +40 -17
  26. package/dist/core/behavior/behaviors/sync-fields.d.ts +34 -14
  27. package/dist/core/behavior/behaviors/transform-value.d.ts +116 -44
  28. package/dist/core/behavior/behaviors/watch-field.d.ts +66 -21
  29. package/dist/core/behavior/compose-behavior.d.ts +2 -12
  30. package/dist/core/behavior/index.d.ts +0 -1
  31. package/dist/core/behavior/types.d.ts +2 -8
  32. package/dist/core/factories/node-factory.d.ts +6 -29
  33. package/dist/core/nodes/array-node.d.ts +42 -22
  34. package/dist/core/nodes/field-node.d.ts +51 -26
  35. package/dist/core/nodes/form-node.d.ts +18 -20
  36. package/dist/core/nodes/group-node.d.ts +37 -212
  37. package/dist/core/types/deep-schema.d.ts +2 -12
  38. package/dist/core/types/field-path.d.ts +1 -1
  39. package/dist/core/types/form-context.d.ts +36 -30
  40. package/dist/core/types/{group-node-proxy.d.ts → form-proxy.d.ts} +12 -42
  41. package/dist/core/types/index.d.ts +52 -6
  42. package/dist/core/types/validation-schema.d.ts +3 -12
  43. package/dist/core/utils/abstract-registry.d.ts +74 -0
  44. package/dist/core/utils/aggregate-signals.d.ts +71 -0
  45. package/dist/core/utils/create-form.d.ts +3 -20
  46. package/dist/core/utils/error-handler.d.ts +1 -18
  47. package/dist/core/utils/field-path-navigator.d.ts +1 -1
  48. package/dist/core/{validation → utils}/field-path.d.ts +23 -6
  49. package/dist/core/utils/form-observer.d.ts +176 -0
  50. package/dist/core/utils/form-proxy-builder.d.ts +25 -0
  51. package/dist/core/utils/form-submitter.d.ts +121 -0
  52. package/dist/core/utils/index.d.ts +10 -2
  53. package/dist/core/utils/registry-helpers.d.ts +0 -7
  54. package/dist/core/utils/safe-effect.d.ts +73 -0
  55. package/dist/core/utils/status-machine.d.ts +153 -0
  56. package/dist/core/utils/type-guards.d.ts +5 -23
  57. package/dist/core/utils/unique-id.d.ts +53 -0
  58. package/dist/core/validation/core/apply-when.d.ts +3 -9
  59. package/dist/core/validation/core/apply.d.ts +2 -13
  60. package/dist/core/validation/core/validate-async.d.ts +2 -8
  61. package/dist/core/validation/core/validate-tree.d.ts +10 -10
  62. package/dist/core/validation/core/validate.d.ts +1 -7
  63. package/dist/core/validation/index.d.ts +8 -2
  64. package/dist/core/validation/validate-form.d.ts +1 -38
  65. package/dist/core/validation/validation-applicator.d.ts +2 -21
  66. package/dist/core/validation/validation-context.d.ts +67 -28
  67. package/dist/core/validation/validation-registry.d.ts +11 -25
  68. package/dist/core/validation/validators/array-validators.d.ts +2 -12
  69. package/dist/core/validation/validators/date-utils.d.ts +26 -0
  70. package/dist/core/validation/validators/email.d.ts +2 -9
  71. package/dist/core/validation/validators/future-date.d.ts +35 -0
  72. package/dist/core/validation/validators/index.d.ts +7 -1
  73. package/dist/core/validation/validators/is-date.d.ts +36 -0
  74. package/dist/core/validation/validators/max-age.d.ts +36 -0
  75. package/dist/core/validation/validators/max-date.d.ts +36 -0
  76. package/dist/core/validation/validators/max-length.d.ts +3 -10
  77. package/dist/core/validation/validators/max.d.ts +3 -10
  78. package/dist/core/validation/validators/min-age.d.ts +36 -0
  79. package/dist/core/validation/validators/min-date.d.ts +36 -0
  80. package/dist/core/validation/validators/min-length.d.ts +3 -10
  81. package/dist/core/validation/validators/min.d.ts +3 -10
  82. package/dist/core/validation/validators/number.d.ts +2 -9
  83. package/dist/core/validation/validators/past-date.d.ts +35 -0
  84. package/dist/core/validation/validators/pattern.d.ts +2 -9
  85. package/dist/core/validation/validators/phone.d.ts +2 -9
  86. package/dist/core/validation/validators/required.d.ts +2 -9
  87. package/dist/core/validation/validators/url.d.ts +2 -9
  88. package/dist/date-utils-xUWFslTj.js +29 -0
  89. package/dist/field-path-DuKdGcIE.js +66 -0
  90. package/dist/hooks/types.d.ts +328 -0
  91. package/dist/hooks/useArrayLength.d.ts +31 -0
  92. package/dist/hooks/useFormControl.d.ts +15 -39
  93. package/dist/hooks/useFormControlValue.d.ts +167 -0
  94. package/dist/hooks/useHiddenCondition.d.ts +25 -0
  95. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  96. package/dist/index-D25LsbRm.js +73 -0
  97. package/dist/index.d.ts +8 -1
  98. package/dist/index.js +3271 -8
  99. package/dist/registry-helpers-Bv_BJ1s-.js +615 -0
  100. package/dist/safe-effect-Dh8uw81c.js +20 -0
  101. package/dist/validate-C3XiA_zf.js +10 -0
  102. package/dist/validators/email.d.ts +2 -0
  103. package/dist/validators/email.js +13 -0
  104. package/dist/validators/future-date.d.ts +2 -0
  105. package/dist/validators/future-date.js +20 -0
  106. package/dist/validators/is-date.d.ts +2 -0
  107. package/dist/validators/is-date.js +12 -0
  108. package/dist/validators/max-age.d.ts +2 -0
  109. package/dist/validators/max-age.js +20 -0
  110. package/dist/validators/max-date.d.ts +2 -0
  111. package/dist/validators/max-date.js +20 -0
  112. package/dist/validators/max-length.d.ts +2 -0
  113. package/dist/validators/max-length.js +11 -0
  114. package/dist/validators/max.d.ts +2 -0
  115. package/dist/validators/max.js +11 -0
  116. package/dist/validators/min-age.d.ts +2 -0
  117. package/dist/validators/min-age.js +20 -0
  118. package/dist/validators/min-date.d.ts +2 -0
  119. package/dist/validators/min-date.js +20 -0
  120. package/dist/validators/min-length.d.ts +2 -0
  121. package/dist/validators/min-length.js +11 -0
  122. package/dist/validators/min.d.ts +2 -0
  123. package/dist/validators/min.js +11 -0
  124. package/dist/validators/number.d.ts +2 -0
  125. package/dist/validators/number.js +35 -0
  126. package/dist/validators/past-date.d.ts +2 -0
  127. package/dist/validators/past-date.js +20 -0
  128. package/dist/validators/pattern.d.ts +2 -0
  129. package/dist/validators/pattern.js +11 -0
  130. package/dist/validators/phone.d.ts +2 -0
  131. package/dist/validators/phone.js +35 -0
  132. package/dist/validators/required.d.ts +2 -0
  133. package/dist/validators/required.js +15 -0
  134. package/dist/validators/url.d.ts +2 -0
  135. package/dist/validators/url.js +19 -0
  136. package/dist/validators-BGsNOgT1.js +207 -0
  137. package/dist/validators.d.ts +6 -2
  138. package/dist/validators.js +54 -296
  139. package/llms.txt +8887 -59
  140. package/package.json +87 -8
  141. package/dist/core/behavior/behavior-applicator.d.ts +0 -71
  142. package/dist/core/behavior/behavior-applicator.js +0 -92
  143. package/dist/core/behavior/behavior-context.js +0 -38
  144. package/dist/core/behavior/behavior-registry.js +0 -198
  145. package/dist/core/behavior/behaviors/compute-from.js +0 -84
  146. package/dist/core/behavior/behaviors/copy-from.js +0 -64
  147. package/dist/core/behavior/behaviors/enable-when.js +0 -81
  148. package/dist/core/behavior/behaviors/index.js +0 -11
  149. package/dist/core/behavior/behaviors/reset-when.js +0 -63
  150. package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
  151. package/dist/core/behavior/behaviors/sync-fields.js +0 -66
  152. package/dist/core/behavior/behaviors/transform-value.js +0 -110
  153. package/dist/core/behavior/behaviors/watch-field.js +0 -56
  154. package/dist/core/behavior/compose-behavior.js +0 -166
  155. package/dist/core/behavior/create-field-path.d.ts +0 -20
  156. package/dist/core/behavior/create-field-path.js +0 -69
  157. package/dist/core/behavior/index.js +0 -17
  158. package/dist/core/behavior/types.js +0 -7
  159. package/dist/core/context/form-context-impl.d.ts +0 -29
  160. package/dist/core/context/form-context-impl.js +0 -37
  161. package/dist/core/factories/index.js +0 -6
  162. package/dist/core/factories/node-factory.js +0 -281
  163. package/dist/core/nodes/array-node.js +0 -534
  164. package/dist/core/nodes/field-node.js +0 -510
  165. package/dist/core/nodes/form-node.js +0 -343
  166. package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
  167. package/dist/core/nodes/group-node/field-registry.js +0 -215
  168. package/dist/core/nodes/group-node/index.d.ts +0 -11
  169. package/dist/core/nodes/group-node/index.js +0 -11
  170. package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
  171. package/dist/core/nodes/group-node/proxy-builder.js +0 -161
  172. package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
  173. package/dist/core/nodes/group-node/state-manager.js +0 -265
  174. package/dist/core/nodes/group-node.js +0 -770
  175. package/dist/core/types/deep-schema.js +0 -11
  176. package/dist/core/types/field-path.js +0 -4
  177. package/dist/core/types/form-context.js +0 -25
  178. package/dist/core/types/group-node-proxy.js +0 -31
  179. package/dist/core/types/index.js +0 -4
  180. package/dist/core/types/validation-schema.js +0 -10
  181. package/dist/core/utils/create-form.js +0 -24
  182. package/dist/core/utils/debounce.d.ts +0 -160
  183. package/dist/core/utils/debounce.js +0 -197
  184. package/dist/core/utils/error-handler.js +0 -226
  185. package/dist/core/utils/field-path-navigator.js +0 -374
  186. package/dist/core/utils/index.js +0 -14
  187. package/dist/core/utils/registry-helpers.js +0 -79
  188. package/dist/core/utils/registry-stack.js +0 -86
  189. package/dist/core/utils/resources.d.ts +0 -41
  190. package/dist/core/utils/resources.js +0 -69
  191. package/dist/core/utils/subscription-manager.js +0 -214
  192. package/dist/core/utils/type-guards.js +0 -169
  193. package/dist/core/validation/core/apply-when.js +0 -41
  194. package/dist/core/validation/core/apply.js +0 -38
  195. package/dist/core/validation/core/index.js +0 -8
  196. package/dist/core/validation/core/validate-async.js +0 -45
  197. package/dist/core/validation/core/validate-tree.js +0 -37
  198. package/dist/core/validation/core/validate.js +0 -38
  199. package/dist/core/validation/field-path.js +0 -147
  200. package/dist/core/validation/index.js +0 -33
  201. package/dist/core/validation/validate-form.js +0 -152
  202. package/dist/core/validation/validation-applicator.js +0 -217
  203. package/dist/core/validation/validation-context.js +0 -75
  204. package/dist/core/validation/validation-registry.js +0 -298
  205. package/dist/core/validation/validators/array-validators.js +0 -86
  206. package/dist/core/validation/validators/date.d.ts +0 -38
  207. package/dist/core/validation/validators/date.js +0 -117
  208. package/dist/core/validation/validators/email.js +0 -60
  209. package/dist/core/validation/validators/index.js +0 -14
  210. package/dist/core/validation/validators/max-length.js +0 -60
  211. package/dist/core/validation/validators/max.js +0 -60
  212. package/dist/core/validation/validators/min-length.js +0 -60
  213. package/dist/core/validation/validators/min.js +0 -60
  214. package/dist/core/validation/validators/number.js +0 -90
  215. package/dist/core/validation/validators/pattern.js +0 -62
  216. package/dist/core/validation/validators/phone.js +0 -58
  217. package/dist/core/validation/validators/required.js +0 -69
  218. package/dist/core/validation/validators/url.js +0 -55
  219. package/dist/create-field-path-CdPF3lIK.js +0 -704
  220. package/dist/hooks/useFormControl.js +0 -298
  221. package/dist/node-factory-D7DOnSSN.js +0 -3200
@@ -1,21 +1,25 @@
1
+ import { GroupNode } from '../nodes/group-node';
2
+ import { BehaviorHandlerFn, BehaviorOptions } from './types';
3
+ import { AbstractRegistry } from '../utils/abstract-registry';
4
+ import { FormFields } from '../types';
1
5
  /**
2
- * BehaviorRegistry - регистрация и управление behavior схемами
3
- *
4
- * Аналогично ValidationRegistry, но для реактивного поведения форм
6
+ * Зарегистрированный behavior с опциями
5
7
  */
6
- import type { GroupNode } from '../nodes/group-node';
7
- import type { BehaviorHandlerFn, BehaviorOptions } from './types';
8
- import { FormFields } from '../types';
8
+ export interface RegisteredBehavior {
9
+ /** Handler функция behavior */
10
+ handler: BehaviorHandlerFn<FormFields>;
11
+ /** Debounce в миллисекундах */
12
+ debounce?: number;
13
+ }
9
14
  /**
10
15
  * Реестр behaviors для формы
11
16
  *
12
17
  * Каждый экземпляр GroupNode создает собственный реестр (композиция).
13
18
  * Устраняет race conditions и изолирует формы друг от друга.
14
19
  *
15
- * Context stack используется для tracking текущего активного реестра:
16
- * - beginRegistration() помещает this в stack
17
- * - endRegistration() извлекает из stack
18
- * - getCurrent() возвращает текущий активный реестр
20
+ * Наследует AbstractRegistry для унификации:
21
+ * - Управления global stack
22
+ * - Template methods begin/end registration
19
23
  *
20
24
  * @example
21
25
  * ```typescript
@@ -30,14 +34,7 @@ import { FormFields } from '../types';
30
34
  * }
31
35
  * ```
32
36
  */
33
- export declare class BehaviorRegistry {
34
- /**
35
- * Stack активных контекстов регистрации
36
- * Используется для изоляции форм друг от друга
37
- */
38
- private static contextStack;
39
- private registrations;
40
- private isRegistering;
37
+ export declare class BehaviorRegistry extends AbstractRegistry<RegisteredBehavior> {
41
38
  /**
42
39
  * Получить текущий активный реестр из context stack
43
40
  *
@@ -55,13 +52,6 @@ export declare class BehaviorRegistry {
55
52
  * ```
56
53
  */
57
54
  static getCurrent(): BehaviorRegistry | null;
58
- /**
59
- * Начать регистрацию behaviors
60
- * Вызывается перед применением схемы
61
- *
62
- * Помещает this в context stack для изоляции форм
63
- */
64
- beginRegistration(): void;
65
55
  /**
66
56
  * Зарегистрировать behavior handler
67
57
  * Вызывается функциями из schema-behaviors.ts
@@ -80,8 +70,6 @@ export declare class BehaviorRegistry {
80
70
  * Завершить регистрацию и применить behaviors к форме
81
71
  * Создает effect подписки для всех зарегистрированных behaviors
82
72
  *
83
- * Извлекает this из context stack
84
- *
85
73
  * @param form - GroupNode формы
86
74
  * @returns Количество зарегистрированных behaviors и функция cleanup
87
75
  */
@@ -1,12 +1,5 @@
1
- /**
2
- * Вычисляемые поля
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/computeFrom
7
- */
8
- import type { FieldPathNode } from '../../types';
9
- import type { ComputeFromOptions } from '../types';
1
+ import { FieldPathNode } from '../../types';
2
+ import { ComputeFromOptions } from '../types';
10
3
  /**
11
4
  * Автоматически вычисляет значение поля на основе других полей
12
5
  *
@@ -16,26 +9,62 @@ import type { ComputeFromOptions } from '../types';
16
9
  * @param sources - Массив полей-зависимостей
17
10
  * @param target - Поле для записи результата
18
11
  * @param computeFn - Функция вычисления (принимает объект с именами полей)
19
- * @param options - Опции
12
+ * @param options - Опции (`debounce`, `condition`, `trigger`)
20
13
  *
21
- * @example
14
+ * @example Многополевой расчёт — total = price × quantity
22
15
  * ```typescript
23
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
24
- * // Автоматический расчет минимального взноса
25
- * computeFrom(
26
- * [path.propertyValue],
27
- * path.initialPayment,
28
- * (values) => values.propertyValue ? values.propertyValue * 0.2 : null,
29
- * { debounce: 300 }
30
- * );
16
+ * import { computeFrom, type BehaviorSchemaFn } from '@reformer/core/behaviors';
31
17
  *
32
- * // Общая стоимость = цена * количество
18
+ * interface OrderForm {
19
+ * price: number;
20
+ * quantity: number;
21
+ * total: number;
22
+ * }
23
+ *
24
+ * export const orderBehavior: BehaviorSchemaFn<OrderForm> = (path) => {
33
25
  * computeFrom(
34
26
  * [path.price, path.quantity],
35
27
  * path.total,
36
- * (values) => values.price * values.quantity
28
+ * (values) =>
29
+ * (typeof values.price === 'number' ? values.price : 0) *
30
+ * (typeof values.quantity === 'number' ? values.quantity : 0),
31
+ * );
32
+ * };
33
+ * ```
34
+ *
35
+ * @example Edge case — async-like дорогие вычисления с `debounce` и условием
36
+ * ```typescript
37
+ * import { computeFrom, type BehaviorSchemaFn } from '@reformer/core/behaviors';
38
+ *
39
+ * interface MortgageForm {
40
+ * loanType: 'mortgage' | 'consumer';
41
+ * loanAmount: number;
42
+ * loanTerm: number;
43
+ * interestRate: number;
44
+ * monthlyPayment: number;
45
+ * }
46
+ *
47
+ * function annuity(values: MortgageForm): number {
48
+ * const { loanAmount, loanTerm, interestRate } = values;
49
+ * if (!loanAmount || !loanTerm || !interestRate) return 0;
50
+ * const r = interestRate / 100 / 12;
51
+ * const n = loanTerm;
52
+ * return Math.round((loanAmount * r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1));
53
+ * }
54
+ *
55
+ * export const mortgageBehavior: BehaviorSchemaFn<MortgageForm> = (path) => {
56
+ * computeFrom(
57
+ * [path.loanAmount, path.loanTerm, path.interestRate],
58
+ * path.monthlyPayment,
59
+ * annuity,
60
+ * {
61
+ * debounce: 300, // не пересчитываем на каждый keystroke
62
+ * condition: (form) => form.loanType === 'mortgage', // считаем только для ипотеки
63
+ * },
37
64
  * );
38
65
  * };
39
66
  * ```
67
+ *
68
+ * @see [docs/llms/20-compute-vs-watch.md](../../../../docs/llms/20-compute-vs-watch.md)
40
69
  */
41
70
  export declare function computeFrom<TForm, TTarget>(sources: FieldPathNode<TForm, any>[], target: FieldPathNode<TForm, TTarget>, computeFn: (values: TForm) => TTarget, options?: ComputeFromOptions<TForm>): void;
@@ -1,12 +1,5 @@
1
- /**
2
- * Копирование значений между полями
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/copyFrom
7
- */
8
- import type { FieldPathNode } from '../../types';
9
- import type { CopyFromOptions } from '../types';
1
+ import { FieldPathNode } from '../../types';
2
+ import { CopyFromOptions } from '../types';
10
3
  /**
11
4
  * Копирует значения из одного поля/группы в другое при выполнении условия
12
5
  *
@@ -15,17 +8,49 @@ import type { CopyFromOptions } from '../types';
15
8
  *
16
9
  * @param source - Откуда копировать
17
10
  * @param target - Куда копировать
18
- * @param options - Опции копирования
11
+ * @param options - Опции копирования (`when`, `fields`, `transform`, `debounce`)
19
12
  *
20
- * @example
13
+ * @example Скаляр → скаляр с условием
21
14
  * ```typescript
22
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
23
- * // Копировать адрес регистрации в адрес проживания
15
+ * import { copyFrom, type BehaviorSchemaFn } from '@reformer/core/behaviors';
16
+ *
17
+ * interface ContactForm {
18
+ * sameEmail: boolean;
19
+ * email: string;
20
+ * emailAdditional: string;
21
+ * }
22
+ *
23
+ * export const contactBehavior: BehaviorSchemaFn<ContactForm> = (path) => {
24
+ * copyFrom(path.email, path.emailAdditional, {
25
+ * when: (form) => form.sameEmail === true,
26
+ * });
27
+ * };
28
+ * ```
29
+ *
30
+ * @example Копирование группы с подмножеством полей и `transform`
31
+ * ```typescript
32
+ * import { copyFrom, type BehaviorSchemaFn } from '@reformer/core/behaviors';
33
+ *
34
+ * interface Address { country: string; region: string; city: string; street: string }
35
+ * interface ProfileForm {
36
+ * sameAsRegistration: boolean;
37
+ * registrationAddress: Address;
38
+ * residenceAddress: Address;
39
+ * }
40
+ *
41
+ * export const profileBehavior: BehaviorSchemaFn<ProfileForm> = (path) => {
24
42
  * copyFrom(path.registrationAddress, path.residenceAddress, {
25
43
  * when: (form) => form.sameAsRegistration === true,
26
- * fields: 'all'
44
+ * fields: ['country', 'region', 'city'], // street НЕ копируем
45
+ * transform: (addr) => ({
46
+ * ...addr,
47
+ * country: addr.country.toUpperCase(), // нормализация при копировании
48
+ * }),
49
+ * debounce: 200,
27
50
  * });
28
51
  * };
29
52
  * ```
53
+ *
54
+ * @see [docs/llms/23-copy-from.md](../../../../docs/llms/23-copy-from.md)
30
55
  */
31
56
  export declare function copyFrom<TForm, TSource, TTarget>(source: FieldPathNode<TForm, TSource>, target: FieldPathNode<TForm, TTarget>, options?: CopyFromOptions<TSource, TForm>): void;
@@ -1,12 +1,5 @@
1
- /**
2
- * Условное включение/отключение полей
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/enableWhen
7
- */
8
- import type { FieldPathNode } from '../../types';
9
- import type { EnableWhenOptions } from '../types';
1
+ import { FieldPathNode } from '../../types';
2
+ import { EnableWhenOptions } from '../types';
10
3
  /**
11
4
  * Условное включение поля на основе значений других полей
12
5
  *
@@ -15,17 +8,68 @@ import type { EnableWhenOptions } from '../types';
15
8
  *
16
9
  * @param field - Поле для включения/выключения
17
10
  * @param condition - Функция условия (true = enable, false = disable)
18
- * @param options - Опции
11
+ * @param options - Опции (`resetOnDisable`, `debounce`)
19
12
  *
20
- * @example
13
+ * @example Базовый сценарий с `resetOnDisable: true`
21
14
  * ```typescript
22
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
23
- * // Включить поле только для ипотеки
15
+ * import { enableWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
16
+ *
17
+ * interface LoanForm {
18
+ * loanType: 'mortgage' | 'consumer' | 'car';
19
+ * propertyValue: number;
20
+ * initialPayment: number;
21
+ * }
22
+ *
23
+ * export const loanBehavior: BehaviorSchemaFn<LoanForm> = (path) => {
24
+ * // Поля ипотеки активны только для loanType === 'mortgage'.
25
+ * // resetOnDisable: true гарантирует чистые initial values при переключении.
24
26
  * enableWhen(path.propertyValue, (form) => form.loanType === 'mortgage', {
25
- * resetOnDisable: true
27
+ * resetOnDisable: true,
28
+ * });
29
+ * enableWhen(path.initialPayment, (form) => form.loanType === 'mortgage', {
30
+ * resetOnDisable: true,
26
31
  * });
27
32
  * };
28
33
  * ```
34
+ *
35
+ * @example Множественные independent условия + cycle prevention
36
+ * ```typescript
37
+ * import { enableWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
38
+ *
39
+ * interface ProfileForm {
40
+ * sameAsRegistration: boolean;
41
+ * employmentStatus: 'employed' | 'selfEmployed' | 'unemployed';
42
+ * residenceAddress: { city: string; street: string };
43
+ * companyName: string;
44
+ * companyInn: string;
45
+ * businessType: string;
46
+ * }
47
+ *
48
+ * export const profileBehavior: BehaviorSchemaFn<ProfileForm> = (path) => {
49
+ * // Адрес проживания: enabled, когда НЕ совпадает с регистрационным
50
+ * enableWhen(path.residenceAddress, (form) => form.sameAsRegistration === false, {
51
+ * resetOnDisable: true,
52
+ * });
53
+ *
54
+ * // Поля работодателя: только для employed
55
+ * enableWhen(path.companyName, (form) => form.employmentStatus === 'employed', {
56
+ * resetOnDisable: true,
57
+ * });
58
+ * enableWhen(path.companyInn, (form) => form.employmentStatus === 'employed', {
59
+ * resetOnDisable: true,
60
+ * });
61
+ *
62
+ * // ИП-поля: только для selfEmployed
63
+ * enableWhen(path.businessType, (form) => form.employmentStatus === 'selfEmployed', {
64
+ * resetOnDisable: true,
65
+ * });
66
+ *
67
+ * // ВАЖНО: condition не должен читать значение САМОГО поля — иначе цикл.
68
+ * // condition зависит ТОЛЬКО от независимых триггеров (loanType, employmentStatus, ...).
69
+ * };
70
+ * ```
71
+ *
72
+ * @see [docs/llms/22-cycle-detection.md](../../../../docs/llms/22-cycle-detection.md)
29
73
  */
30
74
  export declare function enableWhen<TForm>(field: FieldPathNode<TForm, any>, condition: (form: TForm) => boolean, options?: EnableWhenOptions): void;
31
75
  /**
@@ -36,13 +80,38 @@ export declare function enableWhen<TForm>(field: FieldPathNode<TForm, any>, cond
36
80
  *
37
81
  * @param field - Поле для выключения
38
82
  * @param condition - Функция условия (true = disable, false = enable)
39
- * @param options - Опции
83
+ * @param options - Опции (`resetOnDisable`, `debounce`)
40
84
  *
41
- * @example
85
+ * @example Базовый сценарий — readonly после подтверждения
42
86
  * ```typescript
43
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
44
- * // Выключить поле для потребительского кредита
45
- * disableWhen(path.propertyValue, (form) => form.loanType === 'consumer');
87
+ * import { disableWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
88
+ *
89
+ * interface ConfirmForm {
90
+ * isConfirmed: boolean;
91
+ * editableField: string;
92
+ * }
93
+ *
94
+ * export const confirmBehavior: BehaviorSchemaFn<ConfirmForm> = (path) => {
95
+ * // Поле блокируется после установки чекбокса подтверждения
96
+ * disableWhen(path.editableField, (form) => form.isConfirmed === true);
97
+ * // resetOnDisable НЕ ставим — сохраняем введённый текст
98
+ * };
99
+ * ```
100
+ *
101
+ * @example С `resetOnDisable` для очистки заблокированного поля
102
+ * ```typescript
103
+ * import { disableWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
104
+ *
105
+ * interface PromoForm {
106
+ * loanType: 'mortgage' | 'consumer';
107
+ * promoCode: string;
108
+ * }
109
+ *
110
+ * export const promoBehavior: BehaviorSchemaFn<PromoForm> = (path) => {
111
+ * // Промокод недоступен для потребительских кредитов и сбрасывается
112
+ * disableWhen(path.promoCode, (form) => form.loanType === 'consumer', {
113
+ * resetOnDisable: true,
114
+ * });
46
115
  * };
47
116
  * ```
48
117
  */
@@ -1,11 +1,4 @@
1
- /**
2
- * Условный сброс полей
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/resetWhen
7
- */
8
- import type { FieldPathNode, FormFields, FormValue } from '../../types';
1
+ import { FieldPathNode, FormFields, FormValue } from '../../types';
9
2
  /**
10
3
  * Опции для resetWhen
11
4
  *
@@ -26,25 +19,45 @@ export interface ResetWhenOptions {
26
19
  *
27
20
  * @param field - Поле для сброса
28
21
  * @param condition - Функция условия (true = reset)
29
- * @param options - Опции
22
+ * @param options - Опции (`resetValue`, `onlyIfDirty`, `debounce`)
30
23
  *
31
- * @example
24
+ * @example Сброс зависимого поля при смене типа платежа
32
25
  * ```typescript
33
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
34
- * // Сбросить поле при изменении типа кредита
35
- * resetWhen(path.propertyValue, (form) => form.loanType !== 'mortgage');
26
+ * import { resetWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
27
+ *
28
+ * interface CheckoutForm {
29
+ * paymentType: 'card' | 'cash';
30
+ * cardNumber: string;
31
+ * }
36
32
  *
37
- * // Сбросить с кастомным значением
38
- * resetWhen(path.initialPayment, (form) => !form.propertyValue, {
39
- * resetValue: 0
33
+ * export const checkoutBehavior: BehaviorSchemaFn<CheckoutForm> = (path) => {
34
+ * // Когда выбрано НЕ card — обнуляем номер карты в пустую строку
35
+ * resetWhen(path.cardNumber, (form) => form.paymentType !== 'card', {
36
+ * resetValue: '',
40
37
  * });
38
+ * };
39
+ * ```
40
+ *
41
+ * @example `onlyIfDirty` — не трогаем нетронутые initial значения
42
+ * ```typescript
43
+ * import { resetWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
44
+ *
45
+ * interface CarForm {
46
+ * loanType: 'mortgage' | 'car' | 'consumer';
47
+ * carPrice: number;
48
+ * }
41
49
  *
42
- * // Сбросить только если поле было изменено пользователем
50
+ * export const carBehavior: BehaviorSchemaFn<CarForm> = (path) => {
51
+ * // Если пользователь не вводил carPrice — оставляем default из схемы.
52
+ * // Сбрасываем только если поле dirty (была пользовательская правка).
43
53
  * resetWhen(path.carPrice, (form) => form.loanType !== 'car', {
44
- * onlyIfDirty: true
54
+ * resetValue: 0,
55
+ * onlyIfDirty: true,
45
56
  * });
46
57
  * };
47
58
  * ```
59
+ *
60
+ * @see [docs/llms/25-reset-when.md](../../../../docs/llms/25-reset-when.md)
48
61
  */
49
62
  export declare function resetWhen<TForm extends FormFields>(field: FieldPathNode<TForm, FormValue>, condition: (form: TForm) => boolean, options?: ResetWhenOptions & {
50
63
  debounce?: number;
@@ -1,12 +1,5 @@
1
- /**
2
- * Перевалидация полей при изменениях
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/revalidateWhen
7
- */
8
- import type { FieldPathNode, FormValue } from '../../types';
9
- import type { RevalidateWhenOptions } from '../types';
1
+ import { FieldPathNode, FormValue } from '../../types';
2
+ import { RevalidateWhenOptions } from '../types';
10
3
  /**
11
4
  * Перевалидирует поле при изменении других полей
12
5
  *
@@ -14,17 +7,47 @@ import type { RevalidateWhenOptions } from '../types';
14
7
  * @category Behavior Rules
15
8
  *
16
9
  * @param target - Поле для перевалидации
17
- * @param triggers - Поля-триггеры
18
- * @param options - Опции
10
+ * @param triggers - Поля-триггеры (НЕ должно содержать `target`)
11
+ * @param options - Опции (`debounce`)
12
+ *
13
+ * @example Парная перевалидация — confirmPassword при смене password
14
+ * ```typescript
15
+ * import { revalidateWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
16
+ * import { equalTo } from '@reformer/core/validators';
17
+ * import type { FieldPath } from '@reformer/core';
18
+ *
19
+ * interface RegistrationForm { password: string; confirmPassword: string }
19
20
  *
20
- * @example
21
+ * export const validation = (path: FieldPath<RegistrationForm>) => {
22
+ * equalTo(path.confirmPassword, path.password, { message: 'Пароли не совпадают' });
23
+ * };
24
+ *
25
+ * export const behavior: BehaviorSchemaFn<RegistrationForm> = (path) => {
26
+ * // Если пользователь сначала ввёл confirm, потом меняет password —
27
+ * // без revalidateWhen ошибка confirmPassword останется устаревшей.
28
+ * revalidateWhen(path.confirmPassword, [path.password]);
29
+ * };
30
+ * ```
31
+ *
32
+ * @example Несколько триггеров + `debounce` для async-валидаторов
21
33
  * ```typescript
22
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
23
- * // Перевалидировать initialPayment при изменении propertyValue
24
- * revalidateWhen(path.initialPayment, [path.propertyValue], {
25
- * debounce: 300
26
- * });
34
+ * import { revalidateWhen, type BehaviorSchemaFn } from '@reformer/core/behaviors';
35
+ *
36
+ * interface MortgageForm {
37
+ * propertyValue: number;
38
+ * loanAmount: number;
39
+ * initialPayment: number; // правило: initialPayment >= propertyValue * 0.2 - loanAmount
40
+ * }
41
+ *
42
+ * export const mortgageBehavior: BehaviorSchemaFn<MortgageForm> = (path) => {
43
+ * revalidateWhen(
44
+ * path.initialPayment,
45
+ * [path.propertyValue, path.loanAmount],
46
+ * { debounce: 300 }, // не дёргаем сервер на каждый keystroke
47
+ * );
27
48
  * };
28
49
  * ```
50
+ *
51
+ * @see [docs/llms/27-revalidate-when.md](../../../../docs/llms/27-revalidate-when.md)
29
52
  */
30
53
  export declare function revalidateWhen<TForm>(target: FieldPathNode<TForm, FormValue>, triggers: FieldPathNode<TForm, FormValue>[], options?: RevalidateWhenOptions): void;
@@ -1,12 +1,5 @@
1
- /**
2
- * Двусторонняя синхронизация полей
3
- *
4
- * @group Behaviors
5
- * @category Behavior Rules
6
- * @module behaviors/syncFields
7
- */
8
- import type { FieldPathNode, FormFields, FormValue } from '../../types';
9
- import type { SyncFieldsOptions } from '../types';
1
+ import { FieldPathNode, FormFields, FormValue } from '../../types';
2
+ import { SyncFieldsOptions } from '../types';
10
3
  /**
11
4
  * Двусторонняя синхронизация двух полей
12
5
  *
@@ -15,14 +8,41 @@ import type { SyncFieldsOptions } from '../types';
15
8
  *
16
9
  * @param field1 - Первое поле
17
10
  * @param field2 - Второе поле
18
- * @param options - Опции
11
+ * @param options - Опции (`transform` асимметричен — применяется только field1 → field2; `debounce`)
12
+ *
13
+ * @example Базовый mirror двух текстовых полей
14
+ * ```typescript
15
+ * import { syncFields, type BehaviorSchemaFn } from '@reformer/core/behaviors';
19
16
  *
20
- * @example
17
+ * interface MirrorForm {
18
+ * syncField1: string;
19
+ * syncField2: string;
20
+ * }
21
+ *
22
+ * export const mirrorBehavior: BehaviorSchemaFn<MirrorForm> = (path) => {
23
+ * syncFields(path.syncField1, path.syncField2);
24
+ * };
25
+ * ```
26
+ *
27
+ * @example С `transform` (асимметричный) и `debounce` для защиты от частых перезаписей
21
28
  * ```typescript
22
- * const schema: BehaviorSchemaFn<MyForm> = (path) => {
23
- * // Синхронизировать два поля
24
- * syncFields(path.email, path.emailCopy);
29
+ * import { syncFields, type BehaviorSchemaFn } from '@reformer/core/behaviors';
30
+ *
31
+ * interface CodeForm {
32
+ * internalCode: string; // канонический формат
33
+ * displayCode: string; // показываем пользователю
34
+ * }
35
+ *
36
+ * export const codeBehavior: BehaviorSchemaFn<CodeForm> = (path) => {
37
+ * // internalCode → displayCode: применяется toUpperCase
38
+ * // displayCode → internalCode: пишется как есть
39
+ * syncFields(path.internalCode, path.displayCode, {
40
+ * transform: (value) => (typeof value === 'string' ? value.toUpperCase() : value),
41
+ * debounce: 150, // сглаживает дёргание каретки
42
+ * });
25
43
  * };
26
44
  * ```
45
+ *
46
+ * @see [docs/llms/24-sync-fields.md](../../../../docs/llms/24-sync-fields.md)
27
47
  */
28
48
  export declare function syncFields<TForm extends FormFields, T extends FormValue>(field1: FieldPathNode<TForm, T>, field2: FieldPathNode<TForm, T>, options?: SyncFieldsOptions<T>): void;