@axzydev/axzy_ui_system 1.2.15 → 1.3.0

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 (60) hide show
  1. package/dist/index.cjs +3067 -1409
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.cts +620 -54
  5. package/dist/index.d.ts +620 -54
  6. package/dist/index.js +2983 -1320
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/App.tsx +28 -0
  10. package/src/components/atoms/badget/badget.tsx +2 -4
  11. package/src/components/atoms/chip/chip.doc.mdx +47 -0
  12. package/src/components/atoms/chip/chip.props.ts +32 -0
  13. package/src/components/atoms/chip/chip.stories.tsx +64 -0
  14. package/src/components/atoms/chip/chip.tsx +112 -0
  15. package/src/components/atoms/grid/grid.tsx +1 -2
  16. package/src/components/molecules/accordion/accordion.doc.mdx +47 -0
  17. package/src/components/molecules/accordion/accordion.props.ts +35 -0
  18. package/src/components/molecules/accordion/accordion.stories.tsx +68 -0
  19. package/src/components/molecules/accordion/accordion.tsx +123 -0
  20. package/src/components/molecules/chip-input/chip-input.doc.mdx +44 -0
  21. package/src/components/molecules/chip-input/chip-input.props.ts +42 -0
  22. package/src/components/molecules/chip-input/chip-input.stories.tsx +52 -0
  23. package/src/components/molecules/chip-input/chip-input.tsx +205 -0
  24. package/src/components/molecules/date-picker/datePicker.tsx +45 -56
  25. package/src/components/molecules/dropdown-menu/dropdown-menu.doc.mdx +46 -0
  26. package/src/components/molecules/dropdown-menu/dropdown-menu.props.ts +41 -0
  27. package/src/components/molecules/dropdown-menu/dropdown-menu.stories.tsx +41 -0
  28. package/src/components/molecules/dropdown-menu/dropdown-menu.tsx +219 -0
  29. package/src/components/molecules/field/field.doc.mdx +43 -0
  30. package/src/components/molecules/field/field.props.ts +23 -0
  31. package/src/components/molecules/field/field.stories.tsx +42 -0
  32. package/src/components/molecules/field/field.tsx +54 -0
  33. package/src/components/molecules/multi-select/multi-select.doc.mdx +55 -0
  34. package/src/components/molecules/multi-select/multi-select.props.ts +65 -0
  35. package/src/components/molecules/multi-select/multi-select.stories.tsx +59 -0
  36. package/src/components/molecules/multi-select/multi-select.tsx +386 -0
  37. package/src/components/molecules/search-select/search-select.doc.mdx +5 -0
  38. package/src/components/molecules/search-select/search-select.props.ts +10 -1
  39. package/src/components/molecules/search-select/search-select.stories.tsx +18 -0
  40. package/src/components/molecules/search-select/search-select.tsx +102 -28
  41. package/src/components/molecules/time-picker/timePicker.tsx +14 -26
  42. package/src/components/molecules/wysiwyg/wysiwyg.props.ts +51 -0
  43. package/src/components/molecules/wysiwyg/wysiwyg.stories.tsx +95 -0
  44. package/src/components/molecules/wysiwyg/wysiwyg.tsx +609 -0
  45. package/src/components/organisms/data-table/dataTable.tsx +16 -5
  46. package/src/components/organisms/form-builder/fieldRenderer.tsx +144 -27
  47. package/src/components/organisms/form-builder/formBuilder.context.tsx +77 -15
  48. package/src/components/organisms/form-builder/formBuilder.doc.mdx +213 -86
  49. package/src/components/organisms/form-builder/formBuilder.props.ts +118 -36
  50. package/src/components/organisms/form-builder/formBuilder.stories.tsx +694 -96
  51. package/src/components/organisms/form-builder/formBuilder.tsx +152 -69
  52. package/src/components/organisms/form-builder/useFormBuilder.ts +59 -21
  53. package/src/hooks/useFloatingPanel.ts +100 -0
  54. package/src/index.ts +24 -4
  55. package/src/showcases/DataShowcases.tsx +76 -0
  56. package/src/showcases/FormShowcases.tsx +396 -10
  57. package/src/showcases/HomeShowcase.tsx +6 -6
  58. package/src/showcases/NavigationShowcases.tsx +72 -2
  59. package/src/showcases/StructureShowcases.tsx +64 -0
  60. package/src/types/chip.types.ts +13 -0
@@ -5,101 +5,126 @@ import * as StoriesData from './formBuilder.stories';
5
5
 
6
6
  # ITFormBuilder
7
7
 
8
- A dynamic form generator that renders fields from JSON-like configuration (V1 or V2). Integrates with Formik and Yup for validation. Supports conditional rendering, calculated fields, grid layout, async validation, and custom components.
8
+ Dynamic form generator that renders fields from a JSON-like array. Integrates with
9
+ Formik + Yup, supports both a backward-compatible V1 (`fields`) and the powerful
10
+ Enterprise V2 (`config`) API, and exposes a `useFormBuilder()` hook for building
11
+ custom submit buttons, progress meters, and dirty-state indicators.
12
+
13
+ ## When to use
14
+
15
+ - You want to drive a form from a declarative config (server-driven forms, CMS schemas).
16
+ - You need conditional fields (`renderWhen`), derived values (`onChangeAction`),
17
+ dynamic props (`dynamicProps`), or cascading selects.
18
+ - You need to render a custom React component as a field (`type: "custom"`).
9
19
 
10
20
  ## Props
11
21
 
12
- | Prop | Type | Default | Description |
13
- |------|------|---------|-------------|
14
- | `fields` | `FieldConfig[]` | — | Legacy V1 field definitions (backward compatible). |
15
- | `config` | `FieldConfigV2[]` | — | V2 field configuration array with conditional logic, dynamic props, and grid layout. |
16
- | `columns` | `number` | — | Number of grid columns (1–12). |
17
- | `values` | `any` | — | Current form values keyed by field name. |
18
- | `handleChange` | `(event) => void` | — | Change handler for input, select, and textarea elements. |
19
- | `handleBlur` | `(event) => void` | — | Blur handler for input, select, and textarea elements. |
20
- | `touched` | `any` | — | Touch state keyed by field name. |
21
- | `errors` | `any` | — | Validation errors keyed by field name. |
22
- | `setFieldValue` | `(field, value, shouldValidate?) => Promise<void>` | — | Programmatically set a field value. |
23
- | `setFieldTouched` | `(field, touched?, shouldValidate?) => Promise<void>` | — | Programmatically mark a field as touched. |
24
- | `setFieldError` | `(field, message?) => void` | — | Programmatically set a field-level error. |
25
- | `isSubmitting` | `boolean` | — | Whether the form is currently submitting. |
26
-
27
- ### FieldConfigV2 Key Properties
28
-
29
- | Property | Type | Description |
30
- |----------|------|-------------|
31
- | `type` | `"text" \| "number" \| "password" \| "email" \| "select" \| "date" \| "time" \| "checkbox" \| "radio" \| "array" \| "section" \| "custom"` | Field input type. |
32
- | `column` | `number \| { sm?, md?, lg?, xl? }` | Grid column span (responsive object or single number). |
33
- | `dependsOn` | `string[]` | Sibling field names to watch for conditional re-evaluation. |
34
- | `renderWhen` | `(values) => boolean` | When false, the field is not rendered or submitted. |
35
- | `dynamicProps` | `(values) => Partial<FieldConfigV2>` | Dynamically override field props based on form state. |
36
- | `validation` | `Yup.AnySchema` | Per-field Yup validation schema. |
37
- | `asyncValidation` | `(value, values) => Promise<string \| null>` | Async per-field validation returning error string. |
38
- | `onChangeAction` | `(val, context) => void \| Promise<void>` | Lifecycle hook for side effects (e.g., calculate totals). |
39
- | `options` | `Array \| () => Promise<Array>` | Select/radio options, sync or async. |
40
- | `component` | `React.ComponentType` | Custom renderer for `type: "custom"`. |
22
+ | Prop | Type | Default | Required | Description |
23
+ |------|------|---------|----------|-------------|
24
+ | `fields` | `FieldConfig[]` | — | No | Legacy V1 field definitions. Kept for backward compatibility. |
25
+ | `config` | `FieldConfigV2[]` | — | No | V2 field configuration. Recommended. Shadows `fields` when both supplied. |
26
+ | `columns` | `number` | `12` | No | Grid column count (1–12). |
27
+ | `values` | `Record<string, unknown>` | — | Yes | Current form values keyed by field `name`. |
28
+ | `handleChange` | `(event) => void` | — | Yes | Change handler — pass Formik's `handleChange` directly. |
29
+ | `handleBlur` | `(event) => void` | — | Yes | Blur handler — pass Formik's `handleBlur` directly. |
30
+ | `touched` | `Record<string, boolean>` | — | Yes | Touch state keyed by field `name`. |
31
+ | `errors` | `Record<string, string>` | — | Yes | Errors keyed by field `name`. |
32
+ | `setFieldValue` | `(field, value, shouldValidate?) => Promise` | no-op | No | Required for V2 `onChangeAction` and `dynamicProps` side effects. |
33
+ | `setFieldTouched` | `(field, touched?, shouldValidate?) => Promise` | no-op | No | Programmatic touch. |
34
+ | `setFieldError` | `(field, message?) => void` | no-op | No | Programmatic field-level error. |
35
+ | `isSubmitting` | `boolean` | `false` | No | Surface submit state to the context. |
36
+
37
+ When both `config` and `fields` are supplied, `config` wins. When neither is supplied the
38
+ component renders an empty grid.
39
+
40
+ ## FieldConfigV2 reference
41
+
42
+ | Field | Type | Description |
43
+ |-------|------|-------------|
44
+ | `type` | `"text" \| "number" \| "password" \| "email" \| "select" \| "date" \| "time" \| "section" \| "custom" \| "array"` | Field kind. |
45
+ | `name` | `string` | Matches the key in `values` / `errors` / `touched`. |
46
+ | `label` | `string` | Text rendered above the field (or as the section heading). |
47
+ | `column` | `number \| { sm?, md?, lg?, xl? }` | Grid span. Responsive object or single number. |
48
+ | `dependsOn` | `string[]` | Sibling field names watched by `renderWhen`/`dynamicProps`. |
49
+ | `renderWhen` | `(values) => boolean` | Hide this field when returns `false`. |
50
+ | `dynamicProps` | `(values) => Partial<FieldConfigV2>` | Compute per-render overrides (e.g. toggle `disabled`). |
51
+ | `validation` | `Yup.AnySchema` | Per-field Yup schema. |
52
+ | `asyncValidation` | `(value, values) => Promise<string \| null>` | Async validator returning an error message or `null`. |
53
+ | `onChangeAction` | `(value, context) => void \| Promise<void>` | Side-effect fired on change. Use to compute derived fields. |
54
+ | `options` | `Array \| () => Promise<Array>` | Sync or async options for `select`. Async → renders `ITSearchSelect`. |
55
+ | `component` | `React.ComponentType` | Renderer for `type: "custom"`. |
56
+ | `fields` | `FieldConfigV2[]` | Nested fields for `type: "section"` (or `array` placeholder). |
57
+ | `placeholder` | `string` | Placeholder text. |
58
+ | `required` | `boolean \| (values) => boolean` | Required flag. |
59
+ | `disabled` | `boolean \| (values) => boolean` | Disabled flag. |
60
+ | `readOnly` | `boolean` | Read-only flag. |
61
+ | `defaultValue` | `any` | Initial value. |
62
+ | `valueField` / `labelField` | `string` | Keys read off each option object. |
63
+ | `leftIcon` / `rightIcon` | `React.ReactNode` | Icon adornments. |
64
+ | `className` | `string` | Extra classes for the field's container. |
65
+ | `maxLength` / `minLength` | `number` | Length bounds for text/textarea. |
66
+ | `rows` | `number` | Rows for textarea-style inputs. |
67
+ | `formatNumber` | `boolean` | Apply thousand-separator formatting as the user types. |
68
+ | `currencyFormat` | `boolean` | Render a `$`-style currency treatment on numeric input. |
69
+ | `showHintLength` | `boolean` | Show a live character counter. |
70
+
71
+ ## FieldConfig (V1) reference (legacy)
72
+
73
+ | Field | Type | Description |
74
+ |-------|------|-------------|
75
+ | `name` | `string` | Key in `values`/`errors`/`touched`. |
76
+ | `label` | `string` | Field label. |
77
+ | `type` | `"text" \| "number" \| "password" \| "select" \| "date"` | Input kind. |
78
+ | `placeholder` | `string` | Placeholder text. |
79
+ | `required` | `boolean` | Required flag. |
80
+ | `disabled` | `boolean` | Disabled flag. |
81
+ | `column` | `number` | Grid span. |
82
+ | `options` | `{ value, label }[]` | Options for `select`. |
83
+ | `leftIcon` / `rightIcon` | `React.ReactNode` | Icon adornments. |
84
+ | `valueField` / `labelField` | `string` | Keys read off each option object. |
85
+ | `maxLength` / `minLength` | `number` | Length bounds. |
86
+ | `rows` | `number` | Rows for multi-line inputs. |
87
+ | `formatNumber` | `boolean` | Thousand-separator formatting. |
88
+ | `currencyFormat` | `boolean` | Currency-style numeric input. |
89
+ | `showHintLength` | `boolean` | Live character counter. |
90
+ | `validation` | `Yup.AnySchema` | Per-field Yup schema. |
91
+ | `onChangeAction` | `(value, setFieldValue) => void` | Side-effect fired on change. |
41
92
 
42
93
  ## Usage
43
94
 
95
+ ### 1. Minimal Formik + Yup form (V2)
96
+
44
97
  ```tsx
45
- import { ITFormBuilder } from '@axzydev/axzy_ui_system';
46
- import { Formik } from 'formik';
47
- import * as Yup from 'yup';
98
+ import { Formik } from "formik";
99
+ import * as Yup from "yup";
100
+ import { ITFormBuilder } from "@axzydev/axzy_ui_system";
101
+ import type { FieldConfigV2 } from "@axzydev/axzy_ui_system";
48
102
 
49
103
  const schema = Yup.object({
50
- email: Yup.string().email("Invalid email").required("Required"),
51
- password: Yup.string().min(8).required("Required"),
104
+ email: Yup.string().email().required(),
105
+ password: Yup.string().min(8).required(),
52
106
  });
53
107
 
54
- const fields = [
55
- { name: "email", label: "Email", type: "email", required: true, column: { sm: 12 } },
56
- { name: "password", label: "Password", type: "password", required: true, column: { sm: 12 } },
57
- {
58
- name: "subtotal",
59
- label: "Subtotal",
60
- type: "number",
61
- currencyFormat: true,
62
- column: { sm: 12, md: 4 },
63
- onChangeAction: (val, { setFieldValue }) => {
64
- const num = parseFloat(val) || 0;
65
- setFieldValue("total", (num * 1.16).toFixed(2));
66
- },
67
- },
68
- {
69
- name: "total",
70
- label: "Total",
71
- type: "number",
72
- currencyFormat: true,
73
- disabled: true,
74
- column: { sm: 12, md: 4 },
75
- },
76
- {
77
- name: "rfc",
78
- label: "RFC",
79
- type: "text",
80
- dependsOn: ["country"],
81
- renderWhen: (vals) => vals.country === "MX",
82
- required: true,
83
- column: { sm: 12, md: 6 },
84
- },
108
+ const config: FieldConfigV2[] = [
109
+ { name: "email", label: "Email", type: "email", required: true, column: 6 },
110
+ { name: "password", label: "Password", type: "password", required: true, column: 6 },
85
111
  ];
86
112
 
87
113
  <Formik
88
- initialValues={{ email: "", password: "", subtotal: "", total: "", rfc: "" }}
114
+ initialValues={{ email: "", password: "" }}
89
115
  validationSchema={schema}
90
- onSubmit={handleSubmit}
116
+ onSubmit={(values) => console.log(values)}
91
117
  >
92
- {(formikProps) => (
93
- <form onSubmit={formikProps.handleSubmit}>
118
+ {(p) => (
119
+ <form onSubmit={p.handleSubmit}>
94
120
  <ITFormBuilder
95
- config={fields}
96
- columns={12}
97
- values={formikProps.values}
98
- handleChange={formikProps.handleChange}
99
- handleBlur={formikProps.handleBlur}
100
- touched={formikProps.touched}
101
- errors={formikProps.errors}
102
- setFieldValue={formikProps.setFieldValue}
121
+ config={config}
122
+ values={p.values}
123
+ handleChange={p.handleChange}
124
+ handleBlur={p.handleBlur}
125
+ touched={p.touched}
126
+ errors={p.errors}
127
+ setFieldValue={p.setFieldValue}
103
128
  />
104
129
  <button type="submit">Submit</button>
105
130
  </form>
@@ -107,18 +132,120 @@ const fields = [
107
132
  </Formik>
108
133
  ```
109
134
 
135
+ ### 2. Conditional + derived fields
136
+
137
+ ```tsx
138
+ const config: FieldConfigV2[] = [
139
+ {
140
+ name: "country",
141
+ label: "País",
142
+ type: "select",
143
+ required: true,
144
+ options: [{ value: "MX", label: "México" }, { value: "US", label: "USA" }],
145
+ },
146
+ {
147
+ name: "rfc",
148
+ label: "RFC",
149
+ type: "text",
150
+ required: true,
151
+ dependsOn: ["country"],
152
+ renderWhen: (v) => v.country === "MX",
153
+ },
154
+ {
155
+ name: "subtotal",
156
+ label: "Subtotal",
157
+ type: "number",
158
+ currencyFormat: true,
159
+ onChangeAction: (val, ctx) => {
160
+ const n = parseFloat(String(val).replace(/,/g, "")) || 0;
161
+ ctx.setFieldValue("total", (n * 1.16).toFixed(2));
162
+ },
163
+ },
164
+ { name: "total", label: "Total", type: "number", disabled: true, currencyFormat: true },
165
+ ];
166
+ ```
167
+
168
+ ### 3. Async / cascading options
169
+
170
+ ```tsx
171
+ {
172
+ name: "city",
173
+ label: "Ciudad",
174
+ type: "select",
175
+ options: async () => {
176
+ const res = await fetch(`/api/cities?country=${values.country}`);
177
+ return res.json();
178
+ },
179
+ }
180
+ ```
181
+
182
+ Async option lists use `ITSearchSelect` underneath and render a spinner fallback
183
+ while loading (`data-testid="field-loading-{name}"`).
184
+
185
+ ### 4. Custom component
186
+
187
+ ```tsx
188
+ const ConfirmToggle = ({ value, onChange, label }) => (
189
+ <label>
190
+ <input type="checkbox" checked={!!value} onChange={(e) => onChange(e.target.checked)} />
191
+ {label}
192
+ </label>
193
+ );
194
+
195
+ {
196
+ name: "confirm",
197
+ label: "Acepto términos",
198
+ type: "custom",
199
+ component: ConfirmToggle,
200
+ defaultValue: false,
201
+ }
202
+ ```
203
+
204
+ ### 5. Section grouping
205
+
206
+ ```tsx
207
+ {
208
+ name: "identity",
209
+ label: "Personal Information",
210
+ type: "section",
211
+ fields: [
212
+ { name: "firstName", label: "First Name", type: "text" },
213
+ { name: "lastName", label: "Last Name", type: "text" },
214
+ ],
215
+ }
216
+ ```
217
+
218
+ ### 6. Custom submit button via `useFormBuilder`
219
+
220
+ ```tsx
221
+ import { useFormBuilder } from "@axzydev/axzy_ui_system";
222
+
223
+ const SubmitButton = () => {
224
+ const { progress, isSubmitting } = useFormBuilder();
225
+ return (
226
+ <button type="submit" disabled={progress < 100 || isSubmitting}>
227
+ {isSubmitting ? "Saving…" : `Submit (${progress}%)`}
228
+ </button>
229
+ );
230
+ };
231
+ ```
232
+
233
+ `useFormBuilder` must be rendered inside the `<ITFormBuilder>` subtree (so the
234
+ V2 provider must be active). It throws a clear error if used outside.
235
+
110
236
  ## Notes
111
237
 
112
- - Supports both legacy V1 (`fields` prop) and enterprise V2 (`config` prop) field configurations.
113
- - V2 fields support a powerful rules engine: `dependsOn`, `renderWhen`, and `dynamicProps` for conditional behavior.
114
- - `onChangeAction` enables real-time field calculations and cross-field updates.
115
- - Grid layout uses a responsive 12-column system with per-breakpoint column span configuration.
116
- - Field types include `section` (grouping with collapsible regions) and `array` (dynamic repeatable lists).
117
- - Fully Formik-compatible — requires Formik context wrapping for state management.
118
- - `custom` type allows injecting arbitrary React components for complete layout control.
238
+ - The component is fully controlled — it does not own form state. Pass values
239
+ and handlers from Formik (or any state holder of your choice).
240
+ - V1 and V2 can coexist on a single page; mixing both on the same `<ITFormBuilder>`
241
+ is not supported — `config` wins.
242
+ - The V2 registry of registered fields is exposed via `useFormBuilder` and via
243
+ `useITFormBuilderContext().getAllFieldConfigs()`.
244
+ - `validation`/`asyncValidation` are NOT applied automatically — wire them to
245
+ Yup at the Formik root, or run them manually inside `onChangeAction`.
119
246
 
120
247
  ## Stories
121
248
 
122
249
  <Primary />
123
250
  <Controls />
124
- <Stories />
251
+ <Stories />
@@ -1,53 +1,135 @@
1
1
  import { FieldConfig, FieldConfigV2 } from "@/types/field.types";
2
2
 
3
+ /**
4
+ * A single field change event, mirroring the Formik public API surface so any
5
+ * standard Formik binding (`formik.handleChange`) can be passed through.
6
+ */
7
+ export type ITFormBuilderChangeEvent =
8
+ | React.ChangeEvent<HTMLInputElement>
9
+ | React.FocusEvent<HTMLInputElement>
10
+ | React.ChangeEvent<HTMLSelectElement>
11
+ | { target: { name: string; value: any } };
12
+
13
+ /**
14
+ * A single field blur event, mirroring the Formik public API surface so any
15
+ * standard Formik binding (`formik.handleBlur`) can be passed through.
16
+ */
17
+ export type ITFormBuilderBlurEvent =
18
+ | React.FocusEvent<HTMLInputElement>
19
+ | React.FocusEvent<HTMLSelectElement, Element>
20
+ | React.FocusEvent<HTMLTextAreaElement, Element>
21
+ | { target: { name: string; value: any } };
22
+
23
+ /**
24
+ * Form-level values keyed by field `name`. Kept as `Record<string, unknown>` so
25
+ * the builder does not impose a concrete domain shape on consumers.
26
+ */
27
+ export type ITFormBuilderValues = Record<string, unknown>;
28
+
29
+ /**
30
+ * Validation errors keyed by field `name`.
31
+ */
32
+ export type ITFormBuilderErrors = Record<string, string | undefined>;
33
+
34
+ /**
35
+ * Touch state keyed by field `name`.
36
+ */
37
+ export type ITFormBuilderTouched = Record<string, boolean>;
38
+
39
+ /**
40
+ * Props for {@link ITFormBuilder}. The component accepts either a legacy V1
41
+ * `fields` array (kept for backward compatibility with projects that adopted
42
+ * the original API) or the richer V2 `config` array. If both are supplied the
43
+ * V2 `config` takes precedence; if neither is supplied the component renders
44
+ * nothing.
45
+ */
3
46
  export interface ITFormBuilderProps {
4
- /** Legacy field definitions (V1). Use `config` for the V2 architecture instead */
47
+ /**
48
+ * Legacy V1 field definitions.
49
+ *
50
+ * @deprecated Prefer the `config` prop (V2). V1 is preserved for backward
51
+ * compatibility and supports a reduced subset of features (no rules engine,
52
+ * no `section`, no `custom`, no async options).
53
+ */
5
54
  fields?: FieldConfig[];
6
-
7
- /** V2 field configuration array. Preferred over the legacy `fields` prop */
55
+
56
+ /**
57
+ * V2 field configuration array. The recommended entry point. Supports the
58
+ * rules engine (`renderWhen` / `dynamicProps` / `dependsOn`), nested
59
+ * `sections`, custom renderers via `type: "custom"`, async option loaders, and
60
+ * per-field `validation` / `asyncValidation`.
61
+ *
62
+ * When this prop is supplied it shadows any `fields` prop.
63
+ */
8
64
  config?: FieldConfigV2[];
9
-
10
- /** Number of grid columns (1-12) */
65
+
66
+ /**
67
+ * Number of grid columns used by the responsive layout. Allowed range is
68
+ * 1..12; values outside the supported grid map fall back to a 12-column
69
+ * layout. @default 12
70
+ */
11
71
  columns?: number;
12
- /** Current form values keyed by field name */
13
- values: any;
14
- /** Change handler for input, select, and textarea elements */
15
- handleChange: (
16
- event:
17
- | React.ChangeEvent<HTMLInputElement>
18
- | React.FocusEvent<HTMLInputElement>
19
- | React.ChangeEvent<HTMLSelectElement>
20
- | { target: { name: string; value: any } }
21
- ) => void;
22
- /** Blur handler for input, select, and textarea elements */
23
- handleBlur: (
24
- event:
25
- | React.FocusEvent<HTMLInputElement>
26
- | React.FocusEvent<HTMLSelectElement, Element>
27
- | React.FocusEvent<HTMLTextAreaElement, Element>
28
- | { target: { name: string; value: any } }
29
- ) => void;
30
- /** Touch state keyed by field name */
31
- touched: any;
32
- /** Validation errors keyed by field name */
33
- errors: any;
34
- /** Programmatically set a field value */
72
+
73
+ /** Current form values keyed by field `name`. */
74
+ values: ITFormBuilderValues;
75
+
76
+ /**
77
+ * Change handler invoked by every rendered input/select/textarea. Designed
78
+ * to receive the native `event` from a controlled child, so a Formik
79
+ * `handleChange` can be passed directly.
80
+ */
81
+ handleChange: (event: ITFormBuilderChangeEvent) => void;
82
+
83
+ /**
84
+ * Blur handler invoked by every rendered input/select/textarea. Designed
85
+ * to receive the native `event` from a controlled child, so a Formik
86
+ * `handleBlur` can be passed directly.
87
+ */
88
+ handleBlur: (event: ITFormBuilderBlurEvent) => void;
89
+
90
+ /** Touch state keyed by field `name`. */
91
+ touched: ITFormBuilderTouched;
92
+
93
+ /** Validation errors keyed by field `name`. */
94
+ errors: ITFormBuilderErrors;
95
+
96
+ /**
97
+ * Programmatically sets a field value. Mirrors Formik's
98
+ * `setFieldValue(field, value, shouldValidate?)` so it can be passed through.
99
+ * Required to enable V2 features such as `onChangeAction` and
100
+ * `dynamicProps` side effects. Defaults to a no-op.
101
+ */
35
102
  setFieldValue?: (
36
103
  field: string,
37
104
  value: any,
38
105
  shouldValidate?: boolean
39
106
  ) => Promise<void | any>;
40
- /** Programmatically mark a field as touched */
107
+
108
+ /**
109
+ * Programmatically marks a field as touched. Mirrors Formik's
110
+ * `setFieldTouched(field, touched?, shouldValidate?)`. Defaults to a no-op.
111
+ */
41
112
  setFieldTouched?: (
42
113
  field: string,
43
114
  touched?: boolean,
44
115
  shouldValidate?: boolean
45
116
  ) => Promise<void | any>;
46
- /** Programmatically set a field-level error message */
47
- setFieldError?: (
48
- field: string,
49
- message: string | undefined
50
- ) => void;
51
- /** Whether the form is currently submitting */
117
+
118
+ /**
119
+ * Programmatically sets a field-level error message (Formik parity). Defaults
120
+ * to a no-op.
121
+ */
122
+ setFieldError?: (field: string, message: string | undefined) => void;
123
+
124
+ /** True while the parent form is submitting. Surfaced via the form context. */
52
125
  isSubmitting?: boolean;
53
- }
126
+
127
+ /**
128
+ * Optional children rendered **inside** the V2 `ITFormBuilderProvider`,
129
+ * after the field grid. Useful for custom submit buttons or progress
130
+ * badges that read live state via {@link useFormBuilder} /
131
+ * `useITFormBuilderContext`. Ignored in the V1 (legacy) path because
132
+ * no provider is mounted there.
133
+ */
134
+ children?: React.ReactNode;
135
+ }