@k3-universe/react-kit 0.0.13 → 0.0.14

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 (41) hide show
  1. package/dist/index.js +413 -403
  2. package/dist/kit/builder/data-table/types.d.ts +1 -1
  3. package/dist/kit/builder/data-table/types.d.ts.map +1 -1
  4. package/dist/kit/builder/form/components/FormBuilder.d.ts +3 -172
  5. package/dist/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
  6. package/dist/kit/builder/form/components/FormBuilderField.d.ts +8 -8
  7. package/dist/kit/builder/form/components/FormBuilderField.d.ts.map +1 -1
  8. package/dist/kit/builder/form/components/fields/types.d.ts +3 -3
  9. package/dist/kit/builder/form/components/fields/types.d.ts.map +1 -1
  10. package/dist/kit/builder/form/index.d.ts +1 -0
  11. package/dist/kit/builder/form/index.d.ts.map +1 -1
  12. package/dist/kit/builder/form/types.d.ts +175 -0
  13. package/dist/kit/builder/form/types.d.ts.map +1 -0
  14. package/dist/kit/builder/form/utils/common-forms.d.ts +1 -1
  15. package/dist/kit/builder/form/utils/common-forms.d.ts.map +1 -1
  16. package/dist/kit/builder/form/utils/field-factories.d.ts +3 -3
  17. package/dist/kit/builder/form/utils/field-factories.d.ts.map +1 -1
  18. package/dist/kit/builder/form/utils/section-factories.d.ts +4 -4
  19. package/dist/kit/builder/form/utils/section-factories.d.ts.map +1 -1
  20. package/dist/kit/builder/stack-dialog/provider.d.ts.map +1 -1
  21. package/dist/kit/builder/stack-dialog/renderer.d.ts.map +1 -1
  22. package/dist/kit/components/autocomplete/Autocomplete.d.ts +8 -8
  23. package/dist/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
  24. package/dist/kit/components/autocomplete/types.d.ts +6 -4
  25. package/dist/kit/components/autocomplete/types.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/kit/builder/data-table/components/DataTable.tsx +1 -1
  28. package/src/kit/builder/data-table/types.ts +1 -1
  29. package/src/kit/builder/form/components/FormBuilder.tsx +43 -237
  30. package/src/kit/builder/form/components/FormBuilderField.tsx +42 -34
  31. package/src/kit/builder/form/components/fields/AutocompleteField.tsx +2 -2
  32. package/src/kit/builder/form/components/fields/types.ts +3 -3
  33. package/src/kit/builder/form/index.ts +1 -0
  34. package/src/kit/builder/form/types.ts +198 -0
  35. package/src/kit/builder/form/utils/common-forms.ts +1 -1
  36. package/src/kit/builder/form/utils/field-factories.ts +5 -5
  37. package/src/kit/builder/form/utils/section-factories.ts +10 -10
  38. package/src/kit/builder/stack-dialog/provider.tsx +2 -1
  39. package/src/kit/builder/stack-dialog/renderer.tsx +6 -7
  40. package/src/kit/components/autocomplete/Autocomplete.tsx +33 -25
  41. package/src/kit/components/autocomplete/types.ts +7 -5
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/kit/components/autocomplete/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,kBAAkB,EAAE,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,uBAAuB,CAAC,CAAA;AAErC,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/kit/components/autocomplete/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC5C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,GAAG,CAAC,EAAE,CAAC,CAAA;CACR,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,OAAO,IAAI;IACjD,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,mBAAmB,CAAC,CAAC,GAAG,OAAO,IAAI,CAC7C,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAA;AAExC,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k3-universe/react-kit",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -20,7 +20,7 @@ import { Button } from '../../../../shadcn/ui/button';
20
20
  import { Checkbox } from '../../../../shadcn/ui/checkbox';
21
21
  import { Skeleton } from '../../../../shadcn/ui/skeleton';
22
22
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../../../shadcn/ui/table';
23
- import { FormBuilder, type FormBuilderSectionConfig } from '../../form/components/FormBuilder';
23
+ import { FormBuilder, type FormBuilderSectionConfig } from '../../form';
24
24
  import type { DataTableAction, DataTableBatchAction, DataTableFiltersProp } from '../types';
25
25
  import { DataTablePagination } from './DataTablePagination';
26
26
  import { DataTableViewOptions } from './DataTableViewOptions';
@@ -1,4 +1,4 @@
1
- import type { FormBuilderSectionConfig } from '../form/components/FormBuilder';
1
+ import type { FormBuilderSectionConfig } from '../form';
2
2
 
3
3
  export type DataTableFiltersProp = FormBuilderSectionConfig[];
4
4
 
@@ -1,221 +1,22 @@
1
- import type React from 'react';
2
1
  import { useCallback, useEffect, useMemo, useRef } from 'react';
3
- import { useForm, useWatch, type Control, type FieldValues } from 'react-hook-form';
2
+ import { useForm, useWatch, type FieldValues, type Path } from 'react-hook-form';
4
3
  import { zodResolver } from '@hookform/resolvers/zod';
5
4
  import { z } from 'zod';
6
5
  import { cn } from '../../../../shadcn/lib/utils';
7
6
  import { Button } from '../../../../shadcn/ui/button';
8
7
  import { FormBuilderField } from './FormBuilderField';
9
8
  import SectionBuilder from '../../section/SectionBuilder';
9
+ import type { SectionNode } from '../../section/types';
10
10
  import type {
11
- SectionLayout,
12
- SectionGridOptions,
13
- SectionFlexOptions,
14
- SectionNode,
15
- } from '../../section/types';
16
- import type {
17
- AutocompleteFetcher,
18
- AutocompleteOption,
19
- } from '../../../components/autocomplete/types';
20
- import type { Accept } from 'react-dropzone';
21
- import type {
22
- FileRecord,
23
- FileUploaderLayout,
24
- } from '../../../components/fileuploader/types';
25
-
26
- export interface FormBuilderFieldConfig {
27
- id?: string; // Optional ID for test fixtures
28
- name: string;
29
- label: string;
30
- type:
31
- | 'text'
32
- | 'email'
33
- | 'password'
34
- | 'number'
35
- | 'textarea'
36
- | 'select'
37
- | 'autocomplete'
38
- | 'checkbox'
39
- | 'switch'
40
- | 'radio'
41
- | 'date' // native input date
42
- | 'date_picker' // UI DatePicker
43
- | 'date_range' // UI DateRangePicker
44
- | 'month' // UI MonthPicker (single month Date)
45
- | 'month_range' // UI MonthRangePicker { start: Date, end: Date }
46
- | 'time' // UI TimePicker (Date with time part)
47
- | 'time_range' // UI TimeRangePicker { from: Date, to: Date }
48
- | 'date_time' // UI DateTimePicker (Date with date+time)
49
- | 'date_time_range' // UI DateTimeRangePicker { from: Date, to: Date }
50
- | 'file'
51
- | 'object'
52
- | 'array';
53
- placeholder?: string;
54
- description?: string;
55
- required?: boolean;
56
- disabled?: boolean;
57
- options?: { label: string; value: string | number | null }[];
58
- // Autocomplete specific (client/server)
59
- autocompleteMode?: 'client' | 'server';
60
- fetcher?: AutocompleteFetcher;
61
- pageSize?: number;
62
- searchPlaceholder?: string;
63
- renderOption?: (
64
- option: AutocompleteOption,
65
- selected: boolean
66
- ) => React.ReactNode;
67
- // New autocomplete features
68
- multiple?: boolean;
69
- allowCustomValue?: boolean;
70
- chipVariant?: 'default' | 'secondary' | 'destructive' | 'outline';
71
- chipClassName?: string;
72
- clearable?: boolean;
73
- initialSelectedOptions?: AutocompleteOption | AutocompleteOption[] | null;
74
- loadSelected?: (values: Array<string | number>) => Promise<AutocompleteOption[]>;
75
- validation?:
76
- | z.ZodType<unknown>
77
- | {
78
- pattern?: { value: RegExp; message: string };
79
- min?: { value: number; message: string };
80
- max?: { value: number; message: string };
81
- minLength?: { value: number; message: string };
82
- maxLength?: { value: number; message: string };
83
- // For array-like fields (e.g., file uploader)
84
- minItems?: { value: number; message: string };
85
- maxItems?: { value: number; message: string };
86
- };
87
- defaultValue?: unknown;
88
- fields?: FormBuilderFieldConfig[]; // For nested object/array fields
89
- dependencies?: {
90
- field: string;
91
- condition: (value: unknown) => boolean;
92
- action: 'show' | 'hide' | 'enable' | 'disable' | 'setValue';
93
- value?: unknown;
94
- }[];
95
- onChange?: (
96
- value: unknown,
97
- setValue: (field: string, value: unknown) => void,
98
- getValues: () => Record<string, unknown>
99
- ) => void;
100
- className?: string;
101
- gridCols?: number;
102
- rows?: number; // For textarea fields
103
- itemType?: string; // For array fields
104
- // Array field layout: default 'card'
105
- arrayLayout?: 'card' | 'table' | 'custom';
106
- // Custom renderer for array fields when arrayLayout === 'custom'
107
- arrayRender?: (params: {
108
- field: FormBuilderFieldConfig;
109
- control: Control<FieldValues>;
110
- fieldPath: string;
111
- value: unknown;
112
- onChange: (value: unknown) => void;
113
- addItem: () => void;
114
- removeItem: (index: number) => void;
115
- disabled?: boolean;
116
- rows?: { id: string }[]; // useFieldArray rows for stable rendering
117
- }) => React.ReactNode;
118
- // Optional styling for array layouts (used mainly for 'table')
119
- arrayColors?: {
120
- headerBgClass?: string; // e.g. 'bg-teal-700'
121
- headerTextClass?: string; // e.g. 'text-white'
122
- rowAltBgClass?: string; // e.g. 'bg-teal-50'
123
- };
124
- conditional?: {
125
- field: string;
126
- value: unknown;
127
- }; // For conditional field visibility
128
- hidden?: boolean; // Declarative hide
129
- // Label placement control across inputs
130
- labelPlacement?: 'stacked' | 'inline' | 'hidden';
131
- // Wrapper container className (applies to the field wrapper, not the input)
132
- wrapperClassName?: string;
133
- // Picker-specific optional props (passed through to components when applicable)
134
- minDate?: Date;
135
- maxDate?: Date;
136
- disabledDates?: Array<Date | { from: Date; to: Date }>;
137
- numberOfMonths?: number;
138
- popoverSide?: 'top' | 'right' | 'bottom' | 'left';
139
- showFooter?: boolean;
140
- cancelLabel?: string;
141
- applyLabel?: string;
142
- // Time picker specific
143
- timePrecision?: 'hour' | 'minute' | 'second';
144
- hourCycle?: 12 | 24;
145
- minuteStep?: number;
146
- secondStep?: number;
147
- // File uploader specific options
148
- fileMultiple?: boolean;
149
- fileMaxFiles?: number;
150
- fileAccept?: Accept;
151
- fileLayout?: FileUploaderLayout;
152
- fileWithDownload?: boolean;
153
- fileUploader?: (
154
- file: File,
155
- onProgress: (pct: number) => void,
156
- ) => Promise<Partial<FileRecord>>;
157
- fileOnUploadSuccess?: (file: FileRecord) => void;
158
- fileOnUploadError?: (file: FileRecord, error: unknown) => void;
159
- fileOnRemove?: (file: FileRecord) => void | Promise<void>;
160
- fileOnRetry?: (file: FileRecord) => void;
161
- fileOnRetryAll?: (files: FileRecord[]) => void;
162
- }
163
-
164
- export interface FormBuilderSectionConfig {
165
- id?: string;
166
- title?: string;
167
- description?: string;
168
- fields?: FormBuilderFieldConfig[];
169
- variant?: 'card' | 'separator' | 'plain';
170
- className?: string;
171
- collapsible?: boolean;
172
- defaultCollapsed?: boolean;
173
- layout?: SectionLayout;
174
- grid?: SectionGridOptions;
175
- flex?: SectionFlexOptions;
176
- hidden?: boolean; // Declarative hide
177
- // Tabs layout support: when layout === 'tabs', provide tabs instead of direct fields
178
- tabs?: Array<{
179
- id: string;
180
- label: React.ReactNode;
181
- sections: FormBuilderSectionConfig[];
182
- className?: string;
183
- contentClassName?: string;
184
- }>;
185
- defaultTabId?: string;
186
- tabsListClassName?: string;
187
- tabsContentClassName?: string;
188
- }
189
-
190
- export interface FormBuilderProps {
191
- sections: FormBuilderSectionConfig[];
192
- schema?: z.ZodType<unknown>;
193
- defaultValues?: Record<string, unknown> | null;
194
- onSubmit: (data: unknown) => void | Promise<void>;
195
- onCancel?: () => void;
196
- onReset?: () => void;
197
- onFieldChange?: (
198
- name: string,
199
- value: unknown,
200
- allValues: Record<string, unknown>
201
- ) => void;
202
- submitLabel?: string;
203
- cancelLabel?: string;
204
- resetLabel?: string;
205
- isSubmitting?: boolean;
206
- className?: string;
207
- formClassName?: string;
208
- actionsClassName?: string;
209
- showActions?: boolean;
210
- customActions?: React.ReactNode;
211
- // UI: show a separator line above action buttons
212
- showActionsSeparator?: boolean;
213
- }
11
+ FormBuilderProps,
12
+ FormBuilderFieldConfig,
13
+ FormBuilderSectionConfig,
14
+ } from '../types';
214
15
 
215
- export function FormBuilder({
16
+ export function FormBuilder<TFieldValues extends FieldValues = FieldValues>({
216
17
  sections,
217
18
  schema,
218
- defaultValues = {},
19
+ defaultValues,
219
20
  onSubmit,
220
21
  onCancel,
221
22
  onReset,
@@ -230,13 +31,13 @@ export function FormBuilder({
230
31
  showActions = true,
231
32
  customActions,
232
33
  showActionsSeparator = true,
233
- }: FormBuilderProps) {
34
+ }: FormBuilderProps<TFieldValues>) {
234
35
  // Generate schema from field configs if not provided
235
36
  const generatedSchema = useMemo(() => {
236
37
  if (schema) return schema;
237
38
 
238
39
  const generateFieldSchema = (
239
- field: FormBuilderFieldConfig
40
+ field: FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>
240
41
  ): z.ZodType<unknown> => {
241
42
  if (field.validation && field.validation instanceof z.ZodType) {
242
43
  return field.validation;
@@ -430,7 +231,7 @@ export function FormBuilder({
430
231
  case 'object':
431
232
  if (field.fields) {
432
233
  const objectSchema: Record<string, z.ZodType<unknown>> = {};
433
- for (const subField of field.fields) {
234
+ for (const subField of field.fields as Array<FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>>) {
434
235
  objectSchema[subField.name] = generateFieldSchema(subField);
435
236
  }
436
237
  fieldSchema = z.object(objectSchema);
@@ -442,9 +243,9 @@ export function FormBuilder({
442
243
  if (field.fields && field.fields.length > 0) {
443
244
  const arrayItemSchema =
444
245
  field.fields.length === 1
445
- ? generateFieldSchema(field.fields[0])
246
+ ? generateFieldSchema(field.fields[0] as FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>)
446
247
  : z.object(
447
- field.fields.reduce((acc, subField) => {
248
+ (field.fields as Array<FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>>).reduce((acc, subField) => {
448
249
  acc[subField.name] = generateFieldSchema(subField);
449
250
  return acc;
450
251
  }, {} as Record<string, z.ZodType<unknown>>)
@@ -463,7 +264,7 @@ export function FormBuilder({
463
264
 
464
265
  const schemaObject: Record<string, z.ZodType<unknown>> = {};
465
266
 
466
- const forEachField = (secs: FormBuilderSectionConfig[]) => {
267
+ const forEachField = (secs: FormBuilderSectionConfig<TFieldValues>[]) => {
467
268
  for (const section of secs) {
468
269
  // Traverse tabs if present
469
270
  if (section.tabs && section.tabs.length > 0) {
@@ -472,21 +273,21 @@ export function FormBuilder({
472
273
  }
473
274
  }
474
275
  for (const field of (section.fields ?? [])) {
475
- schemaObject[field.name] = generateFieldSchema(field);
276
+ schemaObject[field.name] = generateFieldSchema(field as FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>);
476
277
  }
477
278
  }
478
279
  };
479
280
 
480
281
  forEachField(sections);
481
282
 
482
- return z.object(schemaObject);
283
+ return z.object(schemaObject) as unknown as z.ZodType<TFieldValues>;
483
284
  }, [sections, schema]);
484
285
 
485
286
  // Generate default values from field configs
486
287
  const generatedDefaultValues = useMemo(() => {
487
- const values: Record<string, unknown> = { ...defaultValues };
288
+ const values: Record<string, unknown> = { ...((defaultValues ?? {}) as Record<string, unknown>) };
488
289
 
489
- const processFields = (fields: FormBuilderFieldConfig[]) => {
290
+ const processFields = (fields: FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>[]) => {
490
291
  for (const field of fields) {
491
292
  if (
492
293
  values[field.name] === undefined &&
@@ -518,7 +319,7 @@ export function FormBuilder({
518
319
  }
519
320
  };
520
321
 
521
- const forEachSection = (secs: FormBuilderSectionConfig[]) => {
322
+ const forEachSection = (secs: FormBuilderSectionConfig<TFieldValues>[]) => {
522
323
  for (const section of secs) {
523
324
  if (section.tabs && section.tabs.length > 0) {
524
325
  for (const tab of section.tabs) {
@@ -534,19 +335,19 @@ export function FormBuilder({
534
335
  return values;
535
336
  }, [sections, defaultValues]);
536
337
 
537
- const form = useForm<FieldValues>({
338
+ const form = useForm<TFieldValues>({
538
339
  // Dynamic schema shape: cast to any to satisfy resolver generics
539
340
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
540
- resolver: zodResolver(generatedSchema as any) as unknown as import('react-hook-form').Resolver<FieldValues, any, FieldValues>,
541
- defaultValues: generatedDefaultValues as FieldValues,
341
+ resolver: zodResolver(generatedSchema as any) as unknown as import('react-hook-form').Resolver<TFieldValues, any, TFieldValues>,
342
+ defaultValues: generatedDefaultValues as unknown as import('react-hook-form').DefaultValues<TFieldValues>,
542
343
  });
543
344
 
544
345
  const { control, handleSubmit, reset, setValue, getValues } = form;
545
346
 
546
347
  // Determine dependency fields to watch
547
348
  const dependencyFields = useMemo(() => {
548
- const set = new Set<string>();
549
- const forEachField = (secs: FormBuilderSectionConfig[]) => {
349
+ const set = new Set<Path<TFieldValues>>();
350
+ const forEachField = (secs: FormBuilderSectionConfig<TFieldValues>[]) => {
550
351
  for (const section of secs) {
551
352
  if (section.tabs && section.tabs.length > 0) {
552
353
  for (const tab of section.tabs) {
@@ -586,7 +387,7 @@ export function FormBuilder({
586
387
  );
587
388
 
588
389
  const handleFieldDependencies = useCallback(
589
- (field: FormBuilderFieldConfig) => {
390
+ (field: FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>) => {
590
391
  if (!hasDependencies || !field.dependencies) return {};
591
392
 
592
393
  const result: { disabled?: boolean; hidden?: boolean } = {};
@@ -610,11 +411,11 @@ export function FormBuilder({
610
411
  break;
611
412
  case 'setValue':
612
413
  if (conditionMet && dep.value !== undefined) {
613
- const currentValue = getValues(field.name);
414
+ const currentValue = getValues(field.name as unknown as Path<TFieldValues>);
614
415
  if (currentValue !== dep.value) {
615
416
  // Defer the update to an effect to prevent state changes during render
616
417
  pendingValueUpdatesRef.current.push({
617
- name: field.name,
418
+ name: field.name as unknown as string,
618
419
  value: dep.value,
619
420
  });
620
421
  }
@@ -638,9 +439,10 @@ export function FormBuilder({
638
439
  }
639
440
  pendingValueUpdatesRef.current = [];
640
441
  for (const [name, value] of updatesMap) {
641
- const current = getValues(name);
442
+ const pathName = name as unknown as Path<TFieldValues>;
443
+ const current = getValues(pathName);
642
444
  if (current !== value) {
643
- setValue(name, value, {
445
+ setValue(pathName, value as unknown as never, {
644
446
  shouldDirty: false,
645
447
  shouldTouch: false,
646
448
  shouldValidate: false,
@@ -651,16 +453,20 @@ export function FormBuilder({
651
453
 
652
454
  // Handle field change with custom onChange
653
455
  const handleFieldChange = useCallback(
654
- (field: FormBuilderFieldConfig, value: unknown) => {
456
+ (
457
+ field: FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>,
458
+ value: unknown,
459
+ ...extras: unknown[]
460
+ ) => {
655
461
  if (field.onChange) {
656
- field.onChange(value, setValue, getValues);
462
+ field.onChange(value, extras, setValue, getValues);
657
463
  }
658
464
  },
659
465
  [setValue, getValues]
660
466
  );
661
467
 
662
468
  const handleFormSubmit = useCallback(
663
- async (data: unknown) => {
469
+ async (data: TFieldValues) => {
664
470
  try {
665
471
  await onSubmit(data);
666
472
  } catch (error) {
@@ -671,13 +477,13 @@ export function FormBuilder({
671
477
  );
672
478
 
673
479
  const handleReset = useCallback(() => {
674
- reset(generatedDefaultValues);
480
+ reset(generatedDefaultValues as unknown as import('react-hook-form').DefaultValues<TFieldValues>);
675
481
  onReset?.();
676
482
  }, [reset, generatedDefaultValues, onReset]);
677
483
 
678
484
  // Build SectionBuilder nodes from form sections/fields
679
485
  const sectionNodes: SectionNode[] = useMemo(() => {
680
- const buildLeavesFromFields = (fields?: FormBuilderFieldConfig[]): SectionNode['children'] =>
486
+ const buildLeavesFromFields = (fields?: FormBuilderFieldConfig<TFieldValues, string | Path<TFieldValues>>[]): SectionNode['children'] =>
681
487
  (fields ?? [])
682
488
  .map((field) => {
683
489
  const fieldState = handleFieldDependencies(field);
@@ -698,9 +504,9 @@ export function FormBuilder({
698
504
  disabled: field.disabled || fieldState.disabled,
699
505
  }}
700
506
  control={control}
701
- onChange={(value) => {
702
- handleFieldChange(field, value);
703
- onFieldChange?.(field.name, value, getValues());
507
+ onChange={(value, ...extras) => {
508
+ handleFieldChange(field, value, ...extras);
509
+ onFieldChange?.(field.name as unknown as string, value, getValues());
704
510
  }}
705
511
  onFieldChange={onFieldChange}
706
512
  />
@@ -710,7 +516,7 @@ export function FormBuilder({
710
516
  .filter(Boolean) as SectionNode['children'];
711
517
 
712
518
  const buildSectionNode = (
713
- section: FormBuilderSectionConfig,
519
+ section: FormBuilderSectionConfig<TFieldValues>,
714
520
  sectionIndex: number,
715
521
  ): SectionNode => {
716
522
  const baseNode: SectionNode = {