@akinon/akiform-builder 1.0.0 → 1.0.2
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/dist/cjs/__tests__/akiform-builder.test.js +257 -83
- package/dist/cjs/__tests__/field-builder.test.js +48 -3
- package/dist/cjs/index.css +10 -0
- package/dist/cjs/src/akiform-builder.d.ts.map +1 -1
- package/dist/cjs/src/akiform-builder.js +230 -63
- package/dist/cjs/src/field-builder.d.ts +22 -5
- package/dist/cjs/src/field-builder.d.ts.map +1 -1
- package/dist/cjs/src/field-builder.js +81 -22
- package/dist/cjs/src/i18n/translations/en.d.ts +7 -0
- package/dist/cjs/src/i18n/translations/en.d.ts.map +1 -1
- package/dist/cjs/src/i18n/translations/en.js +8 -1
- package/dist/cjs/src/i18n/translations/tr.d.ts +7 -0
- package/dist/cjs/src/i18n/translations/tr.d.ts.map +1 -1
- package/dist/cjs/src/i18n/translations/tr.js +8 -1
- package/dist/cjs/src/types.d.ts +27 -5
- package/dist/cjs/src/types.d.ts.map +1 -1
- package/dist/esm/__tests__/akiform-builder.test.js +257 -83
- package/dist/esm/__tests__/field-builder.test.js +48 -3
- package/dist/esm/index.css +10 -0
- package/dist/esm/src/akiform-builder.d.ts.map +1 -1
- package/dist/esm/src/akiform-builder.js +231 -64
- package/dist/esm/src/field-builder.d.ts +22 -5
- package/dist/esm/src/field-builder.d.ts.map +1 -1
- package/dist/esm/src/field-builder.js +81 -22
- package/dist/esm/src/i18n/translations/en.d.ts +7 -0
- package/dist/esm/src/i18n/translations/en.d.ts.map +1 -1
- package/dist/esm/src/i18n/translations/en.js +8 -1
- package/dist/esm/src/i18n/translations/tr.d.ts +7 -0
- package/dist/esm/src/i18n/translations/tr.d.ts.map +1 -1
- package/dist/esm/src/i18n/translations/tr.js +8 -1
- package/dist/esm/src/types.d.ts +27 -5
- package/dist/esm/src/types.d.ts.map +1 -1
- package/package.json +19 -16
|
@@ -118,10 +118,54 @@ describe('FieldBuilder', () => {
|
|
|
118
118
|
render: renderFn
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
|
+
it('should build row and col fields', () => {
|
|
122
|
+
const customField = field()
|
|
123
|
+
.type('row')
|
|
124
|
+
.key('mainrow')
|
|
125
|
+
.rowProps({
|
|
126
|
+
align: 'middle'
|
|
127
|
+
})
|
|
128
|
+
.columnFields([
|
|
129
|
+
field()
|
|
130
|
+
.type('column')
|
|
131
|
+
.key('col1')
|
|
132
|
+
.columnProps({
|
|
133
|
+
span: 24
|
|
134
|
+
})
|
|
135
|
+
.fields([
|
|
136
|
+
field().type('text').key('test1').label('Text label').build()
|
|
137
|
+
])
|
|
138
|
+
.build()
|
|
139
|
+
])
|
|
140
|
+
.build();
|
|
141
|
+
expect(customField).toEqual({
|
|
142
|
+
type: 'row',
|
|
143
|
+
key: 'mainrow',
|
|
144
|
+
rowProps: {
|
|
145
|
+
align: 'middle'
|
|
146
|
+
},
|
|
147
|
+
columnFields: [
|
|
148
|
+
{
|
|
149
|
+
type: 'column',
|
|
150
|
+
key: 'col1',
|
|
151
|
+
columnProps: {
|
|
152
|
+
span: 24
|
|
153
|
+
},
|
|
154
|
+
fields: [
|
|
155
|
+
{
|
|
156
|
+
type: 'text',
|
|
157
|
+
key: 'test1',
|
|
158
|
+
label: 'Text label'
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
});
|
|
121
165
|
it('should throw an error if required properties are missing', () => {
|
|
122
|
-
expect(() => field().build()).toThrow('Field must have at least a key
|
|
123
|
-
expect(() => field().key('test').build()).toThrow('Field must have at least a key
|
|
124
|
-
expect(() => field().
|
|
166
|
+
expect(() => field().build()).toThrow('Field must have at least a key and type');
|
|
167
|
+
expect(() => field().key('test').build()).toThrow('Field must have at least a key and type');
|
|
168
|
+
expect(() => field().type('text').build()).toThrow('Field must have at least a key and type');
|
|
125
169
|
});
|
|
126
170
|
it('should only allow options for select fields', () => {
|
|
127
171
|
const selectField = field()
|
|
@@ -236,6 +280,7 @@ describe('FieldBuilder', () => {
|
|
|
236
280
|
.key('name')
|
|
237
281
|
.label('Name')
|
|
238
282
|
.type('text')
|
|
283
|
+
// @ts-expect-error : We are explicitly waiting .fields to throw an error.
|
|
239
284
|
.fields([field().key('invalid').label('Invalid').type('text').build()])
|
|
240
285
|
.build();
|
|
241
286
|
expect(textField).toEqual({
|
package/dist/esm/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"akiform-builder.d.ts","sourceRoot":"","sources":["../../../src/akiform-builder.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,OAAO,
|
|
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,EACL,mBAAmB,EACnB,iBAAiB,EAQlB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,cAAc,MAAM,CAAC;AA6WlC,eAAO,MAAM,cAAc,yHA+V1B,CAAC"}
|
|
@@ -12,35 +12,120 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import './index.css';
|
|
13
13
|
import { Akiform, akivalResolver, FormItem, useFieldArray, useForm, useWatch } from '@akinon/akiform';
|
|
14
14
|
import { akival } from '@akinon/akival';
|
|
15
|
+
import { Icon } from '@akinon/icons';
|
|
15
16
|
import { Button } from '@akinon/ui-button';
|
|
16
17
|
import { Checkbox } from '@akinon/ui-checkbox';
|
|
17
18
|
import { Collapse } from '@akinon/ui-collapse';
|
|
18
19
|
import { DatePicker } from '@akinon/ui-date-picker';
|
|
20
|
+
import { Divider } from '@akinon/ui-divider';
|
|
19
21
|
import { Input, InputTextArea } from '@akinon/ui-input';
|
|
20
22
|
import { InputNumber } from '@akinon/ui-input-number';
|
|
23
|
+
import { Col, Row } from '@akinon/ui-layout';
|
|
21
24
|
import { Select } from '@akinon/ui-select';
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
25
|
+
import { Text } from '@akinon/ui-typography';
|
|
26
|
+
import clsx from 'clsx';
|
|
24
27
|
import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
25
28
|
import { i18n } from './i18n';
|
|
26
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
|
+
};
|
|
27
44
|
const SectionComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
});
|
|
44
129
|
};
|
|
45
130
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
131
|
const renderField = (field, control, formValues,
|
|
@@ -60,7 +145,7 @@ formState, layout, layoutOptions) => {
|
|
|
60
145
|
case 'checkbox':
|
|
61
146
|
return (React.createElement(Checkbox, Object.assign({ checked: formValues[field.key] }, commonProps), field.label));
|
|
62
147
|
case 'date':
|
|
63
|
-
return (React.createElement(DatePicker, Object.assign({ placeholder: field.placeholder,
|
|
148
|
+
return (React.createElement(DatePicker, Object.assign({ placeholder: field.placeholder, showTime: field.showTime }, commonProps)));
|
|
64
149
|
case 'textarea':
|
|
65
150
|
return React.createElement(InputTextArea, Object.assign({ placeholder: field.placeholder }, commonProps));
|
|
66
151
|
case 'fieldArray':
|
|
@@ -73,13 +158,32 @@ formState, layout, layoutOptions) => {
|
|
|
73
158
|
return React.createElement(Fragment, null);
|
|
74
159
|
case 'section':
|
|
75
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 }));
|
|
76
165
|
default:
|
|
77
166
|
return React.createElement(Fragment, null);
|
|
78
167
|
}
|
|
79
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
|
+
};
|
|
80
184
|
export const AkiformBuilder = forwardRef((_a, ref) => {
|
|
81
185
|
var _b, _c;
|
|
82
|
-
var { fields, onSubmit, layout = 'vertical', layoutOptions, showResetButton = false, onReset, controlled = false, values, onValueChange } = _a, rest = __rest(_a, ["fields", "onSubmit", "layout", "layoutOptions", "showResetButton", "onReset", "controlled", "values", "onValueChange"]);
|
|
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"]);
|
|
83
187
|
const validationSchema = useMemo(() => {
|
|
84
188
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
189
|
const schema = {};
|
|
@@ -109,6 +213,8 @@ export const AkiformBuilder = forwardRef((_a, ref) => {
|
|
|
109
213
|
const prevFormValuesRef = useRef(null);
|
|
110
214
|
const isInitialRenderRef = useRef(true);
|
|
111
215
|
const throttleTimeoutRef = useRef(null);
|
|
216
|
+
const hasSubmitButton = !!onSubmit;
|
|
217
|
+
const hasFormActions = hasSubmitButton || showResetButton;
|
|
112
218
|
const handleValueChange = useCallback((values) => {
|
|
113
219
|
if (!controlled) {
|
|
114
220
|
if (throttleTimeoutRef.current) {
|
|
@@ -214,47 +320,78 @@ export const AkiformBuilder = forwardRef((_a, ref) => {
|
|
|
214
320
|
}
|
|
215
321
|
}
|
|
216
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
|
+
};
|
|
217
352
|
return (React.createElement("div", { className: "akiform-builder" },
|
|
218
|
-
React.createElement(Akiform, Object.assign({ onFinish: handleSubmit(onSubmit), onReset: handleReset, layout: layout }, formItemLayout, rest, { "data-testid": "akiform-builder", role: "form", "aria-label": i18n.t('formLabel'), requiredMark: true }),
|
|
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 }),
|
|
219
354
|
fields.map(field => {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const isVisible = typeof ((_c = field.config) === null || _c === void 0 ? void 0 : _c.visible) === 'function'
|
|
225
|
-
? field.config.visible(formValues)
|
|
226
|
-
: ((_d = field.config) === null || _d === void 0 ? void 0 : _d.visible) !== false;
|
|
355
|
+
const isVisible = checkIsVisible({
|
|
356
|
+
field,
|
|
357
|
+
formValues
|
|
358
|
+
});
|
|
227
359
|
if (!isVisible) {
|
|
228
360
|
return null;
|
|
229
361
|
}
|
|
230
|
-
|
|
231
|
-
|
|
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
|
+
});
|
|
232
381
|
}
|
|
233
|
-
if (field.type === 'fieldArray') {
|
|
234
|
-
return (React.createElement("div", { className: "akiform-builder-field-array", key: field.key },
|
|
235
|
-
React.createElement(Title, { level: 5 }, field.label),
|
|
236
|
-
renderField(field, control, formValues, formState, layout, layoutOptions)));
|
|
237
|
-
}
|
|
238
|
-
return (React.createElement(FormItem, { key: field.key, control: control, name: field.key, label: field.label, disabled: isDisabled, required: field.validation ? true : false, tooltip: field.tooltip }, renderField(field, control, formValues, formState, layout, layoutOptions)));
|
|
239
382
|
}),
|
|
240
|
-
React.createElement(FormItem, { control: control, name: 'form_actions', wrapperCol: layout === 'horizontal'
|
|
383
|
+
hasFormActions && (React.createElement(FormItem, { control: control, name: 'form_actions', wrapperCol: layout === 'horizontal'
|
|
241
384
|
? {
|
|
242
385
|
offset: (_b = formItemLayout.labelCol) === null || _b === void 0 ? void 0 : _b.span,
|
|
243
386
|
span: (_c = formItemLayout.wrapperCol) === null || _c === void 0 ? void 0 : _c.span
|
|
244
387
|
}
|
|
245
|
-
: undefined },
|
|
246
|
-
React.createElement(Space, null,
|
|
247
|
-
React.createElement(Button, { type: "primary", htmlType: "submit" }, i18n.t('submit')),
|
|
248
|
-
showResetButton && (React.createElement(Button
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
250
|
-
, {
|
|
251
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
252
|
-
onClick: handleReset, type: "default", htmlType: "reset" }, i18n.t('reset'))))))));
|
|
388
|
+
: undefined }, renderFormActions())))));
|
|
253
389
|
});
|
|
254
390
|
AkiformBuilder.displayName = 'AkiformBuilder';
|
|
255
391
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
256
392
|
const FieldArrayComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
|
|
257
|
-
const {
|
|
393
|
+
const { errors } = formState;
|
|
394
|
+
const { fields, append, remove, insert } = useFieldArray({
|
|
258
395
|
control,
|
|
259
396
|
name: field.key
|
|
260
397
|
});
|
|
@@ -267,22 +404,52 @@ const FieldArrayComponent = ({ field, control, formValues, formState, layout, la
|
|
|
267
404
|
{});
|
|
268
405
|
};
|
|
269
406
|
return (React.createElement("div", { role: "group", "aria-labelledby": `${field.key}-label` },
|
|
270
|
-
React.createElement("div", {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
+
})));
|
|
288
455
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { FieldPath, FieldValues } from '@akinon/akiform';
|
|
2
2
|
import { AnySchema } from '@akinon/akival';
|
|
3
|
+
import { ColProps, RowProps } from '@akinon/ui-layout';
|
|
3
4
|
import { TooltipProps } from '@akinon/ui-tooltip';
|
|
4
5
|
import { FieldConfig, FieldType, FormField } from './types';
|
|
5
|
-
type FieldTypeToBuilder<T extends FieldType, TFieldValues extends FieldValues = FieldValues> = T extends 'select' ? SelectFieldBuilder<TFieldValues> : T extends 'custom' ? CustomFieldBuilder<TFieldValues> : T extends 'section' ? SectionFieldBuilder<TFieldValues> : BaseFieldBuilder<TFieldValues>;
|
|
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>;
|
|
6
7
|
declare class BaseFieldBuilder<TFieldValues extends FieldValues = FieldValues> {
|
|
7
|
-
|
|
8
|
+
field: Partial<FormField<TFieldValues>>;
|
|
8
9
|
key(key: FieldPath<TFieldValues>): this;
|
|
9
10
|
label(label: string): this;
|
|
10
11
|
type<T extends FieldType>(type: T): FieldTypeToBuilder<T, TFieldValues>;
|
|
@@ -12,8 +13,9 @@ declare class BaseFieldBuilder<TFieldValues extends FieldValues = FieldValues> {
|
|
|
12
13
|
defaultValue(value: any): this;
|
|
13
14
|
validation(schema: AnySchema): this;
|
|
14
15
|
config(config: FieldConfig<TFieldValues>): this;
|
|
15
|
-
fields(fields: FormField<TFieldValues>[]): this;
|
|
16
16
|
tooltip(tooltipProps: TooltipProps | string): this;
|
|
17
|
+
help(help: string): this;
|
|
18
|
+
labelDescription(labelDescription: string): this;
|
|
17
19
|
build(): FormField<TFieldValues>;
|
|
18
20
|
}
|
|
19
21
|
declare class SelectFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
|
|
@@ -22,6 +24,9 @@ declare class SelectFieldBuilder<TFieldValues extends FieldValues = FieldValues>
|
|
|
22
24
|
label: string;
|
|
23
25
|
}>): this;
|
|
24
26
|
}
|
|
27
|
+
declare class DateFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
|
|
28
|
+
showTime(showTime: boolean): this;
|
|
29
|
+
}
|
|
25
30
|
declare class CustomFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
|
|
26
31
|
render(renderFn: (props: {
|
|
27
32
|
field: FormField<TFieldValues>;
|
|
@@ -29,9 +34,21 @@ declare class CustomFieldBuilder<TFieldValues extends FieldValues = FieldValues>
|
|
|
29
34
|
control: any;
|
|
30
35
|
}) => React.ReactElement): this;
|
|
31
36
|
}
|
|
32
|
-
declare class
|
|
37
|
+
declare class FieldArrayOrSectionFieldBuilder<TFieldValues extends FieldValues = FieldValues> extends BaseFieldBuilder<TFieldValues> {
|
|
33
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;
|
|
34
51
|
}
|
|
35
|
-
export declare function field<TFieldValues extends FieldValues = FieldValues>(): BaseFieldBuilder<TFieldValues> & SelectFieldBuilder<TFieldValues> & CustomFieldBuilder<TFieldValues> & SectionFieldBuilder<TFieldValues>;
|
|
52
|
+
export declare function field<TFieldValues extends FieldValues = FieldValues>(): BaseFieldBuilder<TFieldValues> & SelectFieldBuilder<TFieldValues> & DateFieldBuilder<TFieldValues> & CustomFieldBuilder<TFieldValues> & SectionFieldBuilder<TFieldValues> & FieldArrayOrSectionFieldBuilder<TFieldValues>;
|
|
36
53
|
export {};
|
|
37
54
|
//# sourceMappingURL=field-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-builder.d.ts","sourceRoot":"","sources":["../../../src/field-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,
|
|
1
|
+
{"version":3,"file":"field-builder.d.ts","sourceRoot":"","sources":["../../../src/field-builder.ts"],"names":[],"mappings":"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"}
|