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