@akinon/akiform-builder 1.3.0 → 1.3.1

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 (43) hide show
  1. package/dist/cjs/akiform-builder.d.ts +7 -0
  2. package/dist/cjs/akiform-builder.d.ts.map +1 -0
  3. package/dist/cjs/akiform-builder.js +458 -0
  4. package/dist/cjs/field-builder.d.ts +54 -0
  5. package/dist/cjs/field-builder.d.ts.map +1 -0
  6. package/dist/cjs/field-builder.js +153 -0
  7. package/dist/cjs/i18n/index.d.ts +2 -0
  8. package/dist/cjs/i18n/index.d.ts.map +1 -0
  9. package/dist/cjs/i18n/index.js +14 -0
  10. package/dist/cjs/i18n/translations/en.d.ts +14 -0
  11. package/dist/cjs/i18n/translations/en.d.ts.map +1 -0
  12. package/dist/cjs/i18n/translations/en.js +15 -0
  13. package/dist/cjs/i18n/translations/tr.d.ts +14 -0
  14. package/dist/cjs/i18n/translations/tr.d.ts.map +1 -0
  15. package/dist/cjs/i18n/translations/tr.js +15 -0
  16. package/dist/cjs/index.d.ts +4 -0
  17. package/dist/cjs/index.d.ts.map +1 -0
  18. package/dist/cjs/index.js +21 -0
  19. package/dist/cjs/types.d.ts +106 -0
  20. package/dist/cjs/types.d.ts.map +1 -0
  21. package/dist/cjs/types.js +2 -0
  22. package/dist/esm/akiform-builder.d.ts +7 -0
  23. package/dist/esm/akiform-builder.d.ts.map +1 -0
  24. package/dist/esm/akiform-builder.js +455 -0
  25. package/dist/esm/field-builder.d.ts +54 -0
  26. package/dist/esm/field-builder.d.ts.map +1 -0
  27. package/dist/esm/field-builder.js +150 -0
  28. package/dist/esm/i18n/index.d.ts +2 -0
  29. package/dist/esm/i18n/index.d.ts.map +1 -0
  30. package/dist/esm/i18n/index.js +11 -0
  31. package/dist/esm/i18n/translations/en.d.ts +14 -0
  32. package/dist/esm/i18n/translations/en.d.ts.map +1 -0
  33. package/dist/esm/i18n/translations/en.js +13 -0
  34. package/dist/esm/i18n/translations/tr.d.ts +14 -0
  35. package/dist/esm/i18n/translations/tr.d.ts.map +1 -0
  36. package/dist/esm/i18n/translations/tr.js +13 -0
  37. package/dist/esm/index.d.ts +4 -0
  38. package/dist/esm/index.d.ts.map +1 -0
  39. package/dist/esm/index.js +3 -0
  40. package/dist/esm/types.d.ts +106 -0
  41. package/dist/esm/types.d.ts.map +1 -0
  42. package/dist/esm/types.js +1 -0
  43. package/package.json +10 -10
@@ -0,0 +1,455 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import './index.css';
13
+ import { Akiform, akivalResolver, FormItem, useFieldArray, useForm, useWatch } from '@akinon/akiform';
14
+ import { akival } from '@akinon/akival';
15
+ import { Icon } from '@akinon/icons';
16
+ import { Button } from '@akinon/ui-button';
17
+ import { Checkbox } from '@akinon/ui-checkbox';
18
+ import { Collapse } from '@akinon/ui-collapse';
19
+ import { DatePicker } from '@akinon/ui-date-picker';
20
+ import { Divider } from '@akinon/ui-divider';
21
+ import { Input, InputTextArea } from '@akinon/ui-input';
22
+ import { InputNumber } from '@akinon/ui-input-number';
23
+ import { Col, Row } from '@akinon/ui-layout';
24
+ import { Select } from '@akinon/ui-select';
25
+ import { Text } from '@akinon/ui-typography';
26
+ import clsx from 'clsx';
27
+ import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
28
+ import { i18n } from './i18n';
29
+ export const THROTTLE_DELAY = 300; // ms
30
+ const checkIsDisabled = ({ field, formValues }) => {
31
+ var _a;
32
+ const configDisabledProperty = (_a = field.config) === null || _a === void 0 ? void 0 : _a.disabled;
33
+ return typeof configDisabledProperty === 'function'
34
+ ? configDisabledProperty(formValues)
35
+ : !!configDisabledProperty;
36
+ };
37
+ const checkIsVisible = ({ field, formValues }) => {
38
+ var _a;
39
+ const configVisibleProperty = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
40
+ return typeof configVisibleProperty === 'function'
41
+ ? configVisibleProperty(formValues)
42
+ : configVisibleProperty !== false;
43
+ };
44
+ const SectionComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const { errors } = formState;
47
+ if (field.collapsible) {
48
+ return (React.createElement(Collapse, { defaultActiveKey: field.defaultExpanded ? [field.key] : [], expandIcon: panelProps => ({
49
+ name: 'circle-down',
50
+ style: {
51
+ color: 'var(--color-azure-500)',
52
+ transform: panelProps.isActive ? 'rotate(-180deg)' : 'rotate(0deg)',
53
+ transition: 'transform 0.3s'
54
+ },
55
+ size: 20
56
+ }), items: [
57
+ {
58
+ label: (React.createElement("div", { className: "akiform-builder-form-actions" },
59
+ React.createElement(Text, { strong: true }, field.label),
60
+ Object.keys(errors).length > 0 ? (React.createElement(Text, { strong: true, type: "danger" }, i18n.t('an_error_occurred'))) : null)),
61
+ key: field.key,
62
+ children: field.fields.map(nestedField => {
63
+ return renderFormItem({
64
+ field: nestedField,
65
+ control,
66
+ formValues,
67
+ formState,
68
+ layout,
69
+ layoutOptions
70
+ });
71
+ })
72
+ }
73
+ ] }));
74
+ }
75
+ else {
76
+ return (React.createElement(React.Fragment, null,
77
+ React.createElement(Divider, { orientation: "left", plain: true, plainOffset: 40 }, field.label),
78
+ field.fields.map(nestedField => {
79
+ return renderFormItem({
80
+ field: nestedField,
81
+ control,
82
+ formValues,
83
+ formState,
84
+ layout,
85
+ layoutOptions
86
+ });
87
+ })));
88
+ }
89
+ };
90
+ const RowComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
91
+ const { columnFields, rowProps } = field;
92
+ if (!(columnFields === null || columnFields === void 0 ? void 0 : columnFields.length))
93
+ return;
94
+ return (React.createElement(Row, Object.assign({}, rowProps), columnFields.map(columnField => {
95
+ const { columnProps } = columnField;
96
+ const isVisible = checkIsVisible({
97
+ field: columnField,
98
+ formValues
99
+ });
100
+ if (!isVisible)
101
+ return null;
102
+ return (React.createElement(Col, Object.assign({ key: columnField.key, flex: "1" }, columnProps),
103
+ React.createElement(ColumnComponent, { field: columnField, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions })));
104
+ })));
105
+ };
106
+ const ColumnComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
107
+ const { fields } = field;
108
+ if (!(fields === null || fields === void 0 ? void 0 : fields.length))
109
+ return;
110
+ return fields.map(rowField => {
111
+ const isVisible = checkIsVisible({
112
+ field: rowField,
113
+ formValues
114
+ });
115
+ if (!isVisible)
116
+ return null;
117
+ const isRowField = rowField.type === 'row';
118
+ return isRowField
119
+ ? renderField(rowField, control, formValues, formState, layout, layoutOptions)
120
+ : renderFormItem({
121
+ field: rowField,
122
+ control,
123
+ formValues,
124
+ formState,
125
+ layout,
126
+ layoutOptions
127
+ });
128
+ });
129
+ };
130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
+ const renderField = (field, control, formValues,
132
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
133
+ formState, layout, layoutOptions) => {
134
+ const commonProps = {
135
+ 'aria-required': field.validation ? true : false,
136
+ 'aria-invalid': formState.errors[field.key] ? true : false
137
+ };
138
+ switch (field.type) {
139
+ case 'text':
140
+ return (React.createElement(Input, Object.assign({ placeholder: field.placeholder, size: "large" }, commonProps)));
141
+ case 'number':
142
+ return (React.createElement(InputNumber, Object.assign({ placeholder: field.placeholder, size: "large" }, commonProps)));
143
+ case 'select':
144
+ return (React.createElement(Select, Object.assign({ placeholder: field.placeholder, options: field.options }, commonProps)));
145
+ case 'checkbox':
146
+ return (React.createElement(Checkbox, Object.assign({ checked: formValues[field.key] }, commonProps), field.label));
147
+ case 'date':
148
+ return (React.createElement(DatePicker, Object.assign({ placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconColor: "var(--color-azure-500)", suffixIconSize: "16" }, commonProps)));
149
+ case 'textarea':
150
+ return React.createElement(InputTextArea, Object.assign({ placeholder: field.placeholder }, commonProps));
151
+ case 'fieldArray':
152
+ return (React.createElement(FieldArrayComponent, { field: field, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions }));
153
+ case 'custom':
154
+ if (typeof field.render === 'function') {
155
+ return field.render({ field, formValues, control, formState });
156
+ }
157
+ console.warn(`Custom field "${field.key}" has no render function`);
158
+ return React.createElement(Fragment, null);
159
+ case 'section':
160
+ return (React.createElement(SectionComponent, { field: field, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions }));
161
+ case 'row':
162
+ return (React.createElement(RowComponent, { field: field, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions }));
163
+ case 'column':
164
+ return (React.createElement(ColumnComponent, { field: field, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions }));
165
+ default:
166
+ return React.createElement(Fragment, null);
167
+ }
168
+ };
169
+ const renderFormItem = ({ field, control, formValues, formState, layout, layoutOptions, customVisibleCheck }) => {
170
+ const isVisible = customVisibleCheck
171
+ ? customVisibleCheck()
172
+ : checkIsVisible({
173
+ field,
174
+ formValues
175
+ });
176
+ if (!isVisible)
177
+ return null;
178
+ const isDisabled = checkIsDisabled({
179
+ field,
180
+ formValues
181
+ });
182
+ return (React.createElement(FormItem, { key: field.key, control: control, name: field.key, label: field.label, required: field.validation ? true : false, tooltip: field.tooltip, disabled: isDisabled, help: field.help, labelDescription: field.labelDescription }, renderField(field, control, formValues, formState, layout, layoutOptions)));
183
+ };
184
+ export const AkiformBuilder = forwardRef((_a, ref) => {
185
+ var _b, _c;
186
+ var { fields, onSubmit, layout = 'vertical', layoutOptions, showResetButton = false, onReset, controlled = false, values, onValueChange, submitButtonProps, resetButtonProps } = _a, rest = __rest(_a, ["fields", "onSubmit", "layout", "layoutOptions", "showResetButton", "onReset", "controlled", "values", "onValueChange", "submitButtonProps", "resetButtonProps"]);
187
+ const validationSchema = useMemo(() => {
188
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
189
+ const schema = {};
190
+ fields.forEach(field => {
191
+ if (field.validation) {
192
+ schema[field.key] = field.validation;
193
+ }
194
+ if (field.type === 'fieldArray') {
195
+ schema[field.key] = akival.array().of(akival.object().shape(field.fields.reduce((acc, nestedField) => {
196
+ if (nestedField.validation) {
197
+ acc[nestedField.key] = nestedField.validation;
198
+ }
199
+ return acc;
200
+ },
201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
+ {})));
203
+ }
204
+ });
205
+ return akival.object().shape(schema);
206
+ }, [fields]);
207
+ const { control, handleSubmit, reset, setValue, formState } = useForm(Object.assign({
208
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
209
+ resolver: akivalResolver(validationSchema),
210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
211
+ defaultValues: rest.initialValues }, (controlled && { values: values })));
212
+ const formValues = useWatch({ control });
213
+ const prevFormValuesRef = useRef(null);
214
+ const isInitialRenderRef = useRef(true);
215
+ const throttleTimeoutRef = useRef(null);
216
+ const hasSubmitButton = !!onSubmit;
217
+ const hasFormActions = hasSubmitButton || showResetButton;
218
+ const handleValueChange = useCallback((values) => {
219
+ if (!controlled) {
220
+ if (throttleTimeoutRef.current) {
221
+ clearTimeout(throttleTimeoutRef.current);
222
+ }
223
+ throttleTimeoutRef.current = setTimeout(() => {
224
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(values);
225
+ }, THROTTLE_DELAY);
226
+ }
227
+ else {
228
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(values);
229
+ }
230
+ }, [controlled, onValueChange]);
231
+ useEffect(() => {
232
+ if (isInitialRenderRef.current) {
233
+ isInitialRenderRef.current = false;
234
+ prevFormValuesRef.current = Object.assign({}, formValues);
235
+ return;
236
+ }
237
+ if (formState.isDirty ||
238
+ Object.keys(formState.touchedFields).length > 0) {
239
+ const hasChanged = JSON.stringify(formValues) !==
240
+ JSON.stringify(prevFormValuesRef.current);
241
+ if (hasChanged) {
242
+ handleValueChange(formValues);
243
+ prevFormValuesRef.current = Object.assign({}, formValues);
244
+ }
245
+ }
246
+ }, [
247
+ formValues,
248
+ formState.isDirty,
249
+ formState.touchedFields,
250
+ handleValueChange
251
+ ]);
252
+ useEffect(() => {
253
+ return () => {
254
+ if (throttleTimeoutRef.current) {
255
+ clearTimeout(throttleTimeoutRef.current);
256
+ }
257
+ };
258
+ }, []);
259
+ useEffect(() => {
260
+ if (controlled && onValueChange) {
261
+ onValueChange(formValues);
262
+ }
263
+ }, [controlled, onValueChange, formValues]);
264
+ const formItemLayout = useMemo(() => {
265
+ const defaultHorizontalLayout = {
266
+ labelCol: { span: 6 },
267
+ wrapperCol: { span: 18 }
268
+ };
269
+ const defaultInlineLayout = {
270
+ wrapperCol: { span: 24 }
271
+ };
272
+ switch (layout) {
273
+ case 'horizontal':
274
+ return {
275
+ labelCol: (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.labelCol) || defaultHorizontalLayout.labelCol,
276
+ wrapperCol: (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.wrapperCol) || defaultHorizontalLayout.wrapperCol
277
+ };
278
+ case 'inline':
279
+ return {
280
+ wrapperCol: (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.wrapperCol) || defaultInlineLayout.wrapperCol
281
+ };
282
+ case 'vertical':
283
+ default:
284
+ return {};
285
+ }
286
+ }, [layout, layoutOptions]);
287
+ const handleReset = (event) => {
288
+ event.preventDefault();
289
+ reset();
290
+ if (onReset) {
291
+ // Create a synthetic FormEvent if the event is a MouseEvent
292
+ const formEvent = event.type === 'click'
293
+ ? {
294
+ preventDefault: () => { },
295
+ target: event.target.closest('form')
296
+ }
297
+ : event;
298
+ onReset(formEvent);
299
+ }
300
+ };
301
+ useImperativeHandle(ref, () => ({
302
+ reset: (values) => {
303
+ if (values) {
304
+ // Partial reset: only reset specified fields
305
+ Object.keys(values).forEach(key => {
306
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
307
+ setValue(key, values[key]);
308
+ });
309
+ }
310
+ else {
311
+ // Full reset
312
+ reset();
313
+ }
314
+ if (onReset) {
315
+ const syntheticEvent = {
316
+ preventDefault: () => { },
317
+ target: { reset: () => { } }
318
+ };
319
+ onReset(syntheticEvent);
320
+ }
321
+ }
322
+ }));
323
+ const renderSubmitButton = () => {
324
+ const _a = submitButtonProps || {}, { children, block = false, className } = _a, otherSubmitButtonProps = __rest(_a, ["children", "block", "className"]);
325
+ const submitButtonClassName = clsx(className, {
326
+ 'w-full': block
327
+ });
328
+ return (React.createElement(Button, Object.assign({ className: submitButtonClassName, type: "primary" }, otherSubmitButtonProps, { htmlType: "submit" }), children || i18n.t('submit')));
329
+ };
330
+ const renderShowResetButton = () => {
331
+ const _a = resetButtonProps || {}, { children, block = false, className, onClick } = _a, otherResetButtonProps = __rest(_a, ["children", "block", "className", "onClick"]);
332
+ const resetButtonClassName = clsx(className, {
333
+ 'w-full': block
334
+ });
335
+ const handleOnClickReset = event => {
336
+ handleReset(event);
337
+ if (onClick) {
338
+ onClick(event);
339
+ }
340
+ };
341
+ return (React.createElement(Button
342
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
343
+ , Object.assign({
344
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
345
+ onClick: handleOnClickReset, className: resetButtonClassName, type: "default" }, otherResetButtonProps, { htmlType: "reset" }), children || i18n.t('reset')));
346
+ };
347
+ const renderFormActions = () => {
348
+ return (React.createElement("div", { className: "akiform-builder-form-actions" },
349
+ hasSubmitButton && renderSubmitButton(),
350
+ showResetButton && renderShowResetButton()));
351
+ };
352
+ return (React.createElement("div", { className: "akiform-builder" },
353
+ React.createElement(Akiform, Object.assign({}, (hasSubmitButton && { onFinish: handleSubmit(onSubmit) }), { onReset: handleReset, layout: layout }, formItemLayout, rest, { "data-testid": "akiform-builder", role: "form", "aria-label": i18n.t('formLabel'), requiredMark: true }),
354
+ fields.map(field => {
355
+ const isVisible = checkIsVisible({
356
+ field,
357
+ formValues
358
+ });
359
+ if (!isVisible) {
360
+ return null;
361
+ }
362
+ switch (field.type) {
363
+ case 'section':
364
+ return (React.createElement(SectionComponent, { key: field.key, field: field, control: control, formValues: formValues, formState: formState, layout: layout, layoutOptions: layoutOptions }));
365
+ case 'fieldArray':
366
+ return (React.createElement("div", { className: "akiform-builder-field-array", key: field.key },
367
+ React.createElement(Divider, { orientation: "left", plain: true, plainOffset: 40 },
368
+ React.createElement("span", { id: `${field.key}-label` }, field.label)),
369
+ renderField(field, control, formValues, formState, layout, layoutOptions)));
370
+ case 'row':
371
+ return renderField(field, control, formValues, formState, layout, layoutOptions);
372
+ default:
373
+ return renderFormItem({
374
+ field,
375
+ control,
376
+ formValues,
377
+ formState,
378
+ layout,
379
+ layoutOptions
380
+ });
381
+ }
382
+ }),
383
+ hasFormActions && (React.createElement(FormItem, { control: control, name: 'form_actions', wrapperCol: layout === 'horizontal'
384
+ ? {
385
+ offset: (_b = formItemLayout.labelCol) === null || _b === void 0 ? void 0 : _b.span,
386
+ span: (_c = formItemLayout.wrapperCol) === null || _c === void 0 ? void 0 : _c.span
387
+ }
388
+ : undefined }, renderFormActions())))));
389
+ });
390
+ AkiformBuilder.displayName = 'AkiformBuilder';
391
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
392
+ const FieldArrayComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
393
+ const { errors } = formState;
394
+ const { fields, append, remove, insert } = useFieldArray({
395
+ control,
396
+ name: field.key
397
+ });
398
+ const createInitialValue = () => {
399
+ return field.fields.reduce((acc, nestedField) => {
400
+ acc[nestedField.key] = nestedField.defaultValue || '';
401
+ return acc;
402
+ },
403
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
404
+ {});
405
+ };
406
+ return (React.createElement("div", { role: "group", "aria-labelledby": `${field.key}-label` },
407
+ !fields.length && (React.createElement("div", { className: "akiform-builder-form-actions akiform-builder-action-icon", "data-testid": `${field.key}-add-button`, onClick: () => append(createInitialValue()) },
408
+ React.createElement(Icon, { icon: "plus", size: 20, color: "var(--color-green-500)", "aria-label": i18n.t('add', { label: field.label }) }),
409
+ React.createElement(Text, { strong: true }, i18n.t('add', { label: field.label })))),
410
+ fields.map((item, index) => {
411
+ var _a;
412
+ return (React.createElement(Fragment, { key: item.id },
413
+ React.createElement(Collapse, { collapsible: "icon", defaultActiveKey: field.defaultExpanded ? [item.id] : [], expandIcon: panelProps => ({
414
+ name: 'circle-down',
415
+ style: {
416
+ color: 'var(--color-azure-500)',
417
+ transform: panelProps.isActive
418
+ ? 'rotate(-180deg)'
419
+ : 'rotate(0deg)',
420
+ transition: 'transform 0.3s'
421
+ },
422
+ size: 20
423
+ }), items: [
424
+ {
425
+ label: (React.createElement("div", { className: "akiform-builder-form-actions" },
426
+ React.createElement(Text, { strong: true }, i18n.t('itemof', {
427
+ label: field.label,
428
+ count: index + 1,
429
+ ordinal: true
430
+ })),
431
+ React.createElement(Icon, { className: "akiform-builder-action-icon", onClick: () => remove(index), icon: "minus", size: 20, color: "var(--color-red-500)", "aria-label": i18n.t('remove', { label: field.label }) }),
432
+ React.createElement(Icon, { className: "akiform-builder-action-icon", onClick: () => insert(index + 1, createInitialValue()), icon: "plus", size: 20, color: "var(--color-green-500)", "aria-label": i18n.t('add', { label: field.label }) }),
433
+ ((_a = errors[field.key]) === null || _a === void 0 ? void 0 : _a[index]) ? (React.createElement(Text, { strong: true, type: "danger" }, i18n.t('an_error_occurred'))) : null)),
434
+ key: field.key,
435
+ children: field.fields.map(nestedField => {
436
+ return renderFormItem({
437
+ field: Object.assign(Object.assign({}, nestedField), { key: `${field.key}.${index}.${nestedField.key}` }),
438
+ control,
439
+ formValues,
440
+ formState,
441
+ layout,
442
+ layoutOptions,
443
+ customVisibleCheck: () => {
444
+ var _a, _b;
445
+ return typeof ((_a = nestedField.config) === null || _a === void 0 ? void 0 : _a.visible) === 'function'
446
+ ? nestedField.config.visible(((_b = formValues[field.key]) === null || _b === void 0 ? void 0 : _b[index]) || {})
447
+ : true;
448
+ }
449
+ });
450
+ })
451
+ }
452
+ ] }),
453
+ React.createElement(Divider, { plain: true })));
454
+ })));
455
+ };
@@ -0,0 +1,54 @@
1
+ import { FieldPath, FieldValues } from '@akinon/akiform';
2
+ import { AnySchema } from '@akinon/akival';
3
+ import type { ColProps, RowProps } from '@akinon/ui-layout';
4
+ import type { TooltipProps } from '@akinon/ui-tooltip';
5
+ import type { FieldConfig, FieldType, FormField } from './types';
6
+ type FieldTypeToBuilder<T extends FieldType, TFieldValues extends FieldValues = FieldValues> = T extends 'select' ? SelectFieldBuilder<TFieldValues> : T extends 'date' ? DateFieldBuilder<TFieldValues> : T extends 'custom' ? CustomFieldBuilder<TFieldValues> : T extends 'section' ? SectionFieldBuilder<TFieldValues> : T extends 'fieldArray' ? FieldArrayOrSectionFieldBuilder<TFieldValues> : T extends 'row' ? RowFieldBuilder<TFieldValues> : T extends 'column' ? ColumnFieldBuilder<TFieldValues> : BaseFieldBuilder<TFieldValues>;
7
+ declare class BaseFieldBuilder<TFieldValues extends FieldValues = FieldValues> {
8
+ field: Partial<FormField<TFieldValues>>;
9
+ key(key: FieldPath<TFieldValues>): this;
10
+ label(label: string): this;
11
+ type<T extends FieldType>(type: T): FieldTypeToBuilder<T, TFieldValues>;
12
+ placeholder(placeholder: string): this;
13
+ defaultValue(value: any): this;
14
+ validation(schema: AnySchema): this;
15
+ config(config: FieldConfig<TFieldValues>): this;
16
+ tooltip(tooltipProps: TooltipProps | string): this;
17
+ help(help: string): this;
18
+ labelDescription(labelDescription: string): this;
19
+ build(): FormField<TFieldValues>;
20
+ }
21
+ declare class SelectFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
22
+ options(options: Array<{
23
+ value: string | number;
24
+ label: string;
25
+ }>): this;
26
+ }
27
+ declare class DateFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
28
+ showTime(showTime: boolean): this;
29
+ }
30
+ declare class CustomFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
31
+ render(renderFn: (props: {
32
+ field: FormField<TFieldValues>;
33
+ formValues: TFieldValues;
34
+ control: any;
35
+ }) => React.ReactElement): this;
36
+ }
37
+ declare class FieldArrayOrSectionFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
38
+ defaultExpanded(expanded: boolean): this;
39
+ fields(fields: FormField<TFieldValues>[]): this;
40
+ }
41
+ declare class SectionFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends FieldArrayOrSectionFieldBuilder<TFieldValues> {
42
+ collapsible(collapsible: boolean): this;
43
+ }
44
+ declare class RowFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
45
+ columnFields(columnFields: FormField<TFieldValues>[]): this;
46
+ rowProps(rowProps: RowProps): this;
47
+ }
48
+ declare class ColumnFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
49
+ fields(fields: FormField<TFieldValues>[]): this;
50
+ columnProps(columnProps: ColProps): this;
51
+ }
52
+ export declare function field<TFieldValues extends FieldValues = FieldValues>(): BaseFieldBuilder<TFieldValues> & SelectFieldBuilder<TFieldValues> & DateFieldBuilder<TFieldValues> & CustomFieldBuilder<TFieldValues> & SectionFieldBuilder<TFieldValues> & FieldArrayOrSectionFieldBuilder<TFieldValues>;
53
+ export {};
54
+ //# sourceMappingURL=field-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-builder.d.ts","sourceRoot":"","sources":["../../src/field-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ class BaseFieldBuilder {
2
+ constructor() {
3
+ this.field = {};
4
+ }
5
+ key(key) {
6
+ this.field.key = key;
7
+ return this;
8
+ }
9
+ label(label) {
10
+ this.field.label = label;
11
+ return this;
12
+ }
13
+ type(type) {
14
+ this.field.type = type;
15
+ return this;
16
+ }
17
+ placeholder(placeholder) {
18
+ this.field.placeholder = placeholder;
19
+ return this;
20
+ }
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ defaultValue(value) {
23
+ this.field.defaultValue = value;
24
+ return this;
25
+ }
26
+ validation(schema) {
27
+ this.field.validation = schema;
28
+ return this;
29
+ }
30
+ config(config) {
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ this.field.config = config;
33
+ return this;
34
+ }
35
+ tooltip(tooltipProps) {
36
+ this.field.tooltip = tooltipProps;
37
+ return this;
38
+ }
39
+ help(help) {
40
+ this.field.help = help;
41
+ return this;
42
+ }
43
+ labelDescription(labelDescription) {
44
+ this.field.labelDescription = labelDescription;
45
+ return this;
46
+ }
47
+ build() {
48
+ if (!this.field.key || !this.field.type) {
49
+ throw new Error('Field must have at least a key and type');
50
+ }
51
+ return this.field;
52
+ }
53
+ }
54
+ class SelectFieldBuilder extends BaseFieldBuilder {
55
+ options(options) {
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ this.field.options = options;
58
+ return this;
59
+ }
60
+ }
61
+ class DateFieldBuilder extends BaseFieldBuilder {
62
+ showTime(showTime) {
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ this.field.showTime = showTime;
65
+ return this;
66
+ }
67
+ }
68
+ class CustomFieldBuilder extends BaseFieldBuilder {
69
+ render(renderFn) {
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ this.field.render = renderFn;
72
+ return this;
73
+ }
74
+ }
75
+ class FieldArrayOrSectionFieldBuilder extends BaseFieldBuilder {
76
+ defaultExpanded(expanded) {
77
+ this.field.defaultExpanded = expanded;
78
+ return this;
79
+ }
80
+ fields(fields) {
81
+ if (this.field.type === 'fieldArray' || this.field.type === 'section') {
82
+ this.field.fields = fields;
83
+ }
84
+ else {
85
+ console.warn(`Fields can only be set for 'fieldArray' or 'section' types. Current type: ${this.field.type}`);
86
+ }
87
+ return this;
88
+ }
89
+ }
90
+ class SectionFieldBuilder extends FieldArrayOrSectionFieldBuilder {
91
+ collapsible(collapsible) {
92
+ this.field.collapsible = collapsible;
93
+ return this;
94
+ }
95
+ }
96
+ class RowFieldBuilder extends BaseFieldBuilder {
97
+ columnFields(columnFields) {
98
+ this.field.columnFields =
99
+ columnFields;
100
+ return this;
101
+ }
102
+ rowProps(rowProps) {
103
+ this.field.rowProps = rowProps;
104
+ return this;
105
+ }
106
+ }
107
+ class ColumnFieldBuilder extends BaseFieldBuilder {
108
+ fields(fields) {
109
+ this.field.fields = fields;
110
+ return this;
111
+ }
112
+ columnProps(columnProps) {
113
+ this.field.columnProps = columnProps;
114
+ return this;
115
+ }
116
+ }
117
+ export function field() {
118
+ return new Proxy(new BaseFieldBuilder(), {
119
+ get(target, prop) {
120
+ switch (prop) {
121
+ case 'options':
122
+ return SelectFieldBuilder.prototype.options;
123
+ case 'showTime':
124
+ return DateFieldBuilder.prototype.showTime;
125
+ case 'render':
126
+ return CustomFieldBuilder.prototype.render;
127
+ case 'defaultExpanded':
128
+ return FieldArrayOrSectionFieldBuilder.prototype.defaultExpanded;
129
+ case 'fields': {
130
+ const fieldType = target.field.type;
131
+ if (fieldType === 'column') {
132
+ return ColumnFieldBuilder.prototype.fields;
133
+ }
134
+ return FieldArrayOrSectionFieldBuilder.prototype.fields;
135
+ }
136
+ case 'collapsible':
137
+ return SectionFieldBuilder.prototype.collapsible;
138
+ case 'columnFields':
139
+ return RowFieldBuilder.prototype.columnFields;
140
+ case 'rowProps':
141
+ return RowFieldBuilder.prototype.rowProps;
142
+ case 'columnProps':
143
+ return ColumnFieldBuilder.prototype.columnProps;
144
+ default:
145
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
+ return target[prop];
147
+ }
148
+ }
149
+ });
150
+ }
@@ -0,0 +1,2 @@
1
+ export declare const i18n: import("@akinon/akilocale").AkilocaleInstance;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/i18n/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI,+CAOf,CAAC"}