autoforma 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.
Files changed (110) hide show
  1. package/dist/index.cjs.js +70 -0
  2. package/dist/index.es.js +13532 -0
  3. package/dist/src/components/AutoForm.d.ts +18 -0
  4. package/dist/src/components/FieldRender.d.ts +16 -0
  5. package/dist/src/components/fields/ArrayField.d.ts +13 -0
  6. package/dist/src/components/fields/CheckField.d.ts +7 -0
  7. package/dist/src/components/fields/DateField.d.ts +6 -0
  8. package/dist/src/components/fields/DateTimeField.d.ts +6 -0
  9. package/dist/src/components/fields/NumberField.d.ts +6 -0
  10. package/dist/src/components/fields/ObjectField.d.ts +9 -0
  11. package/dist/src/components/fields/SelectField.d.ts +10 -0
  12. package/dist/src/components/fields/TextAreaField.d.ts +6 -0
  13. package/dist/src/components/fields/TextField.d.ts +6 -0
  14. package/dist/src/components/fields/TimeField.d.ts +6 -0
  15. package/{src/index.ts → dist/src/index.d.ts} +2 -3
  16. package/dist/src/stories/AutoForm.stories.d.ts +9 -0
  17. package/dist/src/stories/Fields.stories.d.ts +12 -0
  18. package/dist/src/theme.d.ts +141 -0
  19. package/dist/src/types/custom-render.d.ts +11 -0
  20. package/dist/src/types/field.d.ts +30 -0
  21. package/dist/src/types/form.d.ts +7 -0
  22. package/{test-utils/index.ts → dist/test-utils/index.d.ts} +1 -2
  23. package/dist/test-utils/render.d.ts +1 -0
  24. package/package.json +9 -3
  25. package/.github/workflows/npm_test.yml +0 -27
  26. package/.nvmrc +0 -1
  27. package/.prettierrc.mjs +0 -35
  28. package/.storybook/main.ts +0 -17
  29. package/.storybook/preview.tsx +0 -18
  30. package/.storybook/vitest.setup.ts +0 -9
  31. package/.stylelintignore +0 -1
  32. package/.stylelintrc.json +0 -28
  33. package/.yarn/releases/yarn-4.9.1.cjs +0 -948
  34. package/.yarnrc.yml +0 -3
  35. package/eslint.config.js +0 -11
  36. package/index.html +0 -16
  37. package/postcss.config.cjs +0 -14
  38. package/src/favicon.svg +0 -1
  39. package/src/stories/AutoForm.stories.tsx +0 -473
  40. package/src/stories/Fields.stories.tsx +0 -190
  41. package/src/theme.ts +0 -5
  42. package/src/vite-env.d.ts +0 -1
  43. package/storybook-static/assets/AutoForm-CEr4m2za.js +0 -53
  44. package/storybook-static/assets/AutoForm.stories-CtOmRKOV.js +0 -164
  45. package/storybook-static/assets/Color-YHDXOIA2-pc5-Ao7n.js +0 -1
  46. package/storybook-static/assets/DocsRenderer-CFRXHY34-D-_1VvMG.js +0 -575
  47. package/storybook-static/assets/Fields.stories-CoRkpMbJ.js +0 -29
  48. package/storybook-static/assets/chunk-XP5HYGXS-BpfKkqn7.js +0 -1
  49. package/storybook-static/assets/entry-preview-CkHoqRUh.js +0 -2
  50. package/storybook-static/assets/entry-preview-docs-hFR7sEJd.js +0 -46
  51. package/storybook-static/assets/get-contrast-color-Db6nT3bs.js +0 -1
  52. package/storybook-static/assets/iframe-CzpwBD2i.js +0 -211
  53. package/storybook-static/assets/index-B8rYRX2K.js +0 -1
  54. package/storybook-static/assets/index-BQQLSK9g.js +0 -1
  55. package/storybook-static/assets/index-CXQShRbs.js +0 -8
  56. package/storybook-static/assets/index-D4lIrffr.js +0 -9
  57. package/storybook-static/assets/index-Domkg0jQ.js +0 -240
  58. package/storybook-static/assets/index-DrFu-skq.js +0 -6
  59. package/storybook-static/assets/index-DsJinFGm.js +0 -9
  60. package/storybook-static/assets/jsx-runtime-D_zvdyIk.js +0 -9
  61. package/storybook-static/assets/preview-B8lJiyuQ.js +0 -34
  62. package/storybook-static/assets/preview-BBWR9nbA.js +0 -1
  63. package/storybook-static/assets/preview-BOfrPh1e.js +0 -2
  64. package/storybook-static/assets/preview-BWzBA1C2.js +0 -396
  65. package/storybook-static/assets/preview-C2Qr78FS.js +0 -4
  66. package/storybook-static/assets/preview-CvbIS5ZJ.js +0 -1
  67. package/storybook-static/assets/preview-DD_OYowb.js +0 -1
  68. package/storybook-static/assets/preview-DGUiP6tS.js +0 -7
  69. package/storybook-static/assets/preview-DioFdWiE.css +0 -1
  70. package/storybook-static/assets/preview-Dyg8NwXV.js +0 -1
  71. package/storybook-static/assets/react-18-Dhjvimrl.js +0 -25
  72. package/storybook-static/assets/test-utils--_O2wM1y.js +0 -9
  73. package/storybook-static/favicon.svg +0 -1
  74. package/storybook-static/iframe.html +0 -666
  75. package/storybook-static/index.html +0 -181
  76. package/storybook-static/index.json +0 -1
  77. package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  78. package/storybook-static/nunito-sans-bold.woff2 +0 -0
  79. package/storybook-static/nunito-sans-italic.woff2 +0 -0
  80. package/storybook-static/nunito-sans-regular.woff2 +0 -0
  81. package/storybook-static/project.json +0 -1
  82. package/storybook-static/sb-addons/chromatic-com-storybook-9/manager-bundle.js +0 -331
  83. package/storybook-static/sb-addons/chromatic-com-storybook-9/manager-bundle.js.LEGAL.txt +0 -51
  84. package/storybook-static/sb-addons/docs-11/manager-bundle.js +0 -242
  85. package/storybook-static/sb-addons/essentials-actions-2/manager-bundle.js +0 -3
  86. package/storybook-static/sb-addons/essentials-backgrounds-3/manager-bundle.js +0 -12
  87. package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +0 -402
  88. package/storybook-static/sb-addons/essentials-measure-6/manager-bundle.js +0 -3
  89. package/storybook-static/sb-addons/essentials-outline-7/manager-bundle.js +0 -3
  90. package/storybook-static/sb-addons/essentials-toolbars-5/manager-bundle.js +0 -3
  91. package/storybook-static/sb-addons/essentials-viewport-4/manager-bundle.js +0 -3
  92. package/storybook-static/sb-addons/onboarding-8/manager-bundle.js +0 -127
  93. package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +0 -3
  94. package/storybook-static/sb-addons/storybook-experimental-addon-test-10/manager-bundle.js +0 -223
  95. package/storybook-static/sb-common-assets/favicon.svg +0 -1
  96. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  97. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  98. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  99. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  100. package/storybook-static/sb-manager/globals-module-info.js +0 -1051
  101. package/storybook-static/sb-manager/globals-runtime.js +0 -41591
  102. package/storybook-static/sb-manager/globals.js +0 -48
  103. package/storybook-static/sb-manager/runtime.js +0 -12048
  104. package/test-utils/render.tsx +0 -11
  105. package/text +0 -64
  106. package/tsconfig.json +0 -25
  107. package/vite.config.mjs +0 -19
  108. package/vitest.setup.mjs +0 -29
  109. package/vitest.shims.d.ts +0 -1
  110. package/vitest.workspace.js +0 -30
package/.yarnrc.yml DELETED
@@ -1,3 +0,0 @@
1
- nodeLinker: node-modules
2
-
3
- yarnPath: .yarn/releases/yarn-4.9.1.cjs
package/eslint.config.js DELETED
@@ -1,11 +0,0 @@
1
- import mantine from 'eslint-config-mantine';
2
- import tseslint from 'typescript-eslint';
3
-
4
- export default tseslint.config(
5
- ...mantine,
6
- { ignores: ['**/*.{mjs,cjs,js,d.ts,d.mts}', './.storybook/main.ts'] },
7
- {
8
- files: ['**/*.story.tsx'],
9
- rules: { 'no-console': 'off' },
10
- }
11
- );
package/index.html DELETED
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
6
- <meta
7
- name="viewport"
8
- content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
9
- />
10
- <title>Vite + Mantine App</title>
11
- </head>
12
- <body>
13
- <div id="root"></div>
14
- <script type="module" src="/src/main.tsx"></script>
15
- </body>
16
- </html>
@@ -1,14 +0,0 @@
1
- module.exports = {
2
- plugins: {
3
- 'postcss-preset-mantine': {},
4
- 'postcss-simple-vars': {
5
- variables: {
6
- 'mantine-breakpoint-xs': '36em',
7
- 'mantine-breakpoint-sm': '48em',
8
- 'mantine-breakpoint-md': '62em',
9
- 'mantine-breakpoint-lg': '75em',
10
- 'mantine-breakpoint-xl': '88em',
11
- },
12
- },
13
- },
14
- };
package/src/favicon.svg DELETED
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 163 163"><path fill="#339AF0" d="M162.162 81.5c0-45.011-36.301-81.5-81.08-81.5C36.301 0 0 36.489 0 81.5 0 126.51 36.301 163 81.081 163s81.081-36.49 81.081-81.5z"/><path fill="#fff" d="M65.983 43.049a6.234 6.234 0 00-.336 6.884 6.14 6.14 0 001.618 1.786c9.444 7.036 14.866 17.794 14.866 29.52 0 11.726-5.422 22.484-14.866 29.52a6.145 6.145 0 00-1.616 1.786 6.21 6.21 0 00-.694 4.693 6.21 6.21 0 001.028 2.186 6.151 6.151 0 006.457 2.319 6.154 6.154 0 002.177-1.035 50.083 50.083 0 007.947-7.39h17.493c3.406 0 6.174-2.772 6.174-6.194s-2.762-6.194-6.174-6.194h-9.655a49.165 49.165 0 004.071-19.69 49.167 49.167 0 00-4.07-19.692h9.66c3.406 0 6.173-2.771 6.173-6.194 0-3.422-2.762-6.193-6.173-6.193H82.574a50.112 50.112 0 00-7.952-7.397 6.15 6.15 0 00-4.578-1.153 6.189 6.189 0 00-4.055 2.438h-.006z"/><path fill="#fff" fill-rule="evenodd" d="M56.236 79.391a9.342 9.342 0 01.632-3.608 9.262 9.262 0 011.967-3.077 9.143 9.143 0 012.994-2.063 9.06 9.06 0 017.103 0 9.145 9.145 0 012.995 2.063 9.262 9.262 0 011.967 3.077 9.339 9.339 0 01-2.125 10.003 9.094 9.094 0 01-6.388 2.63 9.094 9.094 0 01-6.39-2.63 9.3 9.3 0 01-2.755-6.395z" clip-rule="evenodd"/></svg>
@@ -1,473 +0,0 @@
1
- import AutoForm from '@/components/AutoForm';
2
- import FieldRender, { getArrayOptions } from '@/components/FieldRender';
3
- import { CustomFieldRender } from '@/types/custom-render';
4
- import { FieldSchema } from '@/types/field';
5
- import { Accordion, Button, Grid, Group, Modal, Table, Text } from '@mantine/core';
6
- import { useDisclosure } from '@mantine/hooks';
7
- import type { Meta, StoryObj } from '@storybook/react';
8
-
9
- // ------------------------------
10
- // Schema Definitions
11
- // ------------------------------
12
-
13
- const schema: FieldSchema[] = [
14
- {
15
- type: 'check',
16
- label: 'Enabled',
17
- name: 'enabled',
18
- initialValue: true,
19
- },
20
- {
21
- type: 'object',
22
- name: 'personalInformation',
23
- label: 'Personal Information',
24
- fields: [
25
- {
26
- type: 'text',
27
- name: 'firstName',
28
- label: 'First Name',
29
- initialValue: 'Saji',
30
- },
31
- {
32
- type: 'text',
33
- name: 'lastName',
34
- label: 'Last Name',
35
- initialValue: 'Nael',
36
- },
37
- {
38
- type: 'select',
39
- name: 'gender',
40
- label: 'Gender',
41
- data: [
42
- { label: 'Male', value: 'male' },
43
- { label: 'Female', value: 'female' },
44
- ],
45
- initialValue: 'male',
46
- },
47
- ],
48
- },
49
- {
50
- type: 'object',
51
- name: 'accountInformation',
52
- label: 'Account Information',
53
- fields: [
54
- {
55
- type: 'text',
56
- name: 'username',
57
- label: 'Username',
58
- initialValue: 'saji-nael',
59
- },
60
- {
61
- type: 'text',
62
- name: 'email',
63
- label: 'Email',
64
- initialValue: 'saji.nael.98@gmail.com',
65
- },
66
- {
67
- type: 'date',
68
- name: 'dateOfJoin',
69
- label: 'Date Of Join',
70
- initialValue: new Date(),
71
- },
72
- ],
73
- },
74
- {
75
- type: 'object',
76
- name: 'contactInformation',
77
- label: 'Contact Information',
78
- fields: [
79
- {
80
- type: 'array',
81
- name: 'phones',
82
- label: 'Phones',
83
- fields: [
84
- {
85
- type: 'text',
86
- name: 'phoneNo',
87
- label: 'Phone NO',
88
- },
89
- ],
90
- },
91
- ],
92
- },
93
- ];
94
-
95
- const schemaWithValidation: FieldSchema[] = [
96
- ...schema.slice(0, 3),
97
- {
98
- ...schema[3],
99
- fields: [
100
- {
101
- ...schema[3].fields[0],
102
- required: true,
103
- },
104
- ],
105
- },
106
- ];
107
-
108
- // ------------------------------
109
- // Storybook Meta
110
- // ------------------------------
111
-
112
- const meta: Meta<typeof AutoForm> = {
113
- title: 'components/AutoForm',
114
- component: AutoForm,
115
- tags: ['autodocs'],
116
- args: {
117
- onSubmit: (values) => alert(JSON.stringify(values, null, 2)),
118
- schema,
119
- container: (form, onSubmit, readOnly) => (
120
- <>
121
- <Grid>{form}</Grid>
122
- {!readOnly && (
123
- <Group justify="flex-end">
124
- <Button onClick={onSubmit}>Submit</Button>
125
- </Group>
126
- )}
127
- </>
128
- ),
129
- fieldContainer: (field, fieldSchema) => (
130
- <Grid.Col span={{ base: 12, md: fieldSchema.type === 'object' ? 12 : 6 }}>{field}</Grid.Col>
131
- ),
132
- },
133
-
134
- argTypes: {
135
- values: {
136
- description: 'Initial form values. Useful for editing or setting default values.',
137
- control: false,
138
- },
139
- schema: {
140
- description:
141
- 'Array of field definitions used to render the form. Each item defines one input field.',
142
- control: false,
143
- },
144
- onSubmit: {
145
- description: 'Function called with form values when the form is submitted.',
146
- control: false,
147
- },
148
- container: {
149
- description:
150
- 'Function that receives the rendered form and the onSubmit handler. Used to wrap the form with layout and controls.',
151
- control: false,
152
- },
153
- fieldContainer: {
154
- description: 'Optional function to wrap each individual field with custom layout or styling.',
155
- control: false,
156
- },
157
- customRender: {
158
- description:
159
- 'Optional custom render function to override the default field rendering based on field type.',
160
- control: false,
161
- },
162
- validate: {
163
- description:
164
- 'Optional validation logic. Receives values and returns an object with field errors or nulls.',
165
- control: false,
166
- },
167
- readOnly: {
168
- description: 'If true, all fields will be rendered in read-only mode.',
169
- control: { type: 'boolean' },
170
- },
171
- onFieldChange: {
172
- description:
173
- 'Optional function triggered on field change. You can return modified values dynamically.',
174
- control: false,
175
- },
176
- },
177
- parameters: {
178
- docs: {
179
- description: {
180
- component: `
181
- ### 📄 AutoForm
182
-
183
- \`AutoForm\` is a dynamic, schema-driven form component designed for full control and customization.
184
-
185
- ---
186
-
187
- ### 🧩 AutoFormProps Overview
188
-
189
- | Prop | Type | Description |
190
- |------------------|----------------------------------------------------------------------|-------------|
191
- | \`schema\` | \`FieldSchema[]\` | Array of field definitions |
192
- | \`onSubmit\` | \`(values: Record<string, any>) => void\` | Called when form is submitted |
193
- | \`values\` | \`Record<string, any>\` | Initial values |
194
- | \`readOnly\` | \`true?\` | Makes the form non-editable |
195
- | \`validate\` | \`FormValidateInput<Record<string, any>>\` | Optional validation function |
196
- | \`onFieldChange\` | \`(name, value, values) => Record<string, any>\` | Callback when a field changes |
197
- | \`container\` | \`(formNode, onSubmit, readOnly) => React.ReactNode\` | Customize the outer layout of the form |
198
- | \`fieldContainer\` | \`(fieldNode, fieldSchema) => React.ReactNode\` | Customize how each field is rendered |
199
- | \`customRender\` | \`(field, value, error, onChange, values, options, readOnly) => JSX\` | Advanced per-field rendering |
200
-
201
- ---
202
-
203
- ### 🧱 Layout Customization
204
-
205
- #### 🔲 \`container\`
206
-
207
- Use the \`container\` prop to wrap the full form, including layout, submit buttons, etc.
208
-
209
- #### 🔳 \`fieldContainer\`
210
-
211
- With \`fieldContainer\`, you can wrap **each field** with your own layout:
212
-
213
- \`\`\`tsx
214
- fieldContainer: (field, fieldSchema) => (
215
- <Grid.Col span={{ base: 12, md: fieldSchema.type === 'object' ? 12 : 6 }}>
216
- {field}
217
- </Grid.Col>
218
- )
219
- \`\`\`
220
-
221
- This allows **full control per field** — spacing, layout, responsiveness, etc.
222
-
223
- ---
224
-
225
- ### 🧠 Advanced Rendering with \`customRender\`
226
-
227
- \`customRender\` gives you full control over how a field is rendered.
228
-
229
- #### 📦 Example
230
-
231
- \`\`\`tsx
232
- customRender: (field, objValue, error, onObjChange, formValues, options, readOnly) => {
233
- if (field.type === 'object') {
234
- return (
235
- <Accordion defaultValue={field.name}>
236
- <Accordion.Item value={field.name}>
237
- <Accordion.Control>{field.label}</Accordion.Control>
238
- <Accordion.Panel>
239
- <Grid>
240
- {field.fields?.map((childField) => {
241
- function onChange(name: string, value: any) {
242
- objValue[name] = value;
243
- onObjChange(field.name, objValue);
244
- }
245
-
246
- if (childField.name === 'phones') {
247
- return (
248
- <CustomPhoneList
249
- key={childField.name}
250
- field={childField}
251
- value={objValue[childField.name]}
252
- onChange={onChange}
253
- error={error}
254
- formValues={formValues}
255
- options={options}
256
- readOnly={readOnly}
257
- />
258
- );
259
- }
260
-
261
- return (
262
- <Grid.Col key={childField.name} span={6}>
263
- <FieldRender
264
- field={childField}
265
- formValues={formValues}
266
- value={objValue[childField.name]}
267
- onChange={onChange}
268
- readOnly={readOnly}
269
- />
270
- </Grid.Col>
271
- );
272
- })}
273
- </Grid>
274
- </Accordion.Panel>
275
- </Accordion.Item>
276
- </Accordion>
277
- );
278
- }
279
- return null;
280
- }
281
- \`\`\`
282
-
283
- You can use this to:
284
- - Nest fields inside custom layouts
285
- - Open modals, drawers, or complex editors
286
- - Show/hide fields dynamically
287
- - Render fields as fully custom components
288
-
289
- ---
290
- `,
291
- },
292
- },
293
- },
294
- };
295
-
296
- export default meta;
297
-
298
- // ------------------------------
299
- // Stories
300
- // ------------------------------
301
-
302
- type Story = StoryObj<typeof AutoForm>;
303
-
304
- export const Standard: Story = {};
305
-
306
- export const ReadOnly: Story = {
307
- args: { readOnly: true },
308
- };
309
-
310
- export const FormValidation: Story = {
311
- args: {
312
- schema: schemaWithValidation,
313
- validate: {
314
- contactInformation: {
315
- phones: {
316
- phoneNo: (value: string) => {
317
- const regex = /^(059|056)\d{7}$/;
318
- return regex.test(value)
319
- ? null
320
- : "Invalid phone number. It must be exactly 10 digits long and start with '059' or '056'.";
321
- },
322
- },
323
- },
324
- },
325
- },
326
- };
327
-
328
- export const CustomizedForm: Story = {
329
- args: {
330
- schema,
331
- customRender: (field, objValue, error, onObjChange, formValues, options, readOnly) => {
332
- if (field.type === 'object') {
333
- return (
334
- <Grid.Col span={12}>
335
- <Accordion defaultValue={field.name} variant="contained">
336
- <Accordion.Item value={field.name}>
337
- <Accordion.Control>{field.label}</Accordion.Control>
338
- <Accordion.Panel>
339
- <Grid>
340
- {field.fields?.map((field) => {
341
- const onChange = (name: string, value: any) => {
342
- objValue[name] = value;
343
- onObjChange(field.name, objValue);
344
- };
345
-
346
- if (field.name === 'phones') {
347
- return (
348
- <CustomPhoneList
349
- key={field.name}
350
- error={error}
351
- field={field}
352
- formValues={formValues}
353
- onChange={onChange}
354
- value={objValue[field.name]}
355
- options={options}
356
- readOnly={readOnly}
357
- />
358
- );
359
- }
360
-
361
- return (
362
- <Grid.Col
363
- key={field.name}
364
- span={{ base: 12, md: field.type === 'object' ? 12 : 6 }}
365
- >
366
- <FieldRender
367
- field={field}
368
- formValues={formValues}
369
- value={objValue[field.name]}
370
- error={undefined}
371
- readOnly={readOnly}
372
- onChange={onChange}
373
- />
374
- </Grid.Col>
375
- );
376
- })}
377
- </Grid>
378
- </Accordion.Panel>
379
- </Accordion.Item>
380
- </Accordion>
381
- </Grid.Col>
382
- );
383
- }
384
- return null;
385
- },
386
- },
387
- };
388
-
389
- // ------------------------------
390
- // Custom Field Renderer
391
- // ------------------------------
392
-
393
- const CustomPhoneList: React.FC<CustomFieldRender> = (props) => {
394
- const [visible, { open, close }] = useDisclosure(false);
395
- const { error, field, formValues, onChange, value, options, readOnly } = props;
396
-
397
- const arrayOptions = getArrayOptions(field.name, onChange, value);
398
-
399
- return (
400
- <>
401
- <FieldRender
402
- field={field}
403
- formValues={formValues}
404
- onChange={onChange}
405
- value={value}
406
- error={error}
407
- readOnly={readOnly}
408
- customRender={() => (
409
- <>
410
- <Modal title="Add Phone" onClose={close} opened={visible}>
411
- <AutoForm
412
- schema={field.fields as FieldSchema[]}
413
- fieldContainer={(field, fieldSchema) => (
414
- <Grid.Col span={{ base: 12, md: fieldSchema.type === 'object' ? 12 : 6 }}>
415
- {field}
416
- </Grid.Col>
417
- )}
418
- container={(form, onSubmit, readOnly) => (
419
- <>
420
- <Grid>{form}</Grid>
421
- {!readOnly && (
422
- <Group justify="flex-end">
423
- <Button onClick={onSubmit}>Submit</Button>
424
- </Group>
425
- )}
426
- </>
427
- )}
428
- onSubmit={(values) => {
429
- arrayOptions?.addElement(values);
430
- close();
431
- }}
432
- />
433
- </Modal>
434
-
435
- <Button onClick={open} mb="md">
436
- Add Phone
437
- </Button>
438
-
439
- {value.length > 0 ? (
440
- <Table withColumnBorders withRowBorders withTableBorder striped>
441
- <Table.Thead>
442
- <Table.Tr>
443
- <Table.Th>Phone NO.</Table.Th>
444
- <Table.Th>Action</Table.Th>
445
- </Table.Tr>
446
- </Table.Thead>
447
- <Table.Tbody>
448
- {value.map((phone, index) => (
449
- <Table.Tr key={index}>
450
- <Table.Td>{phone.phoneNo}</Table.Td>
451
- <Table.Td>
452
- <Button
453
- variant="light"
454
- size="xs"
455
- color="red"
456
- onClick={() => arrayOptions.removeElement(index)}
457
- >
458
- Delete
459
- </Button>
460
- </Table.Td>
461
- </Table.Tr>
462
- ))}
463
- </Table.Tbody>
464
- </Table>
465
- ) : (
466
- <Text>No phones are inserted</Text>
467
- )}
468
- </>
469
- )}
470
- />
471
- </>
472
- );
473
- };