@akinon/akiform-builder 1.0.0 → 1.0.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.
- 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
|
@@ -120,10 +120,54 @@ describe('FieldBuilder', () => {
|
|
|
120
120
|
render: renderFn
|
|
121
121
|
});
|
|
122
122
|
});
|
|
123
|
+
it('should build row and col fields', () => {
|
|
124
|
+
const customField = (0, field_builder_1.field)()
|
|
125
|
+
.type('row')
|
|
126
|
+
.key('mainrow')
|
|
127
|
+
.rowProps({
|
|
128
|
+
align: 'middle'
|
|
129
|
+
})
|
|
130
|
+
.columnFields([
|
|
131
|
+
(0, field_builder_1.field)()
|
|
132
|
+
.type('column')
|
|
133
|
+
.key('col1')
|
|
134
|
+
.columnProps({
|
|
135
|
+
span: 24
|
|
136
|
+
})
|
|
137
|
+
.fields([
|
|
138
|
+
(0, field_builder_1.field)().type('text').key('test1').label('Text label').build()
|
|
139
|
+
])
|
|
140
|
+
.build()
|
|
141
|
+
])
|
|
142
|
+
.build();
|
|
143
|
+
expect(customField).toEqual({
|
|
144
|
+
type: 'row',
|
|
145
|
+
key: 'mainrow',
|
|
146
|
+
rowProps: {
|
|
147
|
+
align: 'middle'
|
|
148
|
+
},
|
|
149
|
+
columnFields: [
|
|
150
|
+
{
|
|
151
|
+
type: 'column',
|
|
152
|
+
key: 'col1',
|
|
153
|
+
columnProps: {
|
|
154
|
+
span: 24
|
|
155
|
+
},
|
|
156
|
+
fields: [
|
|
157
|
+
{
|
|
158
|
+
type: 'text',
|
|
159
|
+
key: 'test1',
|
|
160
|
+
label: 'Text label'
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
});
|
|
166
|
+
});
|
|
123
167
|
it('should throw an error if required properties are missing', () => {
|
|
124
|
-
expect(() => (0, field_builder_1.field)().build()).toThrow('Field must have at least a key
|
|
125
|
-
expect(() => (0, field_builder_1.field)().key('test').build()).toThrow('Field must have at least a key
|
|
126
|
-
expect(() => (0, field_builder_1.field)().
|
|
168
|
+
expect(() => (0, field_builder_1.field)().build()).toThrow('Field must have at least a key and type');
|
|
169
|
+
expect(() => (0, field_builder_1.field)().key('test').build()).toThrow('Field must have at least a key and type');
|
|
170
|
+
expect(() => (0, field_builder_1.field)().type('text').build()).toThrow('Field must have at least a key and type');
|
|
127
171
|
});
|
|
128
172
|
it('should only allow options for select fields', () => {
|
|
129
173
|
const selectField = (0, field_builder_1.field)()
|
|
@@ -238,6 +282,7 @@ describe('FieldBuilder', () => {
|
|
|
238
282
|
.key('name')
|
|
239
283
|
.label('Name')
|
|
240
284
|
.type('text')
|
|
285
|
+
// @ts-expect-error : We are explicitly waiting .fields to throw an error.
|
|
241
286
|
.fields([(0, field_builder_1.field)().key('invalid').label('Invalid').type('text').build()])
|
|
242
287
|
.build();
|
|
243
288
|
expect(textField).toEqual({
|
package/dist/cjs/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"}
|
|
@@ -15,35 +15,120 @@ exports.AkiformBuilder = exports.THROTTLE_DELAY = void 0;
|
|
|
15
15
|
require("./index.css");
|
|
16
16
|
const akiform_1 = require("@akinon/akiform");
|
|
17
17
|
const akival_1 = require("@akinon/akival");
|
|
18
|
+
const icons_1 = require("@akinon/icons");
|
|
18
19
|
const ui_button_1 = require("@akinon/ui-button");
|
|
19
20
|
const ui_checkbox_1 = require("@akinon/ui-checkbox");
|
|
20
21
|
const ui_collapse_1 = require("@akinon/ui-collapse");
|
|
21
22
|
const ui_date_picker_1 = require("@akinon/ui-date-picker");
|
|
23
|
+
const ui_divider_1 = require("@akinon/ui-divider");
|
|
22
24
|
const ui_input_1 = require("@akinon/ui-input");
|
|
23
25
|
const ui_input_number_1 = require("@akinon/ui-input-number");
|
|
26
|
+
const ui_layout_1 = require("@akinon/ui-layout");
|
|
24
27
|
const ui_select_1 = require("@akinon/ui-select");
|
|
25
|
-
const ui_space_1 = require("@akinon/ui-space");
|
|
26
28
|
const ui_typography_1 = require("@akinon/ui-typography");
|
|
29
|
+
const clsx_1 = require("clsx");
|
|
27
30
|
const react_1 = require("react");
|
|
28
31
|
const i18n_1 = require("./i18n");
|
|
29
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
|
+
};
|
|
30
47
|
const SectionComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
+
});
|
|
47
132
|
};
|
|
48
133
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
134
|
const renderField = (field, control, formValues,
|
|
@@ -63,7 +148,7 @@ formState, layout, layoutOptions) => {
|
|
|
63
148
|
case 'checkbox':
|
|
64
149
|
return (react_1.default.createElement(ui_checkbox_1.Checkbox, Object.assign({ checked: formValues[field.key] }, commonProps), field.label));
|
|
65
150
|
case 'date':
|
|
66
|
-
return (react_1.default.createElement(ui_date_picker_1.DatePicker, Object.assign({ placeholder: field.placeholder,
|
|
151
|
+
return (react_1.default.createElement(ui_date_picker_1.DatePicker, Object.assign({ placeholder: field.placeholder, showTime: field.showTime }, commonProps)));
|
|
67
152
|
case 'textarea':
|
|
68
153
|
return react_1.default.createElement(ui_input_1.InputTextArea, Object.assign({ placeholder: field.placeholder }, commonProps));
|
|
69
154
|
case 'fieldArray':
|
|
@@ -76,13 +161,32 @@ formState, layout, layoutOptions) => {
|
|
|
76
161
|
return react_1.default.createElement(react_1.Fragment, null);
|
|
77
162
|
case 'section':
|
|
78
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 }));
|
|
79
168
|
default:
|
|
80
169
|
return react_1.default.createElement(react_1.Fragment, null);
|
|
81
170
|
}
|
|
82
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
|
+
};
|
|
83
187
|
exports.AkiformBuilder = (0, react_1.forwardRef)((_a, ref) => {
|
|
84
188
|
var _b, _c;
|
|
85
|
-
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"]);
|
|
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"]);
|
|
86
190
|
const validationSchema = (0, react_1.useMemo)(() => {
|
|
87
191
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
192
|
const schema = {};
|
|
@@ -112,6 +216,8 @@ exports.AkiformBuilder = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
112
216
|
const prevFormValuesRef = (0, react_1.useRef)(null);
|
|
113
217
|
const isInitialRenderRef = (0, react_1.useRef)(true);
|
|
114
218
|
const throttleTimeoutRef = (0, react_1.useRef)(null);
|
|
219
|
+
const hasSubmitButton = !!onSubmit;
|
|
220
|
+
const hasFormActions = hasSubmitButton || showResetButton;
|
|
115
221
|
const handleValueChange = (0, react_1.useCallback)((values) => {
|
|
116
222
|
if (!controlled) {
|
|
117
223
|
if (throttleTimeoutRef.current) {
|
|
@@ -217,47 +323,78 @@ exports.AkiformBuilder = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
217
323
|
}
|
|
218
324
|
}
|
|
219
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
|
+
};
|
|
220
355
|
return (react_1.default.createElement("div", { className: "akiform-builder" },
|
|
221
|
-
react_1.default.createElement(akiform_1.Akiform, Object.assign({ onFinish: handleSubmit(onSubmit), onReset: handleReset, layout: layout }, formItemLayout, rest, { "data-testid": "akiform-builder", role: "form", "aria-label": i18n_1.i18n.t('formLabel'), requiredMark: true }),
|
|
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 }),
|
|
222
357
|
fields.map(field => {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const isVisible = typeof ((_c = field.config) === null || _c === void 0 ? void 0 : _c.visible) === 'function'
|
|
228
|
-
? field.config.visible(formValues)
|
|
229
|
-
: ((_d = field.config) === null || _d === void 0 ? void 0 : _d.visible) !== false;
|
|
358
|
+
const isVisible = checkIsVisible({
|
|
359
|
+
field,
|
|
360
|
+
formValues
|
|
361
|
+
});
|
|
230
362
|
if (!isVisible) {
|
|
231
363
|
return null;
|
|
232
364
|
}
|
|
233
|
-
|
|
234
|
-
|
|
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
|
+
});
|
|
235
384
|
}
|
|
236
|
-
if (field.type === 'fieldArray') {
|
|
237
|
-
return (react_1.default.createElement("div", { className: "akiform-builder-field-array", key: field.key },
|
|
238
|
-
react_1.default.createElement(ui_typography_1.Title, { level: 5 }, field.label),
|
|
239
|
-
renderField(field, control, formValues, formState, layout, layoutOptions)));
|
|
240
|
-
}
|
|
241
|
-
return (react_1.default.createElement(akiform_1.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)));
|
|
242
385
|
}),
|
|
243
|
-
react_1.default.createElement(akiform_1.FormItem, { control: control, name: 'form_actions', wrapperCol: layout === 'horizontal'
|
|
386
|
+
hasFormActions && (react_1.default.createElement(akiform_1.FormItem, { control: control, name: 'form_actions', wrapperCol: layout === 'horizontal'
|
|
244
387
|
? {
|
|
245
388
|
offset: (_b = formItemLayout.labelCol) === null || _b === void 0 ? void 0 : _b.span,
|
|
246
389
|
span: (_c = formItemLayout.wrapperCol) === null || _c === void 0 ? void 0 : _c.span
|
|
247
390
|
}
|
|
248
|
-
: undefined },
|
|
249
|
-
react_1.default.createElement(ui_space_1.Space, null,
|
|
250
|
-
react_1.default.createElement(ui_button_1.Button, { type: "primary", htmlType: "submit" }, i18n_1.i18n.t('submit')),
|
|
251
|
-
showResetButton && (react_1.default.createElement(ui_button_1.Button
|
|
252
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
253
|
-
, {
|
|
254
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
255
|
-
onClick: handleReset, type: "default", htmlType: "reset" }, i18n_1.i18n.t('reset'))))))));
|
|
391
|
+
: undefined }, renderFormActions())))));
|
|
256
392
|
});
|
|
257
393
|
exports.AkiformBuilder.displayName = 'AkiformBuilder';
|
|
258
394
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
259
395
|
const FieldArrayComponent = ({ field, control, formValues, formState, layout, layoutOptions }) => {
|
|
260
|
-
const {
|
|
396
|
+
const { errors } = formState;
|
|
397
|
+
const { fields, append, remove, insert } = (0, akiform_1.useFieldArray)({
|
|
261
398
|
control,
|
|
262
399
|
name: field.key
|
|
263
400
|
});
|
|
@@ -270,22 +407,52 @@ const FieldArrayComponent = ({ field, control, formValues, formState, layout, la
|
|
|
270
407
|
{});
|
|
271
408
|
};
|
|
272
409
|
return (react_1.default.createElement("div", { role: "group", "aria-labelledby": `${field.key}-label` },
|
|
273
|
-
react_1.default.createElement("div", {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
+
})));
|
|
291
458
|
};
|
|
@@ -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":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAGL,WAAW,EACX,SAAS,EACT,SAAS,EAGV,MAAM,SAAS,CAAC;AAEjB,KAAK,kBAAkB,CACrB,CAAC,SAAS,SAAS,EACnB,YAAY,SAAS,WAAW,GAAG,WAAW,IAC5C,CAAC,SAAS,QAAQ,GAClB,kBAAkB,CAAC,YAAY,CAAC,GAChC,CAAC,SAAS,MAAM,GACd,gBAAgB,CAAC,YAAY,CAAC,GAC9B,CAAC,SAAS,QAAQ,GAChB,kBAAkB,CAAC,YAAY,CAAC,GAChC,CAAC,SAAS,SAAS,GACjB,mBAAmB,CAAC,YAAY,CAAC,GACjC,CAAC,SAAS,YAAY,GACpB,+BAA+B,CAAC,YAAY,CAAC,GAC7C,CAAC,SAAS,KAAK,GACb,eAAe,CAAC,YAAY,CAAC,GAC7B,CAAC,SAAS,QAAQ,GAChB,kBAAkB,CAAC,YAAY,CAAC,GAChC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAE/C,cAAM,gBAAgB,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW;IACnE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAM;IAE7C,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,YAAY,CAAC,GAAG,IAAI;IAKvC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,EAAE,YAAY,CAAC;IAKvE,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMtC,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAK9B,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAKnC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,IAAI;IAM/C,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAKlD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAKhD,KAAK,IAAI,SAAS,CAAC,YAAY,CAAC;CAMjC;AAED,cAAM,kBAAkB,CACtB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;CAKzE;AAED,cAAM,gBAAgB,CACpB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;CAKlC;AAED,cAAM,kBAAkB,CACtB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,MAAM,CACJ,QAAQ,EAAE,CAAC,KAAK,EAAE;QAChB,KAAK,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QAC/B,UAAU,EAAE,YAAY,CAAC;QAEzB,OAAO,EAAE,GAAG,CAAC;KACd,KAAK,KAAK,CAAC,YAAY,GACvB,IAAI;CAKR;AAED,cAAM,+BAA+B,CACnC,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAKxC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI;CAYhD;AAED,cAAM,mBAAmB,CACvB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,+BAA+B,CAAC,YAAY,CAAC;IACrD,WAAW,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI;CAIxC;AAED,cAAM,eAAe,CACnB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI;IAM3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAInC;AAED,cAAM,kBAAkB,CACtB,YAAY,SAAS,WAAW,GAAG,WAAW,CAC9C,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IACtC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI;IAK/C,WAAW,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI;CAIzC;AAED,wBAAgB,KAAK,CACnB,YAAY,SAAS,WAAW,GAAG,WAAW,KAC3C,gBAAgB,CAAC,YAAY,CAAC,GACjC,kBAAkB,CAAC,YAAY,CAAC,GAChC,gBAAgB,CAAC,YAAY,CAAC,GAC9B,kBAAkB,CAAC,YAAY,CAAC,GAChC,mBAAmB,CAAC,YAAY,CAAC,GACjC,+BAA+B,CAAC,YAAY,CAAC,CAyC9C"}
|