@companix/formkit 0.0.28 → 0.0.30
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 +300 -38
- package/dist/bundle.es.js +280 -243
- package/dist/index.d.ts +1 -1
- package/dist/manager/manager.d.ts +4 -1
- package/dist/manager/read-scheme.d.ts +4 -1
- package/dist/useForm.d.ts +2 -1
- package/dist/useValue.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,58 +1,320 @@
|
|
|
1
|
-
|
|
1
|
+
# @companix/formkit
|
|
2
|
+
|
|
3
|
+
Формы на React одной декларативной схемой. Поля, раскладка, условия и проверка описываются деревом из обычных вызовов
|
|
4
|
+
функций, а значения формы TypeScript выводит из самой схемы — без ручных интерфейсов, `useState` на каждое поле и
|
|
5
|
+
`register` в разметке.
|
|
2
6
|
|
|
3
7
|
```tsx
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const scheme = [
|
|
9
|
+
Label('Имя')(TextForm('name', { placeholder: 'Иван', $rules: { required: true } })),
|
|
10
|
+
CheckboxForm('hasCompany', { title: 'Представляю компанию' }),
|
|
11
|
+
Condition('hasCompany', { canActivate: (checked: boolean) => checked })(
|
|
12
|
+
Context('company')(Label('Компания')(TextForm('name', { placeholder: 'ООО «Ромашка»' })))
|
|
13
|
+
)
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
// onSubmit получит { name: string; hasCompany: boolean; company?: { name: string } }
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`TextForm`, `CheckboxForm` и `Label` здесь — свои поле и раскладка проекта: как их завести, показано ниже.
|
|
20
|
+
|
|
21
|
+
## Почему formkit
|
|
22
|
+
|
|
23
|
+
- **Форма — данные, а не разметка.** Схема — массив, который собирают функциями: общий блок полей пишется один раз и
|
|
24
|
+
вставляется в любую форму, вариант формы — другой набор элементов, а не ветвление в JSX.
|
|
25
|
+
- **Типы из схемы.** `onSubmit`, `onChange`, `defaultValues`, `setValue` и `useValue` знают имена и типы полей,
|
|
26
|
+
вложенные контексты и необязательность полей под условием.
|
|
27
|
+
- **Поле пишется один раз.** `createForm` превращает любой компонент ввода в поле: умолчание, «что считать пустым» и
|
|
28
|
+
отрисовка ошибки живут в нём, а не в каждой форме.
|
|
29
|
+
- **Условия и вложенность из коробки.** `Condition` показывает поля по значению другого поля, `Context` складывает их
|
|
30
|
+
в объект; скрытое поле не попадает ни в значения, ни в проверку.
|
|
31
|
+
- **Состояние вне React.** Значения держит менеджер формы: правка поля перерисовывает это поле и тех, кто на него
|
|
32
|
+
подписан, а не всю форму и не экран вокруг неё.
|
|
33
|
+
- **Изменённость.** Форма знает, что её правили, сообщает об этом и при отправке без изменений вызывает `onEqual`
|
|
34
|
+
вместо запроса.
|
|
35
|
+
|
|
36
|
+
## Установка
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
npm i @companix/formkit
|
|
10
40
|
```
|
|
11
41
|
|
|
12
|
-
|
|
42
|
+
Нужен React 18.
|
|
43
|
+
|
|
44
|
+
## Форма за минуту
|
|
13
45
|
|
|
14
46
|
```tsx
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
47
|
+
import { useMemo } from 'react'
|
|
48
|
+
import { createForm, createLayout, useForm, FormLayout } from '@companix/formkit'
|
|
49
|
+
|
|
50
|
+
// поле: умолчание, проверка обязательности и компонент
|
|
51
|
+
const TextForm = createForm<string, { placeholder: string }>({
|
|
52
|
+
defaultValue: '',
|
|
53
|
+
getRequireCheck: () => (value) => {
|
|
54
|
+
if (value.trim() === '') {
|
|
55
|
+
throw ''
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
getForm: ({ placeholder }) => {
|
|
59
|
+
return ({ field, error, disabled }) => {
|
|
60
|
+
return (
|
|
61
|
+
<div className="field">
|
|
62
|
+
<input
|
|
63
|
+
ref={field.ref}
|
|
64
|
+
value={field.value}
|
|
65
|
+
placeholder={placeholder}
|
|
66
|
+
disabled={disabled}
|
|
67
|
+
onChange={(e) => field.onChange(e.target.value)}
|
|
68
|
+
/>
|
|
69
|
+
{error?.messages?.map((message) => (
|
|
70
|
+
<p key={message}>{message}</p>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
18
75
|
}
|
|
19
76
|
})
|
|
20
77
|
|
|
21
|
-
|
|
78
|
+
// раскладка: подпись над полем
|
|
79
|
+
const Label = createLayout((text: string) => {
|
|
22
80
|
return ({ children }) => {
|
|
23
|
-
return
|
|
81
|
+
return (
|
|
82
|
+
<label className="label">
|
|
83
|
+
<span>{text}</span>
|
|
84
|
+
{children}
|
|
85
|
+
</label>
|
|
86
|
+
)
|
|
24
87
|
}
|
|
25
88
|
})
|
|
26
89
|
|
|
27
|
-
export const
|
|
28
|
-
|
|
29
|
-
return
|
|
90
|
+
export const ProfileForm = () => {
|
|
91
|
+
const scheme = useMemo(() => {
|
|
92
|
+
return [
|
|
93
|
+
Label('Имя')(TextForm('name', { placeholder: 'Иван', $rules: { required: true } })),
|
|
94
|
+
Label('Город')(TextForm('city', { placeholder: 'Москва' }))
|
|
95
|
+
]
|
|
96
|
+
}, [])
|
|
97
|
+
|
|
98
|
+
const form = useForm(scheme, {
|
|
99
|
+
defaultValues: { city: 'Москва' },
|
|
100
|
+
onSubmit: async (values) => {
|
|
101
|
+
await api.saveProfile(values) // values: { name: string; city: string }
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<>
|
|
107
|
+
<FormLayout manager={form.manager} />
|
|
108
|
+
<button onClick={form.handleSubmit}>Сохранить</button>
|
|
109
|
+
</>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Менеджер формы создаётся один раз: схему и `defaultValues` `useForm` читает при первом рендере, поэтому схему держат в
|
|
115
|
+
`useMemo`. `FormLayout` рисует схему и может стоять где угодно — в окне, на странице, в шаге мастера.
|
|
116
|
+
|
|
117
|
+
## Поле — `createForm`
|
|
118
|
+
|
|
119
|
+
Поле — это компонент ввода плюс три ответа: какое у него значение по умолчанию, что для него значит «пусто» и как его
|
|
120
|
+
нарисовать по параметрам из схемы.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
const SelectForm = <T,>(defaultValue: T | null) => {
|
|
124
|
+
return createForm<T | null, { options: { value: T; title: string }[] }>({
|
|
125
|
+
defaultValue,
|
|
126
|
+
getRequireCheck: () => (value) => {
|
|
127
|
+
if (value === null) {
|
|
128
|
+
throw ''
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
getForm: ({ options }) => {
|
|
132
|
+
return ({ field, error }) => (
|
|
133
|
+
<Select options={options} value={field.value} onChange={field.onChange} error={error} />
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
SelectForm<'day' | 'night'>('day')('mode', { options: MODES })
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Компонент получает `field` (`value`, `onChange`, `ref` для фокуса на ошибке), `error` и `disabled` формы. Умолчание,
|
|
143
|
+
которое зависит от места, задают фабрикой, как у `SelectForm` выше: `NumberInputForm(1)('count', …)`.
|
|
144
|
+
|
|
145
|
+
## Раскладка — `createLayout`
|
|
146
|
+
|
|
147
|
+
Раскладка оборачивает поля разметкой. Параметр раскладки — один аргумент; раскладку без параметров вызывают сразу.
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
const Card = createLayout(({ title, hint }: { title: string; hint?: string }) => {
|
|
151
|
+
return ({ children }) => (
|
|
152
|
+
<section className="card">
|
|
153
|
+
<h3>{title}</h3>
|
|
154
|
+
{hint && <p>{hint}</p>}
|
|
155
|
+
{children}
|
|
156
|
+
</section>
|
|
157
|
+
)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const Double = createLayout(() => {
|
|
161
|
+
return ({ children }) => <div className="double">{children}</div>
|
|
162
|
+
})()
|
|
163
|
+
|
|
164
|
+
Card({ title: 'Контакты', hint: 'Видят только менеджеры' })(
|
|
165
|
+
Double(TextForm('phone', { placeholder: '+7' }), TextForm('email', { placeholder: 'mail@site.ru' }))
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Схема
|
|
170
|
+
|
|
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(…)` | поля, которые пользователь добавляет и убирает сам | поля необязательны |
|
|
179
|
+
|
|
180
|
+
Значения `onSubmit` и `onChange` выводятся из схемы сами, тип `defaultValues` схемы — `GetDefaultValues<typeof scheme>`.
|
|
181
|
+
|
|
182
|
+
## Проверка
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
TextForm('inn', {
|
|
186
|
+
placeholder: '12 цифр',
|
|
187
|
+
$rules: {
|
|
188
|
+
required: true,
|
|
189
|
+
validate: (value) => {
|
|
190
|
+
if (!/^\d{12}$/.test(value)) {
|
|
191
|
+
throw 'ИНН — 12 цифр'
|
|
192
|
+
}
|
|
193
|
+
}
|
|
30
194
|
}
|
|
31
195
|
})
|
|
32
196
|
```
|
|
33
197
|
|
|
34
|
-
|
|
198
|
+
- `required` проверяет поле его же `getRequireCheck`; `validate` — после него. Без `required` `validate` работает,
|
|
199
|
+
только если поле не пустое.
|
|
200
|
+
- Проверка бросает строку: `throw ''` подсвечивает поле, `throw 'текст'` — с сообщением, массив строк — несколько
|
|
201
|
+
сообщений. Ошибку рисует компонент поля из `error.messages`.
|
|
202
|
+
- `handleSubmit` проверяет поля, которые форма показывает, и ставит фокус на первое ошибочное. Поле скрытого условия
|
|
203
|
+
отправку не держит. После первой попытки поля проверяются на каждой правке.
|
|
204
|
+
- Ошибку от сервера ставит `setError` из второго аргумента `onSubmit`: `setError('inn', { message: 'ИНН занят' })`.
|
|
35
205
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
206
|
+
## Значения, умолчания и условия
|
|
207
|
+
|
|
208
|
+
У поля два источника начального значения: умолчание компонента (`defaultValue` из `createForm`) и `defaultValues`
|
|
209
|
+
формы. Стартовое значение — `defaultValues`, а без них — умолчание компонента. От стартового значения считается
|
|
210
|
+
изменённость, и с него поле начинает:
|
|
211
|
+
|
|
212
|
+
- при первом показе;
|
|
213
|
+
- когда условие снова показывает поле: скрытое поле теряет значение и ошибку, вернувшееся — начинает заново со
|
|
214
|
+
стартового, а не с того, что ввели до скрытия.
|
|
215
|
+
|
|
216
|
+
Значения формы — `onChange`, `getValues()` и отправка — это то, что форма показывает. Поля скрытых условий в них не
|
|
217
|
+
входят, а поле, которое изменение только что открыло, входит сразу, ещё до монтирования, со стартовым значением.
|
|
218
|
+
|
|
219
|
+
Отсюда простое правило: `defaultValues` — только данные. Где данных нет, передавайте `undefined`, и поле возьмёт своё
|
|
220
|
+
умолчание; повторять умолчание поля в `defaultValues` не нужно.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
defaultValues: {
|
|
224
|
+
hasEscorts: escorts !== null,
|
|
225
|
+
escorts: escorts ?? undefined // нет данных — поля начнут со своих умолчаний
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Живая форма и изменённость
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
const form = useForm(scheme, {
|
|
233
|
+
defaultValues,
|
|
234
|
+
// значения после каждой правки — расчёт и подсказки поверх полей, без кнопки отправки
|
|
235
|
+
onChange: (values) => setDraft(toDraft(values)),
|
|
236
|
+
// форма изменена или снова стартовая
|
|
237
|
+
onFormDirty: (isDirty) => setDirty(isDirty),
|
|
238
|
+
// отправили без изменений
|
|
239
|
+
onEqual: () => close()
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- `onDirty` сообщает о каждом поле, `onFormDirty` — о форме целиком: первое изменение и снятие последнего.
|
|
244
|
+
- `setAsDefault()` делает текущие значения стартовыми — после успешного сохранения.
|
|
245
|
+
- `reset(values)` ставит новые значения и делает их стартовыми; поле, которого нет в `values`, получает умолчание
|
|
246
|
+
компонента. `reset(values, { asDirty: true })` оставляет новые значения изменением.
|
|
247
|
+
- `setAsDefault()` и `reset(values)` сообщают «чисто» через `onDirty` и `onFormDirty`.
|
|
248
|
+
|
|
249
|
+
## Управление формой
|
|
250
|
+
|
|
251
|
+
`useForm` возвращает:
|
|
252
|
+
|
|
253
|
+
| Метод | Что делает |
|
|
254
|
+
| ----------------------------- | ---------------------------------------------------------------------- |
|
|
255
|
+
| `manager` | менеджер для `FormLayout` |
|
|
256
|
+
| `handleSubmit()` | проверка показанных полей и `onSubmit` (или `onEqual`) |
|
|
257
|
+
| `getValues()` | значения формы — то, что она показывает |
|
|
258
|
+
| `getValue(name)` | значение поля по полному пути (`company.name`) |
|
|
259
|
+
| `setValue(name, value)` | запись поля, как ввод пользователя |
|
|
260
|
+
| `reset(values, options?)` | новые значения, по умолчанию — стартовые |
|
|
261
|
+
| `setAsDefault()` | текущие значения — стартовые |
|
|
262
|
+
| `setError(name, { message })` | ошибка поля |
|
|
263
|
+
| `setFocus(name)` | фокус на поле |
|
|
264
|
+
| `subscribe(name, callback)` | подписка на поле; возвращает отписку |
|
|
265
|
+
| `subscribeAny(callback)` | подписка на любую правку; возвращает отписку |
|
|
266
|
+
| `getNames()` | полные пути всех полей схемы |
|
|
267
|
+
| `useValue(name)` | хук внутри `FormLayout`: значение поля с перерисовкой и типом из схемы |
|
|
268
|
+
|
|
269
|
+
## Внутри схемы: `useValue` и `useSetValue`
|
|
270
|
+
|
|
271
|
+
Компоненты раскладок и поля читают и пишут соседние поля по полному пути. Хуки берут форму из контекста, поэтому
|
|
272
|
+
работают внутри `FormLayout`:
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
// подсказка, которая зависит от выбранной причины
|
|
276
|
+
const ReasonHint = createLayout(() => {
|
|
277
|
+
return () => {
|
|
278
|
+
const reason = useValue<Reason | null>('reason')
|
|
279
|
+
|
|
280
|
+
return (
|
|
281
|
+
<p className="hint">
|
|
282
|
+
{reason === 'scan' ? 'Переснимут только отмеченные' : 'Анкета вернётся на шаг'}
|
|
283
|
+
</p>
|
|
55
284
|
)
|
|
56
|
-
|
|
57
|
-
|
|
285
|
+
}
|
|
286
|
+
})()
|
|
287
|
+
|
|
288
|
+
// подстановка из списка в поле контакта
|
|
289
|
+
const ManagerPick = ({ managers }: { managers: Manager[] }) => {
|
|
290
|
+
const setName = useSetValue<string>('contact.name')
|
|
291
|
+
|
|
292
|
+
return <Menu items={managers} onSelect={(manager) => setName(manager.name)} />
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Типизированный `useValue` для схемы — `createUseValue<typeof scheme>()`.
|
|
297
|
+
|
|
298
|
+
## Поля, которые добавляет пользователь
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
// Removable — своя раскладка с кнопкой удаления, AddMenu — меню ещё не добавленных полей
|
|
302
|
+
const Optional = createExtraForm({
|
|
303
|
+
getItems: (registry) => [
|
|
304
|
+
registry('phone')((name, remove) => Removable(remove)(TextForm(name, { placeholder: 'Телефон' }))),
|
|
305
|
+
registry('email')((name, remove) => Removable(remove)(TextForm(name, { placeholder: 'Почта' })))
|
|
306
|
+
],
|
|
307
|
+
getController: (append, visible) => <AddMenu hidden={visible} onSelect={append} />
|
|
308
|
+
})
|
|
58
309
|
```
|
|
310
|
+
|
|
311
|
+
Поле добавлено, пока у него есть значение: в `defaultValues` — показано сразу, убранное — изменение формы.
|
|
312
|
+
|
|
313
|
+
## 0.0.30
|
|
314
|
+
|
|
315
|
+
- Поле, снова показанное условием, начинает со стартового значения (`defaultValues`), а не с умолчания компонента.
|
|
316
|
+
- `onChange`, `getValues()` и отправка включают поля, которые изменение только что показало, — со стартовым значением,
|
|
317
|
+
до монтирования.
|
|
318
|
+
- `handleSubmit` проверяет только показанные поля: скрытое поле отправку не держит. Ошибка скрытого поля сбрасывается.
|
|
319
|
+
- Скрытое условием поле не считается изменённым — изменение несёт поле условия.
|
|
320
|
+
- `setAsDefault()` и `reset()` сообщают «чисто» через `onDirty` и `onFormDirty`.
|
package/dist/bundle.es.js
CHANGED
|
@@ -1,342 +1,378 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { createContext as
|
|
3
|
-
import
|
|
4
|
-
const
|
|
5
|
-
const [, r] =
|
|
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
6
|
if (!e)
|
|
7
7
|
throw new Error("useValue cannot be used outside Form context");
|
|
8
|
-
const s =
|
|
9
|
-
const t = e.getForm(
|
|
8
|
+
const s = A(() => {
|
|
9
|
+
const t = e.getForm(n);
|
|
10
10
|
if (!t)
|
|
11
|
-
throw new Error(`form with name "${
|
|
11
|
+
throw new Error(`form with name "${n}" doesnt exist in form`);
|
|
12
12
|
return t;
|
|
13
|
-
}, [e,
|
|
14
|
-
return
|
|
15
|
-
const t = e.subscribeToForm(
|
|
13
|
+
}, [e, n]);
|
|
14
|
+
return m(() => {
|
|
15
|
+
const t = e.subscribeToForm(n, () => {
|
|
16
16
|
r([]);
|
|
17
17
|
});
|
|
18
18
|
return () => {
|
|
19
19
|
t();
|
|
20
20
|
};
|
|
21
21
|
}, []), s.value;
|
|
22
|
-
},
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
}, Y = (n) => {
|
|
23
|
+
const r = T(D);
|
|
24
|
+
if (!r)
|
|
25
|
+
throw new Error("useSetValue cannot be used outside Form context");
|
|
26
|
+
return (e) => {
|
|
27
|
+
r.setValue(n, e);
|
|
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, () => {
|
|
27
34
|
e([]);
|
|
28
|
-
}), []),
|
|
29
|
-
(
|
|
30
|
-
if (
|
|
35
|
+
}), []), u = R(
|
|
36
|
+
(y) => {
|
|
37
|
+
if (y && y.focus) {
|
|
31
38
|
const v = s.getForm(r);
|
|
32
39
|
v.focus = () => {
|
|
33
|
-
|
|
40
|
+
y.focus();
|
|
34
41
|
};
|
|
35
42
|
}
|
|
36
43
|
},
|
|
37
44
|
[r]
|
|
38
45
|
);
|
|
39
|
-
|
|
46
|
+
m(() => () => {
|
|
40
47
|
t();
|
|
41
48
|
}, []);
|
|
42
|
-
const { value:
|
|
43
|
-
return /* @__PURE__ */
|
|
44
|
-
|
|
49
|
+
const { value: d, error: b } = s.getForm(r);
|
|
50
|
+
return /* @__PURE__ */ g(
|
|
51
|
+
n,
|
|
45
52
|
{
|
|
46
53
|
field: {
|
|
47
|
-
value:
|
|
48
|
-
onChange: (
|
|
49
|
-
s.onChange(r,
|
|
54
|
+
value: d,
|
|
55
|
+
onChange: (y) => {
|
|
56
|
+
s.onChange(r, y);
|
|
50
57
|
},
|
|
51
58
|
onBlur: () => {
|
|
52
59
|
},
|
|
53
|
-
ref:
|
|
60
|
+
ref: u
|
|
54
61
|
},
|
|
55
62
|
isDirty: !1,
|
|
56
|
-
error:
|
|
63
|
+
error: b,
|
|
57
64
|
disabled: s.disabled
|
|
58
65
|
}
|
|
59
66
|
);
|
|
60
|
-
},
|
|
61
|
-
const { getController: e, items: s } =
|
|
62
|
-
const
|
|
63
|
-
return s.forEach(({ name:
|
|
64
|
-
|
|
65
|
-
}),
|
|
66
|
-
}, []),
|
|
67
|
-
const
|
|
68
|
-
return s.forEach(({ name:
|
|
69
|
-
t.getForm([...r,
|
|
70
|
-
}),
|
|
71
|
-
}, []),
|
|
72
|
-
|
|
73
|
-
const { unregistry:
|
|
74
|
-
s.map(({ name:
|
|
67
|
+
}, J = ({ item: n, path: r }) => {
|
|
68
|
+
const { getController: e, items: s } = n, t = T(D), u = A(() => {
|
|
69
|
+
const l = {};
|
|
70
|
+
return s.forEach(({ name: i, getForm: F }) => {
|
|
71
|
+
l[i] = F(i, () => j(i));
|
|
72
|
+
}), l;
|
|
73
|
+
}, []), d = R(() => {
|
|
74
|
+
const l = [];
|
|
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(".")),
|
|
75
82
|
() => {
|
|
76
|
-
v(
|
|
83
|
+
v(d());
|
|
77
84
|
}
|
|
78
85
|
);
|
|
79
86
|
return () => {
|
|
80
|
-
|
|
87
|
+
l();
|
|
81
88
|
};
|
|
82
89
|
}, []);
|
|
83
|
-
const
|
|
84
|
-
(
|
|
85
|
-
l
|
|
90
|
+
const x = R(
|
|
91
|
+
(l) => {
|
|
92
|
+
u[l] && !y.includes(l) && v((i) => [...i, l]);
|
|
86
93
|
},
|
|
87
|
-
[
|
|
88
|
-
),
|
|
89
|
-
v((
|
|
94
|
+
[y]
|
|
95
|
+
), j = R((l) => {
|
|
96
|
+
v((i) => i.filter((F) => F !== l));
|
|
90
97
|
}, []);
|
|
91
|
-
return /* @__PURE__ */
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
return /* @__PURE__ */
|
|
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}`);
|
|
95
102
|
}),
|
|
96
|
-
e(
|
|
103
|
+
e(x, y)
|
|
97
104
|
] });
|
|
98
|
-
}, p = ({ scheme:
|
|
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(
|
|
99
106
|
p,
|
|
100
107
|
{
|
|
101
108
|
path: [...r, e.context],
|
|
102
109
|
scheme: e.childs
|
|
103
110
|
},
|
|
104
111
|
`context-form--${s}-${e.context}-${r.length}`
|
|
105
|
-
) : e.type === "condition" ? /* @__PURE__ */
|
|
106
|
-
|
|
112
|
+
) : e.type === "condition" ? /* @__PURE__ */ g(
|
|
113
|
+
G,
|
|
107
114
|
{
|
|
108
115
|
name: e.depended,
|
|
109
116
|
canActivate: e.canActivate,
|
|
110
|
-
children: /* @__PURE__ */
|
|
117
|
+
children: /* @__PURE__ */ g(p, { path: r, scheme: e.childs })
|
|
111
118
|
},
|
|
112
119
|
`condition--${s}-${e.depended}-${r.length}`
|
|
113
|
-
) : e.type === "extra" ? /* @__PURE__ */
|
|
114
|
-
|
|
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,
|
|
115
122
|
{
|
|
116
123
|
name: [...r, e.name].join("."),
|
|
117
124
|
item: e
|
|
118
125
|
},
|
|
119
126
|
`form-item--${s}-${e.name}-${r.length}`
|
|
120
|
-
)) }),
|
|
121
|
-
|
|
127
|
+
)) }), $ = (n, r, e, s) => {
|
|
128
|
+
n.forEach((t) => {
|
|
122
129
|
if (t.type === "form" && s(t, [...r, t.name].join("."), e[t.name]), t.type === "context") {
|
|
123
|
-
|
|
130
|
+
$(t.childs, [...r, t.context], e[t.context] ?? {}, s);
|
|
124
131
|
return;
|
|
125
132
|
}
|
|
126
133
|
if (t.type === "layout" || t.type === "condition" || t.type === "visability") {
|
|
134
|
+
$(t.childs, r, e, s);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
t.type === "extra" && t.items.forEach(({ getForm: u, name: d }) => {
|
|
138
|
+
$([u(d, () => {
|
|
139
|
+
})], r, e, s);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}, C = (n, r, e, s) => {
|
|
143
|
+
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);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (t.type === "layout") {
|
|
127
149
|
C(t.childs, r, e, s);
|
|
128
150
|
return;
|
|
129
151
|
}
|
|
130
|
-
t.type === "
|
|
131
|
-
C(
|
|
152
|
+
if (t.type === "visability" && !t.hidden) {
|
|
153
|
+
C(t.childs, r, e, s);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (t.type === "condition" && t.canActivate(e[t.depended]?.value)) {
|
|
157
|
+
C(t.childs, r, e, s);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
t.type === "extra" && t.items.forEach(({ getForm: u, name: d }) => {
|
|
161
|
+
e[[...r, d].join(".")]?.value !== void 0 && C([u(d, () => {
|
|
132
162
|
})], r, e, s);
|
|
133
163
|
});
|
|
134
164
|
});
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
const
|
|
139
|
-
|
|
165
|
+
}, S = ({ scheme: n, values: r, path: e, forms: s, shown: t }) => {
|
|
166
|
+
n.forEach((u) => {
|
|
167
|
+
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);
|
|
140
170
|
}
|
|
141
|
-
if (
|
|
142
|
-
r[
|
|
143
|
-
scheme:
|
|
144
|
-
path: [...e,
|
|
145
|
-
values: r[
|
|
146
|
-
forms: s
|
|
171
|
+
if (u.type === "context") {
|
|
172
|
+
r[u.context] = {}, S({
|
|
173
|
+
scheme: u.childs,
|
|
174
|
+
path: [...e, u.context],
|
|
175
|
+
values: r[u.context],
|
|
176
|
+
forms: s,
|
|
177
|
+
shown: t
|
|
147
178
|
});
|
|
148
179
|
return;
|
|
149
180
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
181
|
+
if (u.type === "layout") {
|
|
182
|
+
S({ scheme: u.childs, path: e, values: r, forms: s, shown: t });
|
|
152
183
|
return;
|
|
153
184
|
}
|
|
154
|
-
if (
|
|
155
|
-
|
|
185
|
+
if (u.type === "visability") {
|
|
186
|
+
S({ scheme: u.childs, path: e, values: r, forms: s, shown: t && !u.hidden });
|
|
156
187
|
return;
|
|
157
188
|
}
|
|
158
|
-
if (
|
|
159
|
-
const
|
|
160
|
-
if (
|
|
161
|
-
|
|
189
|
+
if (u.type === "condition") {
|
|
190
|
+
const d = s[u.depended]?.value;
|
|
191
|
+
if (u.canActivate(d)) {
|
|
192
|
+
S({ scheme: u.childs, path: e, values: r, forms: s, shown: t });
|
|
162
193
|
return;
|
|
163
194
|
}
|
|
164
195
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
})], path: e, values: r, forms: s });
|
|
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 });
|
|
168
199
|
});
|
|
169
200
|
});
|
|
170
|
-
},
|
|
201
|
+
}, L = (n, r) => {
|
|
171
202
|
const e = {};
|
|
172
|
-
return
|
|
173
|
-
},
|
|
174
|
-
const { onSubmit: 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 = {
|
|
175
206
|
isActive: !1,
|
|
176
207
|
isSubmitted: !1,
|
|
177
208
|
dirtyCount: 0
|
|
178
|
-
},
|
|
209
|
+
}, i = {}, F = /* @__PURE__ */ new Set(), E = {
|
|
179
210
|
subscribers: [],
|
|
180
211
|
names: {}
|
|
181
212
|
};
|
|
182
|
-
|
|
183
|
-
a
|
|
213
|
+
$(n, [], v ?? {}, (o, a, c) => {
|
|
214
|
+
i[a] = {
|
|
184
215
|
error: null,
|
|
185
216
|
isDirty: !1,
|
|
186
|
-
value:
|
|
187
|
-
// текущее (динамическое) состояние поля. Значение равно переданному дефолтному, либо: определяется как
|
|
188
|
-
startValue:
|
|
189
|
-
// начальное (стартовое) значение (равно переданному дефолтному, либо значению формы по умолчанию).
|
|
190
|
-
defaultValue:
|
|
217
|
+
value: c,
|
|
218
|
+
// текущее (динамическое) состояние поля. Значение равно переданному дефолтному, либо: определяется как стартовое значение в момент монтирования поля, а до этого - undefined. Поле, которое скрыло условие, значения не имеет.
|
|
219
|
+
startValue: c ?? o.defaultValue,
|
|
220
|
+
// начальное (стартовое) значение (равно переданному дефолтному, либо значению формы по умолчанию). С него начинает поле при монтировании, в том числе снова показанное условием; исходя из сравнения текущего значения со стартовым, можно понять, модифицированно ли поле
|
|
221
|
+
defaultValue: o.defaultValue,
|
|
191
222
|
// дефолтное значение компонента формы
|
|
192
223
|
rerender: () => {
|
|
193
224
|
},
|
|
194
225
|
subscribers: [],
|
|
195
|
-
validate:
|
|
226
|
+
validate: o.validate
|
|
196
227
|
};
|
|
197
228
|
});
|
|
198
|
-
const
|
|
199
|
-
|
|
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 = () => {
|
|
232
|
+
for (const o in i)
|
|
233
|
+
i[o].isDirty && (q(o, !1), i[o].isDirty = !1);
|
|
200
234
|
};
|
|
201
235
|
return {
|
|
202
|
-
submitRef:
|
|
203
|
-
|
|
204
|
-
|
|
236
|
+
submitRef: x,
|
|
237
|
+
changeRef: j,
|
|
238
|
+
scheme: n,
|
|
239
|
+
disabled: u,
|
|
205
240
|
activate() {
|
|
206
|
-
|
|
241
|
+
l.isActive = !0;
|
|
207
242
|
},
|
|
208
243
|
disactivate() {
|
|
209
|
-
|
|
244
|
+
l.isActive = !1;
|
|
210
245
|
},
|
|
211
|
-
setError(
|
|
212
|
-
const
|
|
213
|
-
|
|
246
|
+
setError(o, a) {
|
|
247
|
+
const c = this.getForm(o);
|
|
248
|
+
c && (c.error = {
|
|
214
249
|
error: !0,
|
|
215
|
-
messages: [
|
|
216
|
-
},
|
|
250
|
+
messages: [a.message]
|
|
251
|
+
}, c.rerender());
|
|
217
252
|
},
|
|
218
|
-
setFocus(
|
|
219
|
-
const
|
|
220
|
-
|
|
253
|
+
setFocus(o) {
|
|
254
|
+
const a = this.getForm(o);
|
|
255
|
+
a && a.focus && a.focus();
|
|
221
256
|
},
|
|
222
|
-
setValue(
|
|
223
|
-
const
|
|
224
|
-
|
|
257
|
+
setValue(o, a) {
|
|
258
|
+
const c = this.getForm(o);
|
|
259
|
+
c && c.value !== a && this.onChange(o, a);
|
|
225
260
|
},
|
|
226
261
|
getValues() {
|
|
227
|
-
return
|
|
262
|
+
return L(n, i);
|
|
228
263
|
},
|
|
229
264
|
async handleSubmit() {
|
|
230
|
-
if (
|
|
265
|
+
if (u)
|
|
231
266
|
return;
|
|
232
|
-
|
|
233
|
-
let
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
237
|
-
const
|
|
238
|
-
|
|
267
|
+
l.isSubmitted = !0;
|
|
268
|
+
let o = !1, a = !1;
|
|
269
|
+
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));
|
|
239
274
|
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
s();
|
|
275
|
+
}), !a) {
|
|
276
|
+
if (l.dirtyCount === 0 && t) {
|
|
277
|
+
t();
|
|
244
278
|
return;
|
|
245
279
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
280
|
+
if (!x.onSubmit)
|
|
281
|
+
return;
|
|
282
|
+
const c = L(n, i);
|
|
283
|
+
await x.onSubmit(c, {
|
|
284
|
+
setError: (f, h) => {
|
|
285
|
+
const V = this.getForm(f);
|
|
286
|
+
V.error = {
|
|
251
287
|
error: !0,
|
|
252
|
-
messages: [
|
|
253
|
-
},
|
|
288
|
+
messages: [h.message]
|
|
289
|
+
}, V.rerender();
|
|
254
290
|
}
|
|
255
|
-
}).catch((
|
|
256
|
-
console.log("[formkit] submit exception:",
|
|
291
|
+
}).catch((f) => {
|
|
292
|
+
console.log("[formkit] submit exception:", f);
|
|
257
293
|
});
|
|
258
294
|
}
|
|
259
295
|
},
|
|
260
|
-
reset(
|
|
261
|
-
|
|
262
|
-
if (
|
|
296
|
+
reset(o, { asDirty: a }) {
|
|
297
|
+
$(n, [], o, (c, f, h) => {
|
|
298
|
+
if (h === void 0 && i[f].value === void 0)
|
|
263
299
|
return;
|
|
264
|
-
if (
|
|
265
|
-
|
|
300
|
+
if (E.names[f] && h === void 0) {
|
|
301
|
+
i[f].value = void 0;
|
|
266
302
|
return;
|
|
267
303
|
}
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
}),
|
|
271
|
-
|
|
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 }) => {
|
|
307
|
+
c();
|
|
272
308
|
});
|
|
273
309
|
},
|
|
274
310
|
setAsDefault() {
|
|
275
|
-
|
|
276
|
-
a
|
|
277
|
-
}),
|
|
311
|
+
$(n, [], {}, (o, a) => {
|
|
312
|
+
i[a].startValue = i[a].value ?? i[a].defaultValue;
|
|
313
|
+
}), P(), l.isSubmitted = !1;
|
|
278
314
|
},
|
|
279
|
-
registry(
|
|
280
|
-
return
|
|
315
|
+
registry(o, a) {
|
|
316
|
+
return i[o].rerender = a, i[o].value === void 0 && (i[o].value = E.names[o] ? i[o].defaultValue : i[o].startValue), {
|
|
281
317
|
unregistry() {
|
|
282
|
-
if (
|
|
283
|
-
},
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
318
|
+
if (i[o].rerender = () => {
|
|
319
|
+
}, i[o].focus = void 0, l.isActive) {
|
|
320
|
+
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;
|
|
287
323
|
}
|
|
288
324
|
}
|
|
289
325
|
};
|
|
290
326
|
},
|
|
291
|
-
getForm(
|
|
292
|
-
return
|
|
327
|
+
getForm(o) {
|
|
328
|
+
return i[o];
|
|
293
329
|
},
|
|
294
|
-
subscribeToForm(
|
|
295
|
-
const
|
|
296
|
-
return
|
|
297
|
-
|
|
330
|
+
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);
|
|
298
334
|
};
|
|
299
335
|
},
|
|
300
|
-
subscribeToAny(
|
|
301
|
-
return
|
|
302
|
-
|
|
336
|
+
subscribeToAny(o) {
|
|
337
|
+
return F.add(o), () => {
|
|
338
|
+
F.delete(o);
|
|
303
339
|
};
|
|
304
340
|
},
|
|
305
341
|
getNames() {
|
|
306
|
-
return Object.keys(
|
|
342
|
+
return Object.keys(i);
|
|
307
343
|
},
|
|
308
|
-
registryExtraForm(
|
|
309
|
-
const
|
|
310
|
-
return
|
|
311
|
-
|
|
312
|
-
}),
|
|
344
|
+
registryExtraForm(o, a) {
|
|
345
|
+
const c = { visualizeEvalueatedForms: a };
|
|
346
|
+
return o.forEach((f) => {
|
|
347
|
+
E.names[f] = !0;
|
|
348
|
+
}), E.subscribers.push(c), {
|
|
313
349
|
unregistry() {
|
|
314
|
-
|
|
350
|
+
E.subscribers = E.subscribers.filter((f) => f !== c);
|
|
315
351
|
}
|
|
316
352
|
};
|
|
317
353
|
},
|
|
318
|
-
onChange(
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}),
|
|
325
|
-
|
|
326
|
-
});
|
|
354
|
+
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;
|
|
358
|
+
c.value = a, c.rerender(), c.subscribers.forEach(({ callback: V }) => {
|
|
359
|
+
V(a, h);
|
|
360
|
+
}), F.forEach((V) => {
|
|
361
|
+
V();
|
|
362
|
+
}), j.onChange?.(L(n, i));
|
|
327
363
|
}
|
|
328
364
|
};
|
|
329
|
-
},
|
|
330
|
-
const e =
|
|
331
|
-
e.current === null && (e.current =
|
|
365
|
+
}, k = (n, r) => {
|
|
366
|
+
const e = z(null);
|
|
367
|
+
e.current === null && (e.current = K(n, r));
|
|
332
368
|
const s = e.current;
|
|
333
|
-
return
|
|
334
|
-
e.current && (e.current.submitRef.onSubmit = r.onSubmit);
|
|
335
|
-
}, [r.onSubmit]), {
|
|
369
|
+
return m(() => {
|
|
370
|
+
e.current && (e.current.submitRef.onSubmit = r.onSubmit, e.current.changeRef.onChange = r.onChange);
|
|
371
|
+
}, [r.onSubmit, r.onChange]), {
|
|
336
372
|
manager: s,
|
|
337
|
-
useValue: (t) =>
|
|
338
|
-
reset: (t,
|
|
339
|
-
s.reset(t,
|
|
373
|
+
useValue: (t) => M(t),
|
|
374
|
+
reset: (t, u = {}) => {
|
|
375
|
+
s.reset(t, u);
|
|
340
376
|
},
|
|
341
377
|
setAsDefault: () => {
|
|
342
378
|
s.setAsDefault();
|
|
@@ -344,11 +380,11 @@ const j = M({}), q = (o) => {
|
|
|
344
380
|
setFocus: (t) => {
|
|
345
381
|
s.setFocus(t);
|
|
346
382
|
},
|
|
347
|
-
setError: (t,
|
|
348
|
-
s.setError(t,
|
|
383
|
+
setError: (t, u) => {
|
|
384
|
+
s.setError(t, u);
|
|
349
385
|
},
|
|
350
|
-
setValue: (t,
|
|
351
|
-
s.setValue(t,
|
|
386
|
+
setValue: (t, u) => {
|
|
387
|
+
s.setValue(t, u);
|
|
352
388
|
},
|
|
353
389
|
getValue: (t) => s.getForm(t).value,
|
|
354
390
|
getValues: () => s.getValues(),
|
|
@@ -356,19 +392,19 @@ const j = M({}), q = (o) => {
|
|
|
356
392
|
await s.handleSubmit();
|
|
357
393
|
},
|
|
358
394
|
// prettier-ignore
|
|
359
|
-
subscribe: (t,
|
|
395
|
+
subscribe: (t, u) => s.subscribeToForm(t, u),
|
|
360
396
|
// подписка на любое изменение значений формы (для гейтов поверх всех полей)
|
|
361
397
|
subscribeAny: (t) => s.subscribeToAny(t),
|
|
362
398
|
// плоский список имён всех полей (dotted-пути; вложенные context раскрыты)
|
|
363
399
|
getNames: () => s.getNames()
|
|
364
400
|
};
|
|
365
|
-
},
|
|
366
|
-
|
|
367
|
-
}, []),
|
|
368
|
-
|
|
369
|
-
}, []), /* @__PURE__ */
|
|
401
|
+
}, I = ({ manager: n }) => (A(() => {
|
|
402
|
+
n.activate();
|
|
403
|
+
}, []), m(() => () => {
|
|
404
|
+
n.disactivate();
|
|
405
|
+
}, []), /* @__PURE__ */ g(D.Provider, { value: n, children: /* @__PURE__ */ g(p, { scheme: n.scheme, path: [] }) })), w = (n) => {
|
|
370
406
|
try {
|
|
371
|
-
|
|
407
|
+
n();
|
|
372
408
|
} catch (r) {
|
|
373
409
|
return r && typeof r == "string" ? {
|
|
374
410
|
error: !0,
|
|
@@ -380,66 +416,67 @@ const j = M({}), q = (o) => {
|
|
|
380
416
|
error: !0
|
|
381
417
|
};
|
|
382
418
|
}
|
|
383
|
-
},
|
|
384
|
-
const s =
|
|
419
|
+
}, rr = (n) => (r, e) => {
|
|
420
|
+
const s = n.getRequireCheck(e), { $rules: t = {}, ...u } = e, { validate: d, required: b } = t;
|
|
385
421
|
return {
|
|
386
422
|
type: "form",
|
|
387
423
|
name: r,
|
|
388
|
-
defaultValue:
|
|
389
|
-
Form:
|
|
390
|
-
validate: (
|
|
391
|
-
if (
|
|
392
|
-
const v =
|
|
424
|
+
defaultValue: n.defaultValue,
|
|
425
|
+
Form: n.getForm(u),
|
|
426
|
+
validate: (y) => {
|
|
427
|
+
if (b) {
|
|
428
|
+
const v = w(() => s(y));
|
|
393
429
|
if (v)
|
|
394
430
|
return v;
|
|
395
|
-
if (
|
|
396
|
-
const
|
|
397
|
-
if (
|
|
398
|
-
return
|
|
431
|
+
if (d) {
|
|
432
|
+
const x = w(() => d(y));
|
|
433
|
+
if (x)
|
|
434
|
+
return x;
|
|
399
435
|
}
|
|
400
436
|
return;
|
|
401
437
|
}
|
|
402
|
-
if (
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
return
|
|
438
|
+
if (d && !w(() => s(y))) {
|
|
439
|
+
const x = w(() => d(y));
|
|
440
|
+
if (x)
|
|
441
|
+
return x;
|
|
406
442
|
}
|
|
407
443
|
}
|
|
408
444
|
};
|
|
409
|
-
},
|
|
445
|
+
}, er = (n) => (r) => (...e) => ({
|
|
410
446
|
type: "layout",
|
|
411
|
-
Layout:
|
|
447
|
+
Layout: n(r),
|
|
412
448
|
childs: e
|
|
413
|
-
}),
|
|
414
|
-
getItems:
|
|
449
|
+
}), tr = ({
|
|
450
|
+
getItems: n,
|
|
415
451
|
getController: r
|
|
416
452
|
}) => ({
|
|
417
453
|
type: "extra",
|
|
418
|
-
items:
|
|
454
|
+
items: n((e) => (s) => ({ type: "registry", name: e, getForm: s })),
|
|
419
455
|
getController: r
|
|
420
|
-
}),
|
|
456
|
+
}), sr = (n) => (...r) => ({
|
|
421
457
|
type: "context",
|
|
422
|
-
context:
|
|
458
|
+
context: n,
|
|
423
459
|
childs: r
|
|
424
|
-
}),
|
|
460
|
+
}), nr = (n, r) => (...e) => ({
|
|
425
461
|
type: "condition",
|
|
426
|
-
depended:
|
|
462
|
+
depended: n,
|
|
427
463
|
canActivate: r.canActivate,
|
|
428
464
|
childs: e
|
|
429
|
-
}),
|
|
465
|
+
}), or = ({ hidden: n }) => (...r) => ({
|
|
430
466
|
type: "visability",
|
|
431
|
-
hidden:
|
|
467
|
+
hidden: n ?? !1,
|
|
432
468
|
childs: r
|
|
433
469
|
});
|
|
434
470
|
export {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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,
|
|
481
|
+
M as useValue
|
|
445
482
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { useForm, FormLayout } from './useForm';
|
|
2
|
-
export { useValue, createUseValue } from './useValue';
|
|
2
|
+
export { useValue, useSetValue, createUseValue } from './useValue';
|
|
3
3
|
export { createForm } from './core/builders/create-form';
|
|
4
4
|
export { createLayout } from './core/builders/create-layout';
|
|
5
5
|
export { createExtraForm } from './core/builders/create-extra-form';
|
|
@@ -22,7 +22,10 @@ export interface ResetOptions {
|
|
|
22
22
|
}
|
|
23
23
|
export interface FormManager<Values, FlattenValues, ClonedValues> {
|
|
24
24
|
submitRef: {
|
|
25
|
-
onSubmit
|
|
25
|
+
onSubmit?: (values: Values, callbacks: SubmitCallbacls<FlattenValues>) => Promise<void>;
|
|
26
|
+
};
|
|
27
|
+
changeRef: {
|
|
28
|
+
onChange?: (values: Values) => void;
|
|
26
29
|
};
|
|
27
30
|
scheme: SchemeItems.All[];
|
|
28
31
|
disabled?: boolean;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { Forms } from './manager';
|
|
1
2
|
import { FieldValues } from '../types';
|
|
2
3
|
import { SchemeItems } from '../core/types';
|
|
3
4
|
type cb = (item: SchemeItems.Form, name: string, value?: any) => void;
|
|
5
|
+
type shownCb = (name: string) => void;
|
|
4
6
|
declare const readScheme: (scheme: SchemeItems.All[], path: string[], values: FieldValues, callback: cb) => void;
|
|
5
|
-
|
|
7
|
+
declare const readShown: (scheme: SchemeItems.All[], path: string[], forms: Forms, callback: shownCb) => void;
|
|
8
|
+
export { readScheme, readShown };
|
package/dist/useForm.d.ts
CHANGED
|
@@ -30,7 +30,8 @@ export interface MainOptions<Values extends FieldValues, FlattenValues, ClonedVa
|
|
|
30
30
|
onDirty?: (event: DirtyEvent<FlattenValues>) => void;
|
|
31
31
|
onChangeEvent?: (event: ChangeEvent<FlattenValues>) => void;
|
|
32
32
|
onFormDirty?: (isDirty: boolean) => void;
|
|
33
|
-
|
|
33
|
+
onChange?: (values: Values) => void;
|
|
34
|
+
onSubmit?: (values: Values, callbacks: SubmitCallbacls<FlattenValues>) => Promise<void>;
|
|
34
35
|
}
|
|
35
36
|
export type GetDefaultValues<Items extends SchemeItems.All[]> = DeepPartial<ExtractValues<Items[number]>>;
|
|
36
37
|
declare const useDynamicForm: (scheme: SchemeItems.All[], opts: MainOptions<FieldValues, FieldValues, FieldValues>) => {
|
package/dist/useValue.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SchemeItems } from './core/types';
|
|
2
2
|
import { ExtractFlatValues } from './core/extract';
|
|
3
3
|
export declare const useValue: <T = any>(name: string) => T;
|
|
4
|
+
export declare const useSetValue: <T = any>(name: string) => (value: T) => void;
|
|
4
5
|
export declare const createUseValue: <Items extends SchemeItems.All[]>() => <FlattenValues extends ExtractFlatValues<Items[number]>, K extends keyof FlattenValues>(name: K & string) => FlattenValues[K];
|