@companix/formkit 0.0.30 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  const scheme = [
9
9
  Label('Имя')(TextForm('name', { placeholder: 'Иван', $rules: { required: true } })),
10
10
  CheckboxForm('hasCompany', { title: 'Представляю компанию' }),
11
- Condition('hasCompany', { canActivate: (checked: boolean) => checked })(
11
+ OptionalCondition('hasCompany', { canActivate: (checked: boolean) => checked })(
12
12
  Context('company')(Label('Компания')(TextForm('name', { placeholder: 'ООО «Ромашка»' })))
13
13
  )
14
14
  ]
@@ -26,8 +26,9 @@ const scheme = [
26
26
  вложенные контексты и необязательность полей под условием.
27
27
  - **Поле пишется один раз.** `createForm` превращает любой компонент ввода в поле: умолчание, «что считать пустым» и
28
28
  отрисовка ошибки живут в нём, а не в каждой форме.
29
- - **Условия и вложенность из коробки.** `Condition` показывает поля по значению другого поля, `Context` складывает их
30
- в объект; скрытое поле не попадает ни в значения, ни в проверку.
29
+ - **Условия и вложенность из коробки.** `OptionalCondition` показывает поля по значению другого поля, `Context`
30
+ складывает их в объект; скрытое поле не попадает ни в значения, ни в проверку, а под `NullableCondition` приходит
31
+ `null`.
31
32
  - **Состояние вне React.** Значения держит менеджер формы: правка поля перерисовывает это поле и тех, кто на него
32
33
  подписан, а не всю форму и не экран вокруг неё.
33
34
  - **Изменённость.** Форма знает, что её правили, сообщает об этом и при отправке без изменений вызывает `onEqual`
@@ -168,14 +169,15 @@ Card({ title: 'Контакты', hint: 'Видят только менедже
168
169
 
169
170
  ## Схема
170
171
 
171
- | Элемент | Что делает | В значениях |
172
- | ---------------------------------------- | ------------------------------------------------------------------------- | ------------------ |
173
- | `XForm('name', params)` | поле | `name: V` |
174
- | `Layout(params)(…)` | разметка вокруг полей | поля как есть |
175
- | `Context('name')(…)` | вложенный объект: имена полей внутри — `name.field` | `name: { … }` |
176
- | `Condition('field', { canActivate })(…)` | поля показаны, пока `canActivate(значение поля)` верно; имя — полный путь | поля необязательны |
177
- | `Visablility({ hidden })(…)` | поля не рисуются, но несут значение из `defaultValues` | поля необязательны |
178
- | `createExtraForm(…)` | поля, которые пользователь добавляет и убирает сам | поля необязательны |
172
+ | Элемент | Что делает | В значениях |
173
+ | ------------------------------------------------ | ------------------------------------------------------------------------- | ------------------ |
174
+ | `XForm('name', params)` | поле | `name: V` |
175
+ | `Layout(params)(…)` | разметка вокруг полей | поля как есть |
176
+ | `Context('name')(…)` | вложенный объект: имена полей внутри — `name.field` | `name: { … }` |
177
+ | `OptionalCondition('field', { canActivate })(…)` | поля показаны, пока `canActivate(значение поля)` верно; имя — полный путь | поля необязательны |
178
+ | `NullableCondition('field', { canActivate })(…)` | как `OptionalCondition`, но скрытая ветка отдаёт `null` своим именам | `name: V \| null` |
179
+ | `Visablility({ hidden })(…)` | поля не рисуются, но несут значение из `defaultValues` | поля необязательны |
180
+ | `createExtraForm(…)` | поля, которые пользователь добавляет и убирает сам | поля необязательны |
179
181
 
180
182
  Значения `onSubmit` и `onChange` выводятся из схемы сами, тип `defaultValues` схемы — `GetDefaultValues<typeof scheme>`.
181
183
 
@@ -226,6 +228,42 @@ defaultValues: {
226
228
  }
227
229
  ```
228
230
 
231
+ ### Данные или `null` — `NullableCondition`
232
+
233
+ Часто включаемый блок в данных — объект или `null`: выключенное условие хранится как `null`, а не отдельным флажком.
234
+ `OptionalCondition` даёт такому блоку `undefined` — скрытая ветка пропадает из значений. `NullableCondition` ведёт себя
235
+ так же, но скрытая ветка отдаёт `null` своим именам — полям и контекстам уровня ветки; раскладки и вложенные условия
236
+ внутри неё прозрачны. Имена — как `.optional()` и `.nullable()` в zod: `name?: V` против `name: V | null`.
237
+
238
+ ```tsx
239
+ const scheme = [
240
+ CheckboxForm('hasCompany', { title: 'Представляю компанию' }),
241
+ NullableCondition('hasCompany', { canActivate: (checked: boolean) => checked })(
242
+ Context('company')(Label('Компания')(TextForm('name', { placeholder: 'ООО «Ромашка»' })))
243
+ )
244
+ ]
245
+
246
+ // onSubmit получит { hasCompany: boolean; company: { name: string } | null }
247
+ ```
248
+
249
+ `null` у такого имени в `defaultValues` — отсутствие данных, как `undefined`: поля ветки начнут с умолчаний своих
250
+ компонентов. Блок из данных передаётся как есть, флажок выводится из него:
251
+
252
+ ```tsx
253
+ const form = useForm(scheme, {
254
+ defaultValues: {
255
+ hasCompany: profile.company !== null,
256
+ company: profile.company // { name: string } | null
257
+ },
258
+ onSubmit: async (values) => {
259
+ await api.saveProfile(values) // company — как в данных: объект или null
260
+ }
261
+ })
262
+ ```
263
+
264
+ Ветка из одного поля, у которого `null` — своё значение (стёртое число, дата без выбора), отдаёт `null` и скрытой, и
265
+ пустой: различает их флажок.
266
+
229
267
  ## Живая форма и изменённость
230
268
 
231
269
  ```tsx
@@ -310,6 +348,12 @@ const Optional = createExtraForm({
310
348
 
311
349
  Поле добавлено, пока у него есть значение: в `defaultValues` — показано сразу, убранное — изменение формы.
312
350
 
351
+ ## 0.0.31
352
+
353
+ - `Condition` переименован в `OptionalCondition`: имя говорит, что скрытая ветка пропадает из значений.
354
+ - `NullableCondition`: скрытая ветка отдаёт `null` своим полям и контекстам, а не пропадает из значений; `null` у них
355
+ в `defaultValues` — отсутствие данных.
356
+
313
357
  ## 0.0.30
314
358
 
315
359
  - Поле, снова показанное условием, начинает со стартового значения (`defaultValues`), а не с умолчания компонента.
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ name: string;
3
+ canActivate: (value: any) => boolean;
4
+ children: React.ReactNode;
5
+ }
6
+ export declare const ConditionBranch: ({ canActivate, name, children }: Props) => import("react/jsx-runtime").JSX.Element | null;
7
+ export {};
package/dist/bundle.es.js CHANGED
@@ -1,208 +1,222 @@
1
- import { jsx as g, Fragment as N, jsxs as U } from "react/jsx-runtime";
2
- import { createContext as _, useState as B, useContext as T, useMemo as A, useEffect as m, useCallback as R, useRef as z } from "react";
3
- import O from "fast-deep-equal";
4
- const D = _({}), M = (n) => {
5
- const [, r] = B([]), e = T(D);
6
- if (!e)
1
+ import { jsx as b, Fragment as L, jsxs as _ } from "react/jsx-runtime";
2
+ import { createContext as z, useState as B, useContext as N, useMemo as $, useEffect as D, useCallback as m, useRef as G } from "react";
3
+ import P from "fast-deep-equal";
4
+ const w = z({}), M = (n) => {
5
+ const [, e] = B([]), r = N(w);
6
+ if (!r)
7
7
  throw new Error("useValue cannot be used outside Form context");
8
- const s = A(() => {
9
- const t = e.getForm(n);
8
+ const s = $(() => {
9
+ const t = r.getForm(n);
10
10
  if (!t)
11
11
  throw new Error(`form with name "${n}" doesnt exist in form`);
12
12
  return t;
13
- }, [e, n]);
14
- return m(() => {
15
- const t = e.subscribeToForm(n, () => {
16
- r([]);
13
+ }, [r, n]);
14
+ return D(() => {
15
+ const t = r.subscribeToForm(n, () => {
16
+ e([]);
17
17
  });
18
18
  return () => {
19
19
  t();
20
20
  };
21
21
  }, []), s.value;
22
- }, Y = (n) => {
23
- const r = T(D);
24
- if (!r)
22
+ }, k = (n) => {
23
+ const e = N(w);
24
+ if (!e)
25
25
  throw new Error("useSetValue cannot be used outside Form context");
26
- return (e) => {
27
- r.setValue(n, e);
26
+ return (r) => {
27
+ e.setValue(n, r);
28
28
  };
29
- }, Z = () => (n) => M(n), G = ({ canActivate: n, name: r, children: e }) => {
30
- const s = M(r);
31
- return n(s) ? /* @__PURE__ */ g(N, { children: e }) : null;
32
- }, H = ({ item: { Form: n }, name: r }) => {
33
- const [, e] = B([]), s = T(D), { unregistry: t } = A(() => s.registry(r, () => {
34
- e([]);
35
- }), []), u = R(
29
+ }, I = () => (n) => M(n), H = ({ canActivate: n, name: e, children: r }) => {
30
+ const s = M(e);
31
+ return n(s) ? /* @__PURE__ */ b(L, { children: r }) : null;
32
+ }, J = ({ item: { Form: n }, name: e }) => {
33
+ const [, r] = B([]), s = N(w), { unregistry: t } = $(() => s.registry(e, () => {
34
+ r([]);
35
+ }), []), u = m(
36
36
  (y) => {
37
37
  if (y && y.focus) {
38
- const v = s.getForm(r);
38
+ const v = s.getForm(e);
39
39
  v.focus = () => {
40
40
  y.focus();
41
41
  };
42
42
  }
43
43
  },
44
- [r]
44
+ [e]
45
45
  );
46
- m(() => () => {
46
+ D(() => () => {
47
47
  t();
48
48
  }, []);
49
- const { value: d, error: b } = s.getForm(r);
50
- return /* @__PURE__ */ g(
49
+ const { value: d, error: h } = s.getForm(e);
50
+ return /* @__PURE__ */ b(
51
51
  n,
52
52
  {
53
53
  field: {
54
54
  value: d,
55
55
  onChange: (y) => {
56
- s.onChange(r, y);
56
+ s.onChange(e, y);
57
57
  },
58
58
  onBlur: () => {
59
59
  },
60
60
  ref: u
61
61
  },
62
62
  isDirty: !1,
63
- error: b,
63
+ error: h,
64
64
  disabled: s.disabled
65
65
  }
66
66
  );
67
- }, J = ({ item: n, path: r }) => {
68
- const { getController: e, items: s } = n, t = T(D), u = A(() => {
69
- const l = {};
67
+ }, K = ({ item: n, path: e }) => {
68
+ const { getController: r, items: s } = n, t = N(w), u = $(() => {
69
+ const f = {};
70
70
  return s.forEach(({ name: i, getForm: F }) => {
71
- l[i] = F(i, () => j(i));
72
- }), l;
73
- }, []), d = R(() => {
74
- const l = [];
71
+ f[i] = F(i, () => j(i));
72
+ }), f;
73
+ }, []), d = m(() => {
74
+ const f = [];
75
75
  return s.forEach(({ name: i }) => {
76
- t.getForm([...r, i].join(".")).value !== void 0 && l.push(i);
77
- }), l;
78
- }, []), b = A(() => d(), []), [y, v] = B(b);
79
- m(() => {
80
- const { unregistry: l } = t.registryExtraForm(
81
- s.map(({ name: i }) => [...r, i].join(".")),
76
+ t.getForm([...e, i].join(".")).value !== void 0 && f.push(i);
77
+ }), f;
78
+ }, []), h = $(() => d(), []), [y, v] = B(h);
79
+ D(() => {
80
+ const { unregistry: f } = t.registryExtraForm(
81
+ s.map(({ name: i }) => [...e, i].join(".")),
82
82
  () => {
83
83
  v(d());
84
84
  }
85
85
  );
86
86
  return () => {
87
- l();
87
+ f();
88
88
  };
89
89
  }, []);
90
- const x = R(
91
- (l) => {
92
- u[l] && !y.includes(l) && v((i) => [...i, l]);
90
+ const x = m(
91
+ (f) => {
92
+ u[f] && !y.includes(f) && v((i) => [...i, f]);
93
93
  },
94
94
  [y]
95
- ), j = R((l) => {
96
- v((i) => i.filter((F) => F !== l));
95
+ ), j = m((f) => {
96
+ v((i) => i.filter((F) => F !== f));
97
97
  }, []);
98
- return /* @__PURE__ */ U(N, { children: [
99
- y.map((l) => {
100
- const i = u[l];
101
- return /* @__PURE__ */ g(p, { path: r, scheme: [i] }, `param-form--${l}`);
98
+ return /* @__PURE__ */ _(L, { children: [
99
+ y.map((f) => {
100
+ const i = u[f];
101
+ return /* @__PURE__ */ b(A, { path: e, scheme: [i] }, `param-form--${f}`);
102
102
  }),
103
- e(x, y)
103
+ r(x, y)
104
104
  ] });
105
- }, p = ({ scheme: n, path: r }) => /* @__PURE__ */ g(N, { children: n.map((e, s) => e.type === "layout" ? /* @__PURE__ */ g(e.Layout, { children: /* @__PURE__ */ g(p, { path: r, scheme: e.childs }) }, `layout-form--${s}-${r.length}`) : e.type === "context" ? /* @__PURE__ */ g(
106
- p,
105
+ }, A = ({ scheme: n, path: e }) => /* @__PURE__ */ b(L, { children: n.map((r, s) => r.type === "layout" ? /* @__PURE__ */ b(r.Layout, { children: /* @__PURE__ */ b(A, { path: e, scheme: r.childs }) }, `layout-form--${s}-${e.length}`) : r.type === "context" ? /* @__PURE__ */ b(
106
+ A,
107
107
  {
108
- path: [...r, e.context],
109
- scheme: e.childs
108
+ path: [...e, r.context],
109
+ scheme: r.childs
110
110
  },
111
- `context-form--${s}-${e.context}-${r.length}`
112
- ) : e.type === "condition" ? /* @__PURE__ */ g(
113
- G,
111
+ `context-form--${s}-${r.context}-${e.length}`
112
+ ) : r.type === "condition" ? /* @__PURE__ */ b(
113
+ H,
114
114
  {
115
- name: e.depended,
116
- canActivate: e.canActivate,
117
- children: /* @__PURE__ */ g(p, { path: r, scheme: e.childs })
115
+ name: r.depended,
116
+ canActivate: r.canActivate,
117
+ children: /* @__PURE__ */ b(A, { path: e, scheme: r.childs })
118
118
  },
119
- `condition--${s}-${e.depended}-${r.length}`
120
- ) : e.type === "extra" ? /* @__PURE__ */ g(J, { path: r, item: e }, `partial-item--${s}-${r.length}`) : e.type === "visability" ? e.hidden ? null : /* @__PURE__ */ g(p, { path: r, scheme: e.childs }, `visability--${s}-${r.length}`) : /* @__PURE__ */ g(
121
- H,
119
+ `condition--${s}-${r.depended}-${e.length}`
120
+ ) : r.type === "extra" ? /* @__PURE__ */ b(K, { path: e, item: r }, `partial-item--${s}-${e.length}`) : r.type === "visability" ? r.hidden ? null : /* @__PURE__ */ b(A, { path: e, scheme: r.childs }, `visability--${s}-${e.length}`) : /* @__PURE__ */ b(
121
+ J,
122
122
  {
123
- name: [...r, e.name].join("."),
124
- item: e
123
+ name: [...e, r.name].join("."),
124
+ item: r
125
125
  },
126
- `form-item--${s}-${e.name}-${r.length}`
127
- )) }), $ = (n, r, e, s) => {
126
+ `form-item--${s}-${r.name}-${e.length}`
127
+ )) }), Q = (n) => {
128
+ const e = {};
129
+ for (const r in n)
130
+ n[r] !== null && (e[r] = n[r]);
131
+ return e;
132
+ }, p = (n, e, r, s) => {
128
133
  n.forEach((t) => {
129
- if (t.type === "form" && s(t, [...r, t.name].join("."), e[t.name]), t.type === "context") {
130
- $(t.childs, [...r, t.context], e[t.context] ?? {}, s);
134
+ if (t.type === "form" && s(t, [...e, t.name].join("."), r[t.name]), t.type === "context") {
135
+ p(t.childs, [...e, t.context], r[t.context] ?? {}, s);
131
136
  return;
132
137
  }
133
- if (t.type === "layout" || t.type === "condition" || t.type === "visability") {
134
- $(t.childs, r, e, s);
138
+ if (t.type === "layout" || t.type === "visability") {
139
+ p(t.childs, e, r, s);
140
+ return;
141
+ }
142
+ if (t.type === "condition") {
143
+ p(t.childs, e, t.nullable ? Q(r) : r, s);
135
144
  return;
136
145
  }
137
146
  t.type === "extra" && t.items.forEach(({ getForm: u, name: d }) => {
138
- $([u(d, () => {
139
- })], r, e, s);
147
+ p([u(d, () => {
148
+ })], e, r, s);
140
149
  });
141
150
  });
142
- }, C = (n, r, e, s) => {
151
+ }, C = (n, e, r, s) => {
143
152
  n.forEach((t) => {
144
- if (t.type === "form" && s([...r, t.name].join(".")), t.type === "context") {
145
- C(t.childs, [...r, t.context], e, s);
153
+ if (t.type === "form" && s([...e, t.name].join(".")), t.type === "context") {
154
+ C(t.childs, [...e, t.context], r, s);
146
155
  return;
147
156
  }
148
157
  if (t.type === "layout") {
149
- C(t.childs, r, e, s);
158
+ C(t.childs, e, r, s);
150
159
  return;
151
160
  }
152
161
  if (t.type === "visability" && !t.hidden) {
153
- C(t.childs, r, e, s);
162
+ C(t.childs, e, r, s);
154
163
  return;
155
164
  }
156
- if (t.type === "condition" && t.canActivate(e[t.depended]?.value)) {
157
- C(t.childs, r, e, s);
165
+ if (t.type === "condition" && t.canActivate(r[t.depended]?.value)) {
166
+ C(t.childs, e, r, s);
158
167
  return;
159
168
  }
160
169
  t.type === "extra" && t.items.forEach(({ getForm: u, name: d }) => {
161
- e[[...r, d].join(".")]?.value !== void 0 && C([u(d, () => {
162
- })], r, e, s);
170
+ r[[...e, d].join(".")]?.value !== void 0 && C([u(d, () => {
171
+ })], e, r, s);
163
172
  });
164
173
  });
165
- }, S = ({ scheme: n, values: r, path: e, forms: s, shown: t }) => {
174
+ }, U = (n, e) => {
175
+ n.forEach((r) => {
176
+ r.type === "form" && (e[r.name] = null), r.type === "context" && (e[r.context] = null), (r.type === "layout" || r.type === "condition" || r.type === "visability") && U(r.childs, e);
177
+ });
178
+ }, S = ({ scheme: n, values: e, path: r, forms: s, shown: t }) => {
166
179
  n.forEach((u) => {
167
180
  if (u.type === "form") {
168
- const { value: d, startValue: b } = s[[...e, u.name].join(".")];
169
- d !== void 0 && (r[u.name] = d), d === void 0 && t && (r[u.name] = b);
181
+ const { value: d, startValue: h } = s[[...r, u.name].join(".")];
182
+ d !== void 0 && (e[u.name] = d), d === void 0 && t && (e[u.name] = h);
170
183
  }
171
184
  if (u.type === "context") {
172
- r[u.context] = {}, S({
185
+ e[u.context] = {}, S({
173
186
  scheme: u.childs,
174
- path: [...e, u.context],
175
- values: r[u.context],
187
+ path: [...r, u.context],
188
+ values: e[u.context],
176
189
  forms: s,
177
190
  shown: t
178
191
  });
179
192
  return;
180
193
  }
181
194
  if (u.type === "layout") {
182
- S({ scheme: u.childs, path: e, values: r, forms: s, shown: t });
195
+ S({ scheme: u.childs, path: r, values: e, forms: s, shown: t });
183
196
  return;
184
197
  }
185
198
  if (u.type === "visability") {
186
- S({ scheme: u.childs, path: e, values: r, forms: s, shown: t && !u.hidden });
199
+ S({ scheme: u.childs, path: r, values: e, forms: s, shown: t && !u.hidden });
187
200
  return;
188
201
  }
189
202
  if (u.type === "condition") {
190
203
  const d = s[u.depended]?.value;
191
204
  if (u.canActivate(d)) {
192
- S({ scheme: u.childs, path: e, values: r, forms: s, shown: t });
205
+ S({ scheme: u.childs, path: r, values: e, forms: s, shown: t });
193
206
  return;
194
207
  }
208
+ u.nullable && U(u.childs, e);
195
209
  }
196
- u.type === "extra" && u.items.forEach(({ getForm: d, name: b }) => {
197
- S({ scheme: [d(b, () => {
198
- })], path: e, values: r, forms: s, shown: !1 });
210
+ u.type === "extra" && u.items.forEach(({ getForm: d, name: h }) => {
211
+ S({ scheme: [d(h, () => {
212
+ })], path: r, values: e, forms: s, shown: !1 });
199
213
  });
200
214
  });
201
- }, L = (n, r) => {
202
- const e = {};
203
- return S({ scheme: n, path: [], values: e, forms: r, shown: !0 }), e;
204
- }, K = (n, r) => {
205
- const { onSubmit: e, onChange: s, onEqual: t, disabled: u, onDirty: d, onFormDirty: b, onChangeEvent: y, defaultValues: v } = r, x = { onSubmit: e }, j = { onChange: s }, l = {
215
+ }, q = (n, e) => {
216
+ const r = {};
217
+ return S({ scheme: n, path: [], values: r, forms: e, shown: !0 }), r;
218
+ }, W = (n, e) => {
219
+ const { onSubmit: r, onChange: s, onEqual: t, disabled: u, onDirty: d, onFormDirty: h, onChangeEvent: y, defaultValues: v } = e, x = { onSubmit: r }, j = { onChange: s }, f = {
206
220
  isActive: !1,
207
221
  isSubmitted: !1,
208
222
  dirtyCount: 0
@@ -210,7 +224,7 @@ const D = _({}), M = (n) => {
210
224
  subscribers: [],
211
225
  names: {}
212
226
  };
213
- $(n, [], v ?? {}, (o, a, c) => {
227
+ p(n, [], v ?? {}, (o, a, c) => {
214
228
  i[a] = {
215
229
  error: null,
216
230
  isDirty: !1,
@@ -226,11 +240,11 @@ const D = _({}), M = (n) => {
226
240
  validate: o.validate
227
241
  };
228
242
  });
229
- const q = (o, a) => {
230
- d?.({ name: o, isDirty: a }), a && l.dirtyCount === 0 && b?.(!0), !a && l.dirtyCount === 1 && b?.(!1), l.dirtyCount += a ? 1 : -1;
231
- }, P = () => {
243
+ const T = (o, a) => {
244
+ d?.({ name: o, isDirty: a }), a && f.dirtyCount === 0 && h?.(!0), !a && f.dirtyCount === 1 && h?.(!1), f.dirtyCount += a ? 1 : -1;
245
+ }, O = () => {
232
246
  for (const o in i)
233
- i[o].isDirty && (q(o, !1), i[o].isDirty = !1);
247
+ i[o].isDirty && (T(o, !1), i[o].isDirty = !1);
234
248
  };
235
249
  return {
236
250
  submitRef: x,
@@ -238,10 +252,10 @@ const D = _({}), M = (n) => {
238
252
  scheme: n,
239
253
  disabled: u,
240
254
  activate() {
241
- l.isActive = !0;
255
+ f.isActive = !0;
242
256
  },
243
257
  disactivate() {
244
- l.isActive = !1;
258
+ f.isActive = !1;
245
259
  },
246
260
  setError(o, a) {
247
261
  const c = this.getForm(o);
@@ -259,67 +273,67 @@ const D = _({}), M = (n) => {
259
273
  c && c.value !== a && this.onChange(o, a);
260
274
  },
261
275
  getValues() {
262
- return L(n, i);
276
+ return q(n, i);
263
277
  },
264
278
  async handleSubmit() {
265
279
  if (u)
266
280
  return;
267
- l.isSubmitted = !0;
281
+ f.isSubmitted = !0;
268
282
  let o = !1, a = !1;
269
283
  if (C(n, [], i, (c) => {
270
- const f = i[c];
271
- if (f.value !== void 0) {
272
- const h = f.validate(f.value);
273
- h && (a = !0, f.error = h, f.rerender(), !o && f.focus && (f.focus(), o = !0));
284
+ const l = i[c];
285
+ if (l.value !== void 0) {
286
+ const g = l.validate(l.value);
287
+ g && (a = !0, l.error = g, l.rerender(), !o && l.focus && (l.focus(), o = !0));
274
288
  }
275
289
  }), !a) {
276
- if (l.dirtyCount === 0 && t) {
290
+ if (f.dirtyCount === 0 && t) {
277
291
  t();
278
292
  return;
279
293
  }
280
294
  if (!x.onSubmit)
281
295
  return;
282
- const c = L(n, i);
296
+ const c = q(n, i);
283
297
  await x.onSubmit(c, {
284
- setError: (f, h) => {
285
- const V = this.getForm(f);
298
+ setError: (l, g) => {
299
+ const V = this.getForm(l);
286
300
  V.error = {
287
301
  error: !0,
288
- messages: [h.message]
302
+ messages: [g.message]
289
303
  }, V.rerender();
290
304
  }
291
- }).catch((f) => {
292
- console.log("[formkit] submit exception:", f);
305
+ }).catch((l) => {
306
+ console.log("[formkit] submit exception:", l);
293
307
  });
294
308
  }
295
309
  },
296
310
  reset(o, { asDirty: a }) {
297
- $(n, [], o, (c, f, h) => {
298
- if (h === void 0 && i[f].value === void 0)
311
+ p(n, [], o, (c, l, g) => {
312
+ if (g === void 0 && i[l].value === void 0)
299
313
  return;
300
- if (E.names[f] && h === void 0) {
301
- i[f].value = void 0;
314
+ if (E.names[l] && g === void 0) {
315
+ i[l].value = void 0;
302
316
  return;
303
317
  }
304
- const V = h ?? c.defaultValue;
305
- a || (i[f].startValue = V), i[f].value !== V && this.onChange(f, V);
306
- }), a || (P(), l.isSubmitted = !1), E.subscribers.forEach(({ visualizeEvalueatedForms: c }) => {
318
+ const V = g ?? c.defaultValue;
319
+ a || (i[l].startValue = V), i[l].value !== V && this.onChange(l, V);
320
+ }), a || (O(), f.isSubmitted = !1), E.subscribers.forEach(({ visualizeEvalueatedForms: c }) => {
307
321
  c();
308
322
  });
309
323
  },
310
324
  setAsDefault() {
311
- $(n, [], {}, (o, a) => {
325
+ p(n, [], {}, (o, a) => {
312
326
  i[a].startValue = i[a].value ?? i[a].defaultValue;
313
- }), P(), l.isSubmitted = !1;
327
+ }), O(), f.isSubmitted = !1;
314
328
  },
315
329
  registry(o, a) {
316
330
  return i[o].rerender = a, i[o].value === void 0 && (i[o].value = E.names[o] ? i[o].defaultValue : i[o].startValue), {
317
331
  unregistry() {
318
332
  if (i[o].rerender = () => {
319
- }, i[o].focus = void 0, l.isActive) {
333
+ }, i[o].focus = void 0, f.isActive) {
320
334
  i[o].value = void 0, i[o].error = null;
321
- const c = E.names[o] ? !O(i[o].startValue, i[o].defaultValue) : !1;
322
- i[o].isDirty !== c && q(o, c), i[o].isDirty = c;
335
+ const c = E.names[o] ? !P(i[o].startValue, i[o].defaultValue) : !1;
336
+ i[o].isDirty !== c && T(o, c), i[o].isDirty = c;
323
337
  }
324
338
  }
325
339
  };
@@ -328,9 +342,9 @@ const D = _({}), M = (n) => {
328
342
  return i[o];
329
343
  },
330
344
  subscribeToForm(o, a) {
331
- const c = { callback: a }, f = this.getForm(o);
332
- return f.subscribers.push(c), () => {
333
- f.subscribers = f.subscribers.filter((h) => h !== c);
345
+ const c = { callback: a }, l = this.getForm(o);
346
+ return l.subscribers.push(c), () => {
347
+ l.subscribers = l.subscribers.filter((g) => g !== c);
334
348
  };
335
349
  },
336
350
  subscribeToAny(o) {
@@ -343,32 +357,32 @@ const D = _({}), M = (n) => {
343
357
  },
344
358
  registryExtraForm(o, a) {
345
359
  const c = { visualizeEvalueatedForms: a };
346
- return o.forEach((f) => {
347
- E.names[f] = !0;
360
+ return o.forEach((l) => {
361
+ E.names[l] = !0;
348
362
  }), E.subscribers.push(c), {
349
363
  unregistry() {
350
- E.subscribers = E.subscribers.filter((f) => f !== c);
364
+ E.subscribers = E.subscribers.filter((l) => l !== c);
351
365
  }
352
366
  };
353
367
  },
354
368
  onChange(o, a) {
355
- const c = this.getForm(o), f = !O(a, c.startValue);
356
- c.isDirty !== f && q(o, f), c.isDirty = f, y?.({ name: o, value: a }), (c.error || l.isSubmitted) && (c.error = c.validate(a) || null);
357
- const h = c.value;
369
+ const c = this.getForm(o), l = !P(a, c.startValue);
370
+ c.isDirty !== l && T(o, l), c.isDirty = l, y?.({ name: o, value: a }), (c.error || f.isSubmitted) && (c.error = c.validate(a) || null);
371
+ const g = c.value;
358
372
  c.value = a, c.rerender(), c.subscribers.forEach(({ callback: V }) => {
359
- V(a, h);
373
+ V(a, g);
360
374
  }), F.forEach((V) => {
361
375
  V();
362
- }), j.onChange?.(L(n, i));
376
+ }), j.onChange?.(q(n, i));
363
377
  }
364
378
  };
365
- }, k = (n, r) => {
366
- const e = z(null);
367
- e.current === null && (e.current = K(n, r));
368
- const s = e.current;
369
- return m(() => {
370
- e.current && (e.current.submitRef.onSubmit = r.onSubmit, e.current.changeRef.onChange = r.onChange);
371
- }, [r.onSubmit, r.onChange]), {
379
+ }, rr = (n, e) => {
380
+ const r = G(null);
381
+ r.current === null && (r.current = W(n, e));
382
+ const s = r.current;
383
+ return D(() => {
384
+ r.current && (r.current.submitRef.onSubmit = e.onSubmit, r.current.changeRef.onChange = e.onChange);
385
+ }, [e.onSubmit, e.onChange]), {
372
386
  manager: s,
373
387
  useValue: (t) => M(t),
374
388
  reset: (t, u = {}) => {
@@ -398,85 +412,93 @@ const D = _({}), M = (n) => {
398
412
  // плоский список имён всех полей (dotted-пути; вложенные context раскрыты)
399
413
  getNames: () => s.getNames()
400
414
  };
401
- }, I = ({ manager: n }) => (A(() => {
415
+ }, er = ({ manager: n }) => ($(() => {
402
416
  n.activate();
403
- }, []), m(() => () => {
417
+ }, []), D(() => () => {
404
418
  n.disactivate();
405
- }, []), /* @__PURE__ */ g(D.Provider, { value: n, children: /* @__PURE__ */ g(p, { scheme: n.scheme, path: [] }) })), w = (n) => {
419
+ }, []), /* @__PURE__ */ b(w.Provider, { value: n, children: /* @__PURE__ */ b(A, { scheme: n.scheme, path: [] }) })), R = (n) => {
406
420
  try {
407
421
  n();
408
- } catch (r) {
409
- return r && typeof r == "string" ? {
422
+ } catch (e) {
423
+ return e && typeof e == "string" ? {
410
424
  error: !0,
411
- messages: [r]
412
- } : r instanceof Array && r.every((e) => e && typeof e == "string") ? {
425
+ messages: [e]
426
+ } : e instanceof Array && e.every((r) => r && typeof r == "string") ? {
413
427
  error: !0,
414
- messages: r
428
+ messages: e
415
429
  } : {
416
430
  error: !0
417
431
  };
418
432
  }
419
- }, rr = (n) => (r, e) => {
420
- const s = n.getRequireCheck(e), { $rules: t = {}, ...u } = e, { validate: d, required: b } = t;
433
+ }, tr = (n) => (e, r) => {
434
+ const s = n.getRequireCheck(r), { $rules: t = {}, ...u } = r, { validate: d, required: h } = t;
421
435
  return {
422
436
  type: "form",
423
- name: r,
437
+ name: e,
424
438
  defaultValue: n.defaultValue,
425
439
  Form: n.getForm(u),
426
440
  validate: (y) => {
427
- if (b) {
428
- const v = w(() => s(y));
441
+ if (h) {
442
+ const v = R(() => s(y));
429
443
  if (v)
430
444
  return v;
431
445
  if (d) {
432
- const x = w(() => d(y));
446
+ const x = R(() => d(y));
433
447
  if (x)
434
448
  return x;
435
449
  }
436
450
  return;
437
451
  }
438
- if (d && !w(() => s(y))) {
439
- const x = w(() => d(y));
452
+ if (d && !R(() => s(y))) {
453
+ const x = R(() => d(y));
440
454
  if (x)
441
455
  return x;
442
456
  }
443
457
  }
444
458
  };
445
- }, er = (n) => (r) => (...e) => ({
459
+ }, nr = (n) => (e) => (...r) => ({
446
460
  type: "layout",
447
- Layout: n(r),
448
- childs: e
449
- }), tr = ({
461
+ Layout: n(e),
462
+ childs: r
463
+ }), sr = ({
450
464
  getItems: n,
451
- getController: r
465
+ getController: e
452
466
  }) => ({
453
467
  type: "extra",
454
- items: n((e) => (s) => ({ type: "registry", name: e, getForm: s })),
455
- getController: r
456
- }), sr = (n) => (...r) => ({
468
+ items: n((r) => (s) => ({ type: "registry", name: r, getForm: s })),
469
+ getController: e
470
+ }), or = (n) => (...e) => ({
457
471
  type: "context",
458
472
  context: n,
473
+ childs: e
474
+ }), ir = (n, e) => (...r) => ({
475
+ type: "condition",
476
+ depended: n,
477
+ canActivate: e.canActivate,
478
+ nullable: !1,
459
479
  childs: r
460
- }), nr = (n, r) => (...e) => ({
480
+ }), ur = (n, e) => (...r) => ({
461
481
  type: "condition",
462
482
  depended: n,
463
- canActivate: r.canActivate,
464
- childs: e
465
- }), or = ({ hidden: n }) => (...r) => ({
483
+ canActivate: e.canActivate,
484
+ nullable: !0,
485
+ childs: r
486
+ }), cr = ({ hidden: n }) => (...e) => ({
466
487
  type: "visability",
467
488
  hidden: n ?? !1,
468
- childs: r
489
+ childs: e
469
490
  });
470
491
  export {
471
- nr as Condition,
472
- sr as Context,
473
- I as FormLayout,
474
- or as Visablility,
475
- tr as createExtraForm,
476
- rr as createForm,
477
- er as createLayout,
478
- Z as createUseValue,
479
- k as useForm,
480
- Y as useSetValue,
492
+ or as Context,
493
+ er as FormLayout,
494
+ ur as NullableCondition,
495
+ ir as OptionalCondition,
496
+ cr as Visablility,
497
+ sr as createExtraForm,
498
+ tr as createForm,
499
+ nr as createLayout,
500
+ I as createUseValue,
501
+ rr as useForm,
502
+ k as useSetValue,
481
503
  M as useValue
482
504
  };
@@ -1,8 +1,11 @@
1
1
  import { SchemeItems } from '../types';
2
- export declare const Context: <N extends string>(context: N) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Context<N, T>;
3
- export declare const Condition: (depended: string, props: {
2
+ interface ConditionProps {
4
3
  canActivate: (value: any) => boolean;
5
- }) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Condition<T>;
4
+ }
5
+ export declare const Context: <N extends string>(context: N) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Context<N, T>;
6
+ export declare const OptionalCondition: (depended: string, props: ConditionProps) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Condition<T, false>;
7
+ export declare const NullableCondition: (depended: string, props: ConditionProps) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Condition<T, true>;
6
8
  export declare const Visablility: ({ hidden }: {
7
9
  hidden?: boolean;
8
10
  }) => <T extends SchemeItems.All[]>(...childs: T) => SchemeItems.Visablility<T>;
11
+ export {};
@@ -1,10 +1,13 @@
1
1
  import { SchemeItems } from './types';
2
2
  import { Compute, UnionToIntersection } from '../utils/typescript';
3
+ type OrNull<T> = {
4
+ [K in keyof T]: T[K] | null;
5
+ };
3
6
  type ExtractValue<T> = T extends SchemeItems.Form<infer N, infer V> ? {
4
7
  [K in N]: V;
5
8
  } : T extends SchemeItems.Layout<infer C> ? ExtractValue<C[number]> : T extends SchemeItems.Context<infer N, infer C> ? {
6
9
  [K in N]: Compute<UnionToIntersection<ExtractValue<C[number]>>>;
7
- } : T extends SchemeItems.Condition<infer C> ? Partial<ExtractValue<C[number]>> : T extends SchemeItems.Visablility<infer C> ? Partial<ExtractValue<C[number]>> : T extends SchemeItems.Extra<string, infer C> ? Partial<ExtractValue<ReturnType<C[number]['getForm']>>> : never;
10
+ } : T extends SchemeItems.Condition<infer C, true> ? OrNull<ExtractValue<C[number]>> : T extends SchemeItems.Condition<infer C> ? Partial<ExtractValue<C[number]>> : T extends SchemeItems.Visablility<infer C> ? Partial<ExtractValue<C[number]>> : T extends SchemeItems.Extra<string, infer C> ? Partial<ExtractValue<ReturnType<C[number]['getForm']>>> : never;
8
11
  type ExtractValues<T> = Compute<UnionToIntersection<ExtractValue<T>>>;
9
12
  type ExtractFlatValue<T, A extends string | null> = T extends SchemeItems.Form<infer N, infer V> ? {
10
13
  [K in A extends null ? N : `${A}.${N}`]: V;
@@ -33,10 +33,11 @@ export declare namespace SchemeItems {
33
33
  name: N;
34
34
  getForm: <Q extends N>(name: Q, remove: () => void) => T;
35
35
  }
36
- interface Condition<T extends All[] = All[]> {
36
+ interface Condition<T extends All[] = All[], Nullable extends boolean = boolean> {
37
37
  type: 'condition';
38
38
  depended: string;
39
39
  canActivate: (value: any) => boolean;
40
+ nullable: Nullable;
40
41
  childs: T;
41
42
  }
42
43
  interface Visablility<T extends All[] = All[]> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@companix/formkit",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "module": "./dist/bundle.es.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",
@@ -1,7 +0,0 @@
1
- interface Props {
2
- name: string;
3
- canActivate: (value: any) => boolean;
4
- children: React.ReactNode;
5
- }
6
- export declare const Condition: ({ canActivate, name, children }: Props) => import("react/jsx-runtime").JSX.Element | null;
7
- export {};