@buildnbuzz/buzzform 0.1.5 → 0.1.7

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.
@@ -399,8 +399,8 @@ interface CheckboxGroupField extends BaseField<Array<string | number | boolean>>
399
399
  ui?: {
400
400
  /** Layout direction */
401
401
  direction?: "vertical" | "horizontal";
402
- /** Grid columns (responsive, 1 on mobile) */
403
- columns?: 1 | 2 | 3 | 4;
402
+ /** Grid columns (responsive, 1 on mobile). Leave undefined/empty for Auto flow. */
403
+ columns?: number | string | undefined;
404
404
  /** Visual variant */
405
405
  variant?: "default" | "card";
406
406
  /** Card settings (for variant: 'card') */
@@ -448,8 +448,8 @@ interface RadioField extends BaseField<string | number | boolean> {
448
448
  variant?: "default" | "card";
449
449
  /** Layout direction for 'default' variant */
450
450
  direction?: "vertical" | "horizontal";
451
- /** Grid columns (responsive, 1 on mobile) */
452
- columns?: 1 | 2 | 3 | 4;
451
+ /** Grid columns (responsive, 1 on mobile). Leave undefined or '' for Auto flow. */
452
+ columns?: number | string | undefined;
453
453
  /** Card settings (for variant: 'card') */
454
454
  card?: {
455
455
  /** Size preset ('sm', 'md', 'lg') */
@@ -692,6 +692,43 @@ interface FormSettings {
692
692
  */
693
693
  autoFocus?: boolean;
694
694
  }
695
+ /**
696
+ * Output type for form submission data.
697
+ * - 'path': Flat keys with full path using a delimiter (e.g., "person.contactDetails.address.street")
698
+ *
699
+ * When no output config is set, the default behavior is preserved
700
+ * (hierarchical JSON matching the field tree structure).
701
+ */
702
+ type OutputType = "path";
703
+ /**
704
+ * Delimiter character used for path output.
705
+ * @default '.'
706
+ */
707
+ type PathDelimiter = "." | "-" | "_";
708
+ /**
709
+ * Configuration for form submission output shape.
710
+ * When omitted, the default hierarchical JSON output is used.
711
+ *
712
+ * @example
713
+ * // Path output with dot: { 'person.name': 'John', 'person.address.street': 'Main St' }
714
+ * output: { type: 'path' }
715
+ *
716
+ * @example
717
+ * // Path output with underscore: { 'person_name': 'John', 'person_address_street': 'Main St' }
718
+ * output: { type: 'path', delimiter: '_' }
719
+ */
720
+ interface OutputConfig {
721
+ /**
722
+ * Output mode.
723
+ * Set to 'path' to flatten nested data into delimited path keys.
724
+ */
725
+ type: OutputType;
726
+ /**
727
+ * Delimiter for path keys.
728
+ * @default '.'
729
+ */
730
+ delimiter?: PathDelimiter;
731
+ }
695
732
  /**
696
733
  * Global form configuration set at the provider level.
697
734
  * These defaults apply to all forms unless overridden.
@@ -732,7 +769,7 @@ interface FormConfig {
732
769
  * - 'onSubmit': Validate only on submit
733
770
  * @default 'onChange'
734
771
  */
735
- mode?: 'onChange' | 'onBlur' | 'onSubmit';
772
+ mode?: "onChange" | "onBlur" | "onSubmit";
736
773
  /**
737
774
  * When to re-validate after initial validation error.
738
775
  * - 'onChange': Re-validate on every change (default)
@@ -740,7 +777,14 @@ interface FormConfig {
740
777
  * - 'onSubmit': Re-validate only on submit
741
778
  * @default 'onChange'
742
779
  */
743
- reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';
780
+ reValidateMode?: "onChange" | "onBlur" | "onSubmit";
781
+ /**
782
+ * Default output configuration for all forms.
783
+ * Controls the shape of data passed to onSubmit.
784
+ * Can be overridden per-form via UseFormOptions.
785
+ * @default undefined (hierarchical JSON)
786
+ */
787
+ output?: OutputConfig;
744
788
  }
745
789
  /**
746
790
  * Options passed to useForm hook.
@@ -785,12 +829,19 @@ interface UseFormOptions<TData = Record<string, unknown>> {
785
829
  * Override the validation mode for this form.
786
830
  * Uses provider's mode if not specified.
787
831
  */
788
- mode?: 'onChange' | 'onBlur' | 'onSubmit';
832
+ mode?: "onChange" | "onBlur" | "onSubmit";
789
833
  /**
790
834
  * Override the re-validation mode for this form.
791
835
  * Uses provider's reValidateMode if not specified.
792
836
  */
793
- reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';
837
+ reValidateMode?: "onChange" | "onBlur" | "onSubmit";
838
+ /**
839
+ * Output configuration for this form.
840
+ * Overrides the provider-level output config.
841
+ * Controls the shape of data passed to onSubmit.
842
+ * @default undefined (defaults to hierarchical JSON if not specified here or in Provider)
843
+ */
844
+ output?: OutputConfig;
794
845
  /**
795
846
  * Form behavior settings.
796
847
  */
@@ -1173,4 +1224,4 @@ type AdapterFactory<TData = Record<string, unknown>> = (options: AdapterOptions<
1173
1224
  */
1174
1225
  declare function validateAdapter(adapter: FormAdapter, adapterName?: string): void;
1175
1226
 
1176
- export { type ArrayHelpers as A, type BaseField as B, type ConditionContext as C, type DateField as D, type EmailField as E, type Field as F, type GroupField as G, type RowField as H, type Tab as I, type TabsField as J, type CollapsibleField as K, type FieldType as L, type DataField as M, type NumberField as N, type LayoutField as O, type PasswordField as P, type BuzzFormSchema as Q, type ResolverResult as R, type SetValueOptions as S, type TextField as T, type UseFormOptions as U, type ValidationContext as V, type FormSettings as W, type FormConfig as a, type FormAdapter as b, type FormState as c, type FieldError as d, type Resolver as e, type AdapterOptions as f, type AdapterFactory as g, type ValidationResult as h, type ValidationFn as i, type FieldCondition as j, type FieldComponentProps as k, type FieldInputProps as l, type FieldInputRenderFn as m, type FieldStyle as n, type TextareaField as o, type DatetimeField as p, type SelectOption as q, type SelectField as r, type CheckboxGroupField as s, type CheckboxField as t, type SwitchField as u, validateAdapter as v, type RadioField as w, type TagsField as x, type UploadField as y, type ArrayField as z };
1227
+ export { type ArrayHelpers as A, type BaseField as B, type ConditionContext as C, type DateField as D, type EmailField as E, type Field as F, type GroupField as G, type RowField as H, type Tab as I, type TabsField as J, type CollapsibleField as K, type FieldType as L, type DataField as M, type NumberField as N, type OutputConfig as O, type PasswordField as P, type LayoutField as Q, type ResolverResult as R, type SetValueOptions as S, type TextField as T, type UseFormOptions as U, type ValidationContext as V, type BuzzFormSchema as W, type FormSettings as X, type OutputType as Y, type PathDelimiter as Z, type FormConfig as a, type FormAdapter as b, type FormState as c, type FieldError as d, type Resolver as e, type AdapterOptions as f, type AdapterFactory as g, type ValidationResult as h, type ValidationFn as i, type FieldCondition as j, type FieldComponentProps as k, type FieldInputProps as l, type FieldInputRenderFn as m, type FieldStyle as n, type TextareaField as o, type DatetimeField as p, type SelectOption as q, type SelectField as r, type CheckboxGroupField as s, type CheckboxField as t, type SwitchField as u, validateAdapter as v, type RadioField as w, type TagsField as x, type UploadField as y, type ArrayField as z };
@@ -399,8 +399,8 @@ interface CheckboxGroupField extends BaseField<Array<string | number | boolean>>
399
399
  ui?: {
400
400
  /** Layout direction */
401
401
  direction?: "vertical" | "horizontal";
402
- /** Grid columns (responsive, 1 on mobile) */
403
- columns?: 1 | 2 | 3 | 4;
402
+ /** Grid columns (responsive, 1 on mobile). Leave undefined/empty for Auto flow. */
403
+ columns?: number | string | undefined;
404
404
  /** Visual variant */
405
405
  variant?: "default" | "card";
406
406
  /** Card settings (for variant: 'card') */
@@ -448,8 +448,8 @@ interface RadioField extends BaseField<string | number | boolean> {
448
448
  variant?: "default" | "card";
449
449
  /** Layout direction for 'default' variant */
450
450
  direction?: "vertical" | "horizontal";
451
- /** Grid columns (responsive, 1 on mobile) */
452
- columns?: 1 | 2 | 3 | 4;
451
+ /** Grid columns (responsive, 1 on mobile). Leave undefined or '' for Auto flow. */
452
+ columns?: number | string | undefined;
453
453
  /** Card settings (for variant: 'card') */
454
454
  card?: {
455
455
  /** Size preset ('sm', 'md', 'lg') */
@@ -692,6 +692,43 @@ interface FormSettings {
692
692
  */
693
693
  autoFocus?: boolean;
694
694
  }
695
+ /**
696
+ * Output type for form submission data.
697
+ * - 'path': Flat keys with full path using a delimiter (e.g., "person.contactDetails.address.street")
698
+ *
699
+ * When no output config is set, the default behavior is preserved
700
+ * (hierarchical JSON matching the field tree structure).
701
+ */
702
+ type OutputType = "path";
703
+ /**
704
+ * Delimiter character used for path output.
705
+ * @default '.'
706
+ */
707
+ type PathDelimiter = "." | "-" | "_";
708
+ /**
709
+ * Configuration for form submission output shape.
710
+ * When omitted, the default hierarchical JSON output is used.
711
+ *
712
+ * @example
713
+ * // Path output with dot: { 'person.name': 'John', 'person.address.street': 'Main St' }
714
+ * output: { type: 'path' }
715
+ *
716
+ * @example
717
+ * // Path output with underscore: { 'person_name': 'John', 'person_address_street': 'Main St' }
718
+ * output: { type: 'path', delimiter: '_' }
719
+ */
720
+ interface OutputConfig {
721
+ /**
722
+ * Output mode.
723
+ * Set to 'path' to flatten nested data into delimited path keys.
724
+ */
725
+ type: OutputType;
726
+ /**
727
+ * Delimiter for path keys.
728
+ * @default '.'
729
+ */
730
+ delimiter?: PathDelimiter;
731
+ }
695
732
  /**
696
733
  * Global form configuration set at the provider level.
697
734
  * These defaults apply to all forms unless overridden.
@@ -732,7 +769,7 @@ interface FormConfig {
732
769
  * - 'onSubmit': Validate only on submit
733
770
  * @default 'onChange'
734
771
  */
735
- mode?: 'onChange' | 'onBlur' | 'onSubmit';
772
+ mode?: "onChange" | "onBlur" | "onSubmit";
736
773
  /**
737
774
  * When to re-validate after initial validation error.
738
775
  * - 'onChange': Re-validate on every change (default)
@@ -740,7 +777,14 @@ interface FormConfig {
740
777
  * - 'onSubmit': Re-validate only on submit
741
778
  * @default 'onChange'
742
779
  */
743
- reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';
780
+ reValidateMode?: "onChange" | "onBlur" | "onSubmit";
781
+ /**
782
+ * Default output configuration for all forms.
783
+ * Controls the shape of data passed to onSubmit.
784
+ * Can be overridden per-form via UseFormOptions.
785
+ * @default undefined (hierarchical JSON)
786
+ */
787
+ output?: OutputConfig;
744
788
  }
745
789
  /**
746
790
  * Options passed to useForm hook.
@@ -785,12 +829,19 @@ interface UseFormOptions<TData = Record<string, unknown>> {
785
829
  * Override the validation mode for this form.
786
830
  * Uses provider's mode if not specified.
787
831
  */
788
- mode?: 'onChange' | 'onBlur' | 'onSubmit';
832
+ mode?: "onChange" | "onBlur" | "onSubmit";
789
833
  /**
790
834
  * Override the re-validation mode for this form.
791
835
  * Uses provider's reValidateMode if not specified.
792
836
  */
793
- reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';
837
+ reValidateMode?: "onChange" | "onBlur" | "onSubmit";
838
+ /**
839
+ * Output configuration for this form.
840
+ * Overrides the provider-level output config.
841
+ * Controls the shape of data passed to onSubmit.
842
+ * @default undefined (defaults to hierarchical JSON if not specified here or in Provider)
843
+ */
844
+ output?: OutputConfig;
794
845
  /**
795
846
  * Form behavior settings.
796
847
  */
@@ -1173,4 +1224,4 @@ type AdapterFactory<TData = Record<string, unknown>> = (options: AdapterOptions<
1173
1224
  */
1174
1225
  declare function validateAdapter(adapter: FormAdapter, adapterName?: string): void;
1175
1226
 
1176
- export { type ArrayHelpers as A, type BaseField as B, type ConditionContext as C, type DateField as D, type EmailField as E, type Field as F, type GroupField as G, type RowField as H, type Tab as I, type TabsField as J, type CollapsibleField as K, type FieldType as L, type DataField as M, type NumberField as N, type LayoutField as O, type PasswordField as P, type BuzzFormSchema as Q, type ResolverResult as R, type SetValueOptions as S, type TextField as T, type UseFormOptions as U, type ValidationContext as V, type FormSettings as W, type FormConfig as a, type FormAdapter as b, type FormState as c, type FieldError as d, type Resolver as e, type AdapterOptions as f, type AdapterFactory as g, type ValidationResult as h, type ValidationFn as i, type FieldCondition as j, type FieldComponentProps as k, type FieldInputProps as l, type FieldInputRenderFn as m, type FieldStyle as n, type TextareaField as o, type DatetimeField as p, type SelectOption as q, type SelectField as r, type CheckboxGroupField as s, type CheckboxField as t, type SwitchField as u, validateAdapter as v, type RadioField as w, type TagsField as x, type UploadField as y, type ArrayField as z };
1227
+ export { type ArrayHelpers as A, type BaseField as B, type ConditionContext as C, type DateField as D, type EmailField as E, type Field as F, type GroupField as G, type RowField as H, type Tab as I, type TabsField as J, type CollapsibleField as K, type FieldType as L, type DataField as M, type NumberField as N, type OutputConfig as O, type PasswordField as P, type LayoutField as Q, type ResolverResult as R, type SetValueOptions as S, type TextField as T, type UseFormOptions as U, type ValidationContext as V, type BuzzFormSchema as W, type FormSettings as X, type OutputType as Y, type PathDelimiter as Z, type FormConfig as a, type FormAdapter as b, type FormState as c, type FieldError as d, type Resolver as e, type AdapterOptions as f, type AdapterFactory as g, type ValidationResult as h, type ValidationFn as i, type FieldCondition as j, type FieldComponentProps as k, type FieldInputProps as l, type FieldInputRenderFn as m, type FieldStyle as n, type TextareaField as o, type DatetimeField as p, type SelectOption as q, type SelectField as r, type CheckboxGroupField as s, type CheckboxField as t, type SwitchField as u, validateAdapter as v, type RadioField as w, type TagsField as x, type UploadField as y, type ArrayField as z };
@@ -228,18 +228,18 @@ function createCheckboxGroupFieldSchema(field) {
228
228
  // src/schema/builders/boolean.ts
229
229
  import { z as z5 } from "zod";
230
230
  function createCheckboxFieldSchema(field) {
231
- let schema = z5.boolean({ error: "Invalid value" });
231
+ let schema = z5.boolean({ error: "Invalid value" }).default(false);
232
232
  if (field.required) {
233
- schema = z5.boolean({ error: "This field is required" }).refine((val) => val === true, {
233
+ schema = z5.boolean({ error: "Invalid value" }).default(false).refine((val) => val === true, {
234
234
  error: "This field is required"
235
235
  });
236
236
  }
237
237
  return schema;
238
238
  }
239
239
  function createSwitchFieldSchema(field) {
240
- let schema = z5.boolean({ error: "Invalid value" });
240
+ let schema = z5.boolean({ error: "Invalid value" }).default(false);
241
241
  if (field.required) {
242
- schema = z5.boolean({ error: "This field is required" }).refine((val) => val === true, {
242
+ schema = z5.boolean({ error: "Invalid value" }).default(false).refine((val) => val === true, {
243
243
  error: "This field is required"
244
244
  });
245
245
  }
@@ -469,4 +469,4 @@ export {
469
469
  fieldsToZodSchema,
470
470
  createSchema
471
471
  };
472
- //# sourceMappingURL=chunk-ATZ2HTUS.mjs.map
472
+ //# sourceMappingURL=chunk-HF6HN7X5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema/fields-to-schema.ts","../src/schema/builders/text.ts","../src/schema/builders/number.ts","../src/schema/builders/date.ts","../src/schema/builders/select.ts","../src/schema/builders/boolean.ts","../src/schema/builders/upload.ts","../src/schema/builders/tags.ts","../src/schema/builders/composite.ts","../src/schema/create-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type {\n Field,\n TabsField,\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectField,\n CheckboxGroupField,\n RadioField,\n CheckboxField,\n SwitchField,\n UploadField,\n TagsField,\n ArrayField,\n GroupField,\n FieldsToShape,\n} from \"../types\";\nimport {\n createTextFieldSchema,\n createEmailFieldSchema,\n createPasswordFieldSchema,\n createNumberFieldSchema,\n createDateFieldSchema,\n createSelectFieldSchema,\n createCheckboxGroupFieldSchema,\n createRadioFieldSchema,\n createCheckboxFieldSchema,\n createSwitchFieldSchema,\n createUploadFieldSchema,\n createTagsFieldSchema,\n createArrayFieldSchema,\n createGroupFieldSchema,\n} from \"./builders\";\n\nfunction fieldToZod(field: Field): z.ZodTypeAny {\n if (\"schema\" in field && field.schema) {\n return field.schema as z.ZodTypeAny;\n }\n\n switch (field.type) {\n case \"text\":\n return createTextFieldSchema(field as TextField);\n case \"email\":\n return createEmailFieldSchema(field as EmailField);\n case \"password\":\n return createPasswordFieldSchema(field as PasswordField);\n case \"textarea\":\n return createTextFieldSchema(field as TextareaField);\n case \"number\":\n return createNumberFieldSchema(field as NumberField);\n case \"date\":\n case \"datetime\":\n return createDateFieldSchema(field as DateField | DatetimeField);\n case \"select\":\n return createSelectFieldSchema(field as SelectField);\n case \"checkbox-group\":\n return createCheckboxGroupFieldSchema(field as CheckboxGroupField);\n case \"radio\":\n return createRadioFieldSchema(field as RadioField);\n case \"checkbox\":\n return createCheckboxFieldSchema(field as CheckboxField);\n case \"switch\":\n return createSwitchFieldSchema(field as SwitchField);\n case \"upload\":\n return createUploadFieldSchema(field as UploadField);\n case \"tags\":\n return createTagsFieldSchema(field as TagsField);\n case \"array\":\n return createArrayFieldSchema(field as ArrayField, fieldsToZodSchema);\n case \"group\":\n return createGroupFieldSchema(field as GroupField, fieldsToZodSchema);\n case \"row\":\n case \"collapsible\":\n case \"tabs\":\n return z.any();\n default:\n return z.any();\n }\n}\n\nfunction processTabsField(field: TabsField): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const tab of field.tabs) {\n if (tab.name) {\n const tabSchema = fieldsToZodSchema(tab.fields);\n shape[tab.name] = tabSchema;\n } else {\n const tabFieldsSchema = fieldsToZodSchema(tab.fields);\n if (tabFieldsSchema instanceof z.ZodObject) {\n Object.assign(shape, tabFieldsSchema.shape);\n }\n }\n }\n\n return shape;\n}\n\n/**\n * Converts field definitions to a Zod schema.\n *\n * Note: Custom validation (field.validate) is handled by the zodResolver,\n * not at the schema level. This ensures custom validators run even when\n * other fields have errors.\n */\nexport function fieldsToZodSchema<T extends readonly Field[]>(\n fields: T,\n): z.ZodObject<FieldsToShape<T>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if (\"name\" in field && field.name) {\n shape[field.name] = fieldToZod(field);\n } else if (field.type === \"tabs\") {\n const tabsShape = processTabsField(field);\n Object.assign(shape, tabsShape);\n } else if (field.type === \"row\" || field.type === \"collapsible\") {\n const nestedSchema = fieldsToZodSchema(field.fields);\n if (nestedSchema instanceof z.ZodObject) {\n Object.assign(shape, nestedSchema.shape);\n }\n }\n }\n\n return z.object(shape) as z.ZodObject<FieldsToShape<T>>;\n}\n","import { z } from 'zod';\nimport type { TextField, EmailField, TextareaField, PasswordField } from '../../types';\nimport { makeOptional, getPatternErrorMessage } from '../helpers';\n\nexport function createTextFieldSchema(field: TextField | TextareaField): z.ZodTypeAny {\n let schema = z.string({ error: 'This field is required' });\n\n if ('pattern' in field && field.pattern) {\n const pattern = typeof field.pattern === 'string'\n ? new RegExp(field.pattern)\n : field.pattern;\n\n schema = schema.regex(pattern, {\n error: getPatternErrorMessage(field.pattern),\n });\n }\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'This field is required' });\n }\n\n let finalSchema: z.ZodTypeAny = schema;\n if ('trim' in field && field.trim) {\n finalSchema = z.preprocess((val) => {\n return typeof val === 'string' ? val.trim() : val;\n }, schema);\n }\n\n if (!field.required) {\n return makeOptional(finalSchema, field.type);\n }\n\n return finalSchema;\n}\n\nexport function createEmailFieldSchema(field: EmailField): z.ZodTypeAny {\n // Zod v4: z.email() for email validation with custom error\n let schema = z.email({ error: 'Invalid email address' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'Email is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'email');\n }\n\n return schema;\n}\n\nexport function createPasswordFieldSchema(field: PasswordField): z.ZodTypeAny {\n // Zod v4: provide error message for invalid_type\n let schema = z.string({ error: 'Password is required' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Password must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Password must be no more than ${field.maxLength} characters`,\n });\n }\n if (field.required) {\n schema = schema.min(1, { error: 'Password is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'password');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { NumberField } from '../../types';\nimport { coerceToNumber, makeOptional } from '../helpers';\n\n/**\n * Creates Zod schema for number fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createNumberFieldSchema(field: NumberField): z.ZodTypeAny {\n let numSchema = z.number({ error: 'Must be a number' });\n\n // Min/max constraints\n if (field.min !== undefined) {\n numSchema = numSchema.min(field.min, `Must be at least ${field.min}`);\n }\n if (field.max !== undefined) {\n numSchema = numSchema.max(field.max, `Must be at most ${field.max}`);\n }\n\n // Coercion: empty/null/undefined → undefined, otherwise Number()\n const schema: z.ZodTypeAny = z.preprocess(coerceToNumber, numSchema);\n\n if (field.required) {\n return schema;\n }\n\n return makeOptional(schema, 'number');\n}\n","import { z } from 'zod';\nimport type { DateField, DatetimeField } from '../../types';\nimport { coerceToDate, makeOptional } from '../helpers';\n\n/**\n * Parse a value to a Date object for constraint checking.\n */\nfunction toDate(value?: string | Date): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n}\n\n/**\n * Creates Zod schema for date and datetime fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createDateFieldSchema(field: DateField | DatetimeField): z.ZodTypeAny {\n const isDatetime = field.type === 'datetime';\n\n // Parse min/max dates from field config\n const minDate = toDate(field.minDate);\n const maxDate = toDate(field.maxDate);\n\n // Build base date schema\n let dateSchema = z.date({ error: 'Please enter a valid date' });\n\n // Add min date constraint\n if (minDate) {\n const formattedDate = isDatetime ? minDate.toLocaleString() : minDate.toDateString();\n dateSchema = dateSchema.min(minDate, {\n error: `Date must be on or after ${formattedDate}`,\n });\n }\n\n // Add max date constraint\n if (maxDate) {\n const formattedDate = isDatetime ? maxDate.toLocaleString() : maxDate.toDateString();\n dateSchema = dateSchema.max(maxDate, {\n error: `Date must be on or before ${formattedDate}`,\n });\n }\n\n // Coercion from various input types\n const schema: z.ZodTypeAny = z.preprocess(coerceToDate, dateSchema);\n\n if (field.required) {\n return schema.refine(\n (val) => val instanceof Date && !isNaN(val.getTime()),\n 'Date is required'\n );\n }\n\n return makeOptional(schema, 'date');\n}\n","import { z } from \"zod\";\nimport type { SelectField, RadioField, CheckboxGroupField } from \"../../types\";\nimport { makeOptional } from \"../helpers\";\n\n// Base schema for select/radio values with user-friendly error messages\nconst selectValueSchema = z.union(\n [\n z.string({ error: \"Please select an option\" }),\n z.number({ error: \"Please select an option\" }),\n z.boolean({ error: \"Please select an option\" }),\n ],\n { error: \"Please select an option\" },\n);\n\ntype MultiSelectConfig = {\n minSelected?: number;\n maxSelected?: number;\n required?: boolean;\n};\n\nfunction applyMultiSelectConstraints(\n schema: z.ZodArray<typeof selectValueSchema>,\n config: MultiSelectConfig,\n): z.ZodArray<typeof selectValueSchema> {\n const { minSelected, maxSelected, required } = config;\n let next = schema;\n\n if (minSelected !== undefined && minSelected > 0) {\n const minMsg = `Select at least ${minSelected} option${minSelected !== 1 ? \"s\" : \"\"}`;\n if (required) {\n next = next.min(minSelected, minMsg);\n } else {\n // Optional multi-selects should allow no selection, but enforce min once user starts selecting.\n next = next.refine(\n (val) => val.length === 0 || val.length >= minSelected,\n {\n message: minMsg,\n },\n );\n }\n }\n\n if (required && (minSelected === undefined || minSelected === 0)) {\n next = next.min(1, \"Select at least one option\");\n }\n\n if (maxSelected !== undefined) {\n next = next.max(\n maxSelected,\n `Select at most ${maxSelected} option${maxSelected !== 1 ? \"s\" : \"\"}`,\n );\n }\n\n return next;\n}\n\nexport function createSelectFieldSchema(field: SelectField): z.ZodTypeAny {\n if (field.hasMany) {\n let arraySchema = z.array(selectValueSchema, {\n error: \"Invalid selection\",\n });\n arraySchema = applyMultiSelectConstraints(arraySchema, {\n minSelected: field.minSelected,\n maxSelected: field.maxSelected,\n required: field.required,\n });\n\n if (!field.required) {\n return arraySchema.optional().default([]);\n }\n return arraySchema;\n }\n\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== \"\" && val !== null && val !== undefined,\n \"Please select an option\",\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, \"select\");\n }\n\n return schema;\n}\n\nexport function createRadioFieldSchema(field: RadioField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== \"\" && val !== null && val !== undefined,\n \"Please select an option\",\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, \"radio\");\n }\n\n return schema;\n}\n\nexport function createCheckboxGroupFieldSchema(\n field: CheckboxGroupField,\n): z.ZodTypeAny {\n let schema = z.array(selectValueSchema, { error: \"Invalid selection\" });\n schema = applyMultiSelectConstraints(schema, {\n minSelected: field.minSelected,\n maxSelected: field.maxSelected,\n required: field.required,\n });\n\n if (!field.required) {\n return makeOptional(schema, \"checkbox-group\");\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { CheckboxField, SwitchField } from '../../types';\n\nexport function createCheckboxFieldSchema(field: CheckboxField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' }).default(false);\n\n if (field.required) {\n schema = z.boolean({ error: 'Invalid value' }).default(false).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n\nexport function createSwitchFieldSchema(field: SwitchField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' }).default(false);\n\n if (field.required) {\n schema = z.boolean({ error: 'Invalid value' }).default(false).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { UploadField } from '../../types';\n\nfunction matchesMimePattern(fileType: string, pattern: string): boolean {\n const normalizedPattern = pattern.toLowerCase().trim();\n const normalizedType = fileType.toLowerCase();\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.replace('/*', '');\n return normalizedType.startsWith(category + '/');\n }\n\n if (normalizedPattern.startsWith('.')) {\n return true;\n }\n\n return normalizedType === normalizedPattern;\n}\n\nfunction isFileTypeAccepted(file: File, acceptPatterns: string[]): boolean {\n if (!file.type) return true;\n return acceptPatterns.some(pattern => matchesMimePattern(file.type, pattern));\n}\n\nexport function createUploadFieldSchema(field: UploadField): z.ZodTypeAny {\n let fileSchema: z.ZodTypeAny = z.file({ error: 'Please select a file' });\n\n if (field.maxSize) {\n const sizeMB = (field.maxSize / 1024 / 1024).toFixed(1);\n fileSchema = (fileSchema as z.ZodFile).max(field.maxSize, {\n error: `File must be smaller than ${sizeMB}MB`,\n });\n }\n\n const accept = field.ui?.accept;\n if (accept && accept !== '*') {\n const acceptPatterns = accept.split(',').map(t => t.trim());\n const hasWildcard = acceptPatterns.some(p => p.includes('*') || p.startsWith('.'));\n\n if (hasWildcard) {\n fileSchema = fileSchema.refine(\n (file) => isFileTypeAccepted(file as File, acceptPatterns),\n `File type not allowed. Accepted: ${accept}`\n );\n } else {\n fileSchema = (fileSchema as z.ZodFile).mime(acceptPatterns, {\n error: `File type not allowed. Accepted: ${accept}`,\n });\n }\n }\n\n const fileOrUrl = z.union([\n fileSchema,\n z.string({ error: 'Invalid file' }),\n ], { error: 'Please select a file' });\n\n if (field.hasMany) {\n let arraySchema = z.array(fileOrUrl, { error: 'Invalid files' });\n\n if (field.minFiles !== undefined && field.minFiles > 0) {\n arraySchema = arraySchema.min(field.minFiles, {\n error: `At least ${field.minFiles} file(s) required`,\n });\n }\n\n if (field.maxFiles !== undefined) {\n arraySchema = arraySchema.max(field.maxFiles, {\n error: `Maximum ${field.maxFiles} file(s) allowed`,\n });\n }\n\n if (field.required) {\n arraySchema = arraySchema.min(1, {\n error: 'At least one file is required',\n });\n return arraySchema;\n }\n\n return arraySchema.optional().default([]);\n }\n\n if (field.required) {\n return fileOrUrl;\n }\n\n return fileOrUrl.optional().nullable();\n}\n","import { z } from 'zod';\nimport type { TagsField } from '../../types';\n\nexport function createTagsFieldSchema(field: TagsField): z.ZodTypeAny {\n const tagSchema = z.string({ error: 'Invalid tag' });\n let schema = z.array(tagSchema, { error: 'Invalid tags' });\n\n if (field.minTags !== undefined) {\n schema = schema.min(field.minTags, `At least ${field.minTags} tag(s) required`);\n }\n if (field.maxTags !== undefined) {\n schema = schema.max(field.maxTags, `Maximum ${field.maxTags} tag(s) allowed`);\n }\n\n if (field.required) {\n return schema.refine(\n (arr) => Array.isArray(arr) && arr.length > 0,\n 'At least one tag is required'\n );\n }\n\n return schema.optional().default([]);\n}\n","import { z } from 'zod';\nimport type { ArrayField, GroupField, Field } from '../../types';\n\n// Note: These import from the parent module to avoid circular deps\n// The fieldsToZodSchema function is passed as a parameter\n\ntype SchemaGenerator = (fields: readonly Field[]) => z.ZodObject<z.ZodRawShape>;\n\n/**\n * Creates Zod schema for array fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createArrayFieldSchema(\n field: ArrayField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const itemSchema = fieldsToZodSchema(field.fields);\n let schema = z.array(itemSchema);\n\n if (field.minRows !== undefined) {\n schema = schema.min(\n field.minRows,\n `At least ${field.minRows} row${field.minRows !== 1 ? 's' : ''} required`\n );\n }\n if (field.maxRows !== undefined) {\n schema = schema.max(\n field.maxRows,\n `Maximum ${field.maxRows} row${field.maxRows !== 1 ? 's' : ''} allowed`\n );\n }\n\n if (field.required) {\n return schema;\n }\n\n return schema.optional().default([]);\n}\n\n/**\n * Creates Zod schema for group fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createGroupFieldSchema(\n field: GroupField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const schema = fieldsToZodSchema(field.fields);\n\n if (!field.required) {\n return schema.optional();\n }\n\n return schema;\n}","import { type z } from 'zod';\nimport type { Field, FieldsToShape } from '../types';\nimport type { StrictFieldArray } from '../types/strict-fields';\nimport { fieldsToZodSchema } from './fields-to-schema';\n\n/**\n * Creates a Zod schema from field definitions with strict type validation.\n *\n * @example\n * const schema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type FormData = z.infer<typeof schema>;\n */\nexport function createSchema<const T extends readonly Field[]>(\n fields: StrictFieldArray<T> & T\n): z.ZodObject<FieldsToShape<T>> & { fields: T } {\n const schema = fieldsToZodSchema(fields as unknown as T);\n return Object.assign(schema, { fields }) as z.ZodObject<FieldsToShape<T>> & { fields: T };\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","fieldsToZodSchema","z"]}
@@ -253,6 +253,40 @@ function parseToDate(value) {
253
253
  return void 0;
254
254
  }
255
255
 
256
+ // src/lib/output.ts
257
+ function transformFormOutput(data, config) {
258
+ if (!config || config.type !== "path") {
259
+ return data;
260
+ }
261
+ if (typeof data !== "object" || data === null) {
262
+ return data;
263
+ }
264
+ return flattenToPathKeys(
265
+ data,
266
+ config.delimiter ?? "."
267
+ );
268
+ }
269
+ function flattenToPathKeys(data, delimiter, prefix = "") {
270
+ const result = {};
271
+ for (const [key, value] of Object.entries(data)) {
272
+ const path = prefix ? `${prefix}${delimiter}${key}` : key;
273
+ if (isPlainObject(value)) {
274
+ Object.assign(
275
+ result,
276
+ flattenToPathKeys(value, delimiter, path)
277
+ );
278
+ } else {
279
+ result[path] = value;
280
+ }
281
+ }
282
+ return result;
283
+ }
284
+ function isPlainObject(value) {
285
+ if (typeof value !== "object" || value === null) return false;
286
+ const proto = Object.getPrototypeOf(value);
287
+ return proto === Object.prototype || proto === null;
288
+ }
289
+
256
290
  export {
257
291
  createArrayHelpers,
258
292
  generateFieldId,
@@ -274,6 +308,7 @@ export {
274
308
  applyNumericPrecision,
275
309
  formatNumberWithSeparator,
276
310
  parseFormattedNumber,
277
- parseToDate
311
+ parseToDate,
312
+ transformFormOutput
278
313
  };
279
- //# sourceMappingURL=chunk-VXG7KGOZ.mjs.map
314
+ //# sourceMappingURL=chunk-P5XPEIIF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/array.ts","../src/lib/utils.ts","../src/lib/field.ts","../src/lib/output.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type { ArrayHelpers } from '../types';\n\n/**\n * Creates a standardized set of array field manipulation methods.\n * Abstracts the difference between getting/setting values in different form libraries.\n * \n * @param getArray - Function to get current array value at a path\n * @param setArray - Function to set array value at a path\n */\nexport function createArrayHelpers(\n getArray: (path: string) => unknown,\n setArray: (path: string, value: unknown[]) => void\n): ArrayHelpers {\n const readArray = (path: string): unknown[] => {\n const value = getArray(path);\n return Array.isArray(value) ? value : [];\n };\n\n return {\n fields: <T = unknown>(path: string): Array<T & { id: string }> => {\n const arr = readArray(path);\n return arr.map((item, index) => {\n const itemObject =\n typeof item === 'object' && item !== null\n ? (item as Record<string, unknown>)\n : ({ value: item } as Record<string, unknown>);\n\n return {\n id: (itemObject.id as string) || `${path}-${index}`,\n ...(itemObject as T),\n };\n });\n },\n\n append: (path: string, value: unknown) => {\n const current = readArray(path);\n const itemWithId = ensureId(value);\n setArray(path, [...current, itemWithId]);\n },\n\n prepend: (path: string, value: unknown) => {\n const current = readArray(path);\n const itemWithId = ensureId(value);\n setArray(path, [itemWithId, ...current]);\n },\n\n insert: (path: string, index: number, value: unknown) => {\n const current = [...readArray(path)];\n const itemWithId = ensureId(value);\n current.splice(index, 0, itemWithId);\n setArray(path, current);\n },\n\n remove: (path: string, index: number) => {\n const current = [...readArray(path)];\n current.splice(index, 1);\n setArray(path, current);\n },\n\n move: (path: string, from: number, to: number) => {\n const current = [...readArray(path)];\n const [item] = current.splice(from, 1);\n current.splice(to, 0, item);\n setArray(path, current);\n },\n\n swap: (path: string, indexA: number, indexB: number) => {\n const current = [...readArray(path)];\n const temp = current[indexA];\n current[indexA] = current[indexB];\n current[indexB] = temp;\n setArray(path, current);\n },\n\n replace: (path: string, values: unknown[]) => {\n const itemsWithIds = values.map(ensureId);\n setArray(path, itemsWithIds);\n },\n\n update: (path: string, index: number, value: unknown) => {\n const current = [...readArray(path)];\n // Preserve existing ID if present\n const existingId = (current[index] as Record<string, unknown>)?.id;\n current[index] = {\n ...(typeof value === 'object' && value !== null ? value : {}),\n id: existingId || nanoid(),\n };\n setArray(path, current);\n },\n };\n}\n\n/**\n * Ensures an item has a unique ID for React keys.\n */\nfunction ensureId(value: unknown): unknown {\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n if (!obj.id) {\n return { ...obj, id: nanoid() };\n }\n return obj;\n }\n return { value, id: nanoid() };\n}\n","// =============================================================================\n// COMMON UTILITIES\n// These are used by both the core package and registry field components.\n// =============================================================================\n\n/**\n * Generate a unique field ID from the field path.\n * Converts dot notation to dashes and prefixes with 'field-'.\n * Used for accessibility (htmlFor, id attributes).\n * \n * @example\n * generateFieldId('user.profile.email') => 'field-user-profile-email'\n * generateFieldId('items[0].name') => 'field-items-0-name'\n */\nexport function generateFieldId(path: string): string {\n return `field-${path.replace(/\\./g, \"-\").replace(/\\[/g, \"-\").replace(/\\]/g, \"\")}`;\n}\n\n/**\n * Safely retrieve a nested value from an object using a dot-notation path.\n * \n * @example\n * getNestedValue({ user: { name: 'John' } }, 'user.name') => 'John'\n * getNestedValue({ items: [{ id: 1 }] }, 'items.0.id') => 1\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce<unknown>((acc: unknown, key: string) => {\n if (acc && typeof acc === \"object\" && acc !== null) {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Set a nested value in an object using a dot-notation path.\n * Creates intermediate objects/arrays as needed.\n * \n * @example\n * setNestedValue({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function setNestedValue<T extends Record<string, unknown>>(\n obj: T,\n path: string,\n value: unknown\n): T {\n const keys = path.split(\".\");\n const result = { ...obj } as Record<string, unknown>;\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== \"object\") {\n // Check if next key is numeric (array index)\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n } else {\n current[key] = Array.isArray(current[key])\n ? [...(current[key] as unknown[])]\n : { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result as T;\n}\n\n/**\n * Format bytes into a human-readable string.\n * \n * @example\n * formatBytes(1024) => '1 KB'\n * formatBytes(1234567) => '1.18 MB'\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Flatten a nested object to dot-notation paths.\n * Useful for converting form library state (like dirtyFields, touchedFields)\n * to the flat format expected by FormState.\n * \n * @example\n * flattenNestedObject({ user: { name: true, email: true } })\n * // => { 'user.name': true, 'user.email': true }\n * \n * flattenNestedObject({ items: { 0: { title: true } } })\n * // => { 'items.0.title': true }\n */\nexport function flattenNestedObject(\n obj: Record<string, unknown>,\n prefix = ''\n): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n\n for (const key in obj) {\n const path = prefix ? `${prefix}.${key}` : key;\n const value = obj[key];\n\n if (typeof value === 'boolean') {\n result[path] = value;\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenNestedObject(value as Record<string, unknown>, path));\n }\n }\n\n return result;\n}\n\n","import type { ReactNode } from 'react';\nimport type { Field } from '../types';\n\n// =============================================================================\n// FIELD PATH UTILITIES\n// These utilities help work with nested field definitions and form data.\n// =============================================================================\n\n/**\n * Recursively extracts all field paths from a field definition tree.\n * Handles nested groups, arrays, and layout fields (rows, tabs, collapsibles).\n * \n * @param fields - Array of field definitions\n * @param basePath - Base path prefix (e.g., \"contacts.0\" for array items)\n * @returns Array of all field paths\n * \n * @example\n * const fields = [\n * { type: 'text', name: 'name' },\n * { type: 'group', name: 'address', fields: [\n * { type: 'text', name: 'city' },\n * { type: 'text', name: 'zip' }\n * ]}\n * ];\n * getNestedFieldPaths(fields, 'contact')\n * // => ['contact.name', 'contact.address', 'contact.address.city', 'contact.address.zip']\n */\nexport function getNestedFieldPaths(fields: Field[], basePath: string): string[] {\n const paths: string[] = [];\n\n for (const field of fields) {\n // Data fields with names\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n paths.push(fieldPath);\n\n // Recurse into group/array fields\n if (field.type === 'group' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n if (field.type === 'array' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n }\n\n // Layout fields (row, tabs, collapsible) - pass through without adding to path\n if ('fields' in field && field.type !== 'group' && field.type !== 'array') {\n const layoutField = field as Field & { fields: Field[] };\n paths.push(...getNestedFieldPaths(layoutField.fields, basePath));\n }\n\n // Tabs field - iterate through tabs\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name ? (basePath ? `${basePath}.${tab.name}` : tab.name) : basePath;\n paths.push(...getNestedFieldPaths(tab.fields, tabPath));\n }\n }\n }\n\n return paths;\n}\n\n/**\n * Count validation errors in nested fields.\n * Useful for showing error badges on collapsible sections, array rows, tabs, etc.\n * \n * @param errors - Form errors object from FormAdapter.formState.errors\n * @param fields - Field definitions to check\n * @param basePath - Base path for the fields\n * @returns Number of fields with errors\n * \n * @example\n * const errorCount = countNestedErrors(form.formState.errors, arrayField.fields, `items.0`);\n */\nexport function countNestedErrors(\n errors: Record<string, unknown>,\n fields: Field[],\n basePath: string\n): number {\n const paths = getNestedFieldPaths(fields, basePath);\n return paths.filter((path) => errors[path]).length;\n}\n\n/**\n * Resolve a potentially dynamic field property (disabled, readOnly, hidden).\n * These properties can be boolean or a function that receives form data.\n * \n * @param value - The property value (boolean or function)\n * @param formData - Current form data\n * @param siblingData - Data at the same level (for arrays, this is the row data)\n * @returns Resolved boolean value\n * \n * @example\n * const isDisabled = resolveFieldState(field.disabled, formData, siblingData);\n */\nexport function resolveFieldState<TData = Record<string, unknown>>(\n value: boolean | ((data: TData, siblingData: Record<string, unknown>) => boolean) | undefined,\n formData: TData,\n siblingData: Record<string, unknown> = formData as Record<string, unknown>\n): boolean {\n if (typeof value === 'function') {\n return value(formData, siblingData);\n }\n return Boolean(value);\n}\n\n/**\n * Get the label value for an array row based on field configuration.\n * First checks for a specific rowLabelField in ui options, then falls back\n * to the first named field's value.\n * \n * @param rowData - Data for the row\n * @param fields - Field definitions for the array\n * @param uiOptions - UI options that may contain rowLabelField\n * @param fallbackLabel - Default label if no value found\n * @returns Label string for the row\n * \n * @example\n * const label = getArrayRowLabel(rowData, field.fields, field.ui, `Item ${index + 1}`);\n */\nexport function getArrayRowLabel(\n rowData: Record<string, unknown> | undefined,\n fields: Field[],\n uiOptions: { rowLabelField?: string } | undefined,\n fallbackLabel: string\n): string {\n // First try explicit rowLabelField\n if (uiOptions?.rowLabelField && rowData?.[uiOptions.rowLabelField]) {\n return String(rowData[uiOptions.rowLabelField]);\n }\n\n // Fall back to first named field\n const firstNamedField = fields.find((f) => 'name' in f && f.name);\n if (firstNamedField && 'name' in firstNamedField) {\n const value = rowData?.[firstNamedField.name];\n if (value) {\n return String(value);\n }\n }\n\n return fallbackLabel;\n}\n\n// =============================================================================\n// FIELD STYLE UTILITIES\n// Helpers for computing field styling props.\n// =============================================================================\n\n/**\n * Compute the inline style object for a field's width.\n * Handles both numeric (px) and string (CSS) width values.\n * \n * @param style - Field style configuration\n * @returns CSS properties object or undefined if no width specified\n * \n * @example\n * <Field style={getFieldWidthStyle(field.style)}>\n * ...\n * </Field>\n */\nexport function getFieldWidthStyle(\n style: { width?: number | string } | undefined\n): { width: string } | undefined {\n if (!style?.width) return undefined;\n return {\n width: typeof style.width === 'number'\n ? `${style.width}px`\n : style.width,\n };\n}\n\n// =============================================================================\n// SELECT OPTION UTILITIES\n// Helpers for normalizing and extracting data from SelectOption | string.\n// =============================================================================\n\ntype SelectOptionLike = { value: string | number | boolean; label?: ReactNode; description?: ReactNode; icon?: ReactNode; disabled?: boolean } | string;\n\n/**\n * Normalize a select option to always be an object.\n * Converts string options to { value, label } objects.\n * \n * @param option - String or SelectOption object\n * @returns Normalized SelectOption object\n * \n * @example\n * normalizeSelectOption('foo') // => { value: 'foo', label: 'foo' }\n * normalizeSelectOption({ value: 'bar', label: 'Bar' }) // => { value: 'bar', label: 'Bar' }\n */\nexport function normalizeSelectOption(option: SelectOptionLike): {\n value: string | number | boolean;\n label: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n} {\n if (typeof option === 'string') {\n return { value: option, label: option };\n }\n return {\n value: option.value,\n label: option.label ?? String(option.value),\n description: option.description,\n icon: option.icon,\n disabled: option.disabled,\n };\n}\n\n/**\n * Get the value from a select option (handles string or object).\n * \n * @param option - String or SelectOption object\n * @returns The option's value as a string\n * \n * @example\n * getSelectOptionValue('foo') // => 'foo'\n * getSelectOptionValue({ value: 123, label: 'One Two Three' }) // => '123'\n */\nexport function getSelectOptionValue(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n const val = option.value;\n if (typeof val === 'boolean') return val ? 'true' : 'false';\n return String(val);\n}\n\n/**\n * Get the label from a select option (handles string or object).\n * Returns ReactNode to support JSX labels.\n * \n * @param option - String or SelectOption object\n * @returns The option's label for display\n * \n * @example\n * getSelectOptionLabel('foo') // => 'foo'\n * getSelectOptionLabel({ value: 'bar', label: <strong>Bar</strong> }) // => <strong>Bar</strong>\n */\nexport function getSelectOptionLabel(option: SelectOptionLike): ReactNode {\n if (typeof option === 'string') return option;\n return option.label ?? String(option.value);\n}\n\n/**\n * Get the string label from a select option (for filtering/comparison).\n * Always returns a string, not ReactNode.\n * \n * @param option - String or SelectOption object\n * @returns The option's label as a string\n */\nexport function getSelectOptionLabelString(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n if (typeof option.label === 'string') return option.label;\n return String(option.value);\n}\n\n/**\n * Check if a select option is disabled.\n * \n * @param option - String or SelectOption object\n * @returns true if option is disabled\n */\nexport function isSelectOptionDisabled(option: SelectOptionLike): boolean {\n if (typeof option === 'string') return false;\n return option.disabled === true;\n}\n\n// =============================================================================\n// NUMBER UTILITIES\n// Helpers for number field operations.\n// =============================================================================\n\n/**\n * Clamp a number between min and max bounds.\n * \n * @param value - The number to clamp\n * @param min - Minimum bound (optional)\n * @param max - Maximum bound (optional)\n * @returns Clamped number\n * \n * @example\n * clampNumber(5, 0, 10) // => 5\n * clampNumber(-5, 0, 10) // => 0\n * clampNumber(15, 0, 10) // => 10\n */\nexport function clampNumber(value: number, min?: number, max?: number): number {\n let result = value;\n if (min !== undefined && result < min) result = min;\n if (max !== undefined && result > max) result = max;\n return result;\n}\n\n/**\n * Apply numeric precision (decimal places) to a number.\n * \n * @param value - The number to format\n * @param precision - Number of decimal places\n * @returns Formatted number or undefined if input is undefined\n * \n * @example\n * applyNumericPrecision(3.14159, 2) // => 3.14\n * applyNumericPrecision(10, 2) // => 10\n */\nexport function applyNumericPrecision(\n value: number | undefined,\n precision?: number\n): number | undefined {\n if (value === undefined || precision === undefined) return value;\n return parseFloat(value.toFixed(precision));\n}\n\n/**\n * Format a number with thousand separators.\n * \n * @param value - The number to format\n * @param separator - Separator character (default: ',')\n * @returns Formatted string or empty string if value is undefined/NaN\n * \n * @example\n * formatNumberWithSeparator(1234567.89) // => '1,234,567.89'\n * formatNumberWithSeparator(1234567, ' ') // => '1 234 567'\n */\nexport function formatNumberWithSeparator(\n value: number | undefined,\n separator: string = ','\n): string {\n if (value === undefined || value === null || isNaN(value)) return '';\n const [intPart, decPart] = value.toString().split('.');\n const formattedInt = intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n return decPart !== undefined ? `${formattedInt}.${decPart}` : formattedInt;\n}\n\n/**\n * Parse a formatted number string back to a number.\n * \n * @param str - Formatted string with separators\n * @param separator - Separator character to remove\n * @returns Parsed number or undefined if invalid\n * \n * @example\n * parseFormattedNumber('1,234,567.89') // => 1234567.89\n * parseFormattedNumber('1 234 567', ' ') // => 1234567\n */\nexport function parseFormattedNumber(\n str: string,\n separator: string = ','\n): number | undefined {\n if (!str || str === '') return undefined;\n const cleaned = str.split(separator).join('');\n const num = parseFloat(cleaned);\n return isNaN(num) ? undefined : num;\n}\n\n// =============================================================================\n// DATE UTILITIES\n// Helpers for date field operations.\n// =============================================================================\n\n/**\n * Safely parse a value to a Date object.\n * Handles Date objects, ISO strings, and timestamps.\n * \n * @param value - Value to parse (Date, string, number, or unknown)\n * @returns Date object or undefined if invalid\n * \n * @example\n * parseToDate(new Date()) // => Date\n * parseToDate('2024-01-15') // => Date\n * parseToDate(null) // => undefined\n */\nexport function parseToDate(value: unknown): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) {\n return isNaN(value.getTime()) ? undefined : value;\n }\n if (typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n if (typeof value === 'string') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n return undefined;\n}\n","import type { OutputConfig } from \"../types\";\n\n/**\n * Transform form data into the configured output shape.\n *\n * NOTE: The input data (typically from RHF with GroupField) is already nested.\n * - 'flat' / 'nested' → pass through as-is (already nested)\n * - 'path' → flatten nested object into path-delimited keys\n */\nexport function transformFormOutput<TData>(\n data: TData,\n config?: OutputConfig,\n): TData {\n if (!config || config.type !== \"path\") {\n return data;\n }\n\n if (typeof data !== \"object\" || data === null) {\n return data;\n }\n\n return flattenToPathKeys(\n data as Record<string, unknown>,\n config.delimiter ?? \".\",\n ) as TData;\n}\n\n/**\n * Flatten a nested object into single-level keys using a delimiter.\n * Leaf values (primitives, arrays, Date, File, etc.) are NOT traversed.\n */\nfunction flattenToPathKeys(\n data: Record<string, unknown>,\n delimiter: string,\n prefix = \"\",\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n const path = prefix ? `${prefix}${delimiter}${key}` : key;\n\n if (isPlainObject(value)) {\n Object.assign(\n result,\n flattenToPathKeys(value as Record<string, unknown>, delimiter, path),\n );\n } else {\n result[path] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Check if a value is a plain object.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { F as Field, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-u4raoNx9.mjs';
2
- export { g as AdapterFactory, f as AdapterOptions, z as ArrayField, A as ArrayHelpers, B as BaseField, Q as BuzzFormSchema, t as CheckboxField, s as CheckboxGroupField, K as CollapsibleField, C as ConditionContext, M as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, L as FieldType, W as FormSettings, c as FormState, G as GroupField, O as LayoutField, N as NumberField, P as PasswordField, w as RadioField, e as Resolver, R as ResolverResult, H as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, u as SwitchField, I as Tab, J as TabsField, x as TagsField, T as TextField, o as TextareaField, y as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-u4raoNx9.mjs';
3
- export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-BksL2RlA.mjs';
1
+ import { F as Field, O as OutputConfig, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-Bd0fYuAE.mjs';
2
+ export { g as AdapterFactory, f as AdapterOptions, z as ArrayField, A as ArrayHelpers, B as BaseField, W as BuzzFormSchema, t as CheckboxField, s as CheckboxGroupField, K as CollapsibleField, C as ConditionContext, M as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, L as FieldType, X as FormSettings, c as FormState, G as GroupField, Q as LayoutField, N as NumberField, Y as OutputType, P as PasswordField, Z as PathDelimiter, w as RadioField, e as Resolver, R as ResolverResult, H as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, u as SwitchField, I as Tab, J as TabsField, x as TagsField, T as TextField, o as TextareaField, y as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-Bd0fYuAE.mjs';
3
+ export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-BsX0viz8.mjs';
4
4
  import * as React from 'react';
5
5
  import React__default, { ReactNode } from 'react';
6
6
  import 'zod';
@@ -212,6 +212,15 @@ declare function parseFormattedNumber(str: string, separator?: string): number |
212
212
  */
213
213
  declare function parseToDate(value: unknown): Date | undefined;
214
214
 
215
+ /**
216
+ * Transform form data into the configured output shape.
217
+ *
218
+ * NOTE: The input data (typically from RHF with GroupField) is already nested.
219
+ * - 'flat' / 'nested' → pass through as-is (already nested)
220
+ * - 'path' → flatten nested object into path-delimited keys
221
+ */
222
+ declare function transformFormOutput<TData>(data: TData, config?: OutputConfig): TData;
223
+
215
224
  /**
216
225
  * Provider for global form configuration.
217
226
  * Set the adapter, resolver, and default mode for all forms in the app.
@@ -267,4 +276,4 @@ declare const FormConfigContext: React.Context<FormConfig | null>;
267
276
  */
268
277
  declare function useForm<TData extends Record<string, unknown> = Record<string, unknown>>(options: UseFormOptions<TData>): FormAdapter<TData>;
269
278
 
270
- export { Field, FormAdapter, FormConfig, FormConfigContext, FormProvider, UseFormOptions, applyNumericPrecision, clampNumber, countNestedErrors, formatNumberWithSeparator, getArrayRowLabel, getFieldWidthStyle, getNestedFieldPaths, getSelectOptionLabel, getSelectOptionLabelString, getSelectOptionValue, isSelectOptionDisabled, normalizeSelectOption, parseFormattedNumber, parseToDate, resolveFieldState, useForm };
279
+ export { Field, FormAdapter, FormConfig, FormConfigContext, FormProvider, OutputConfig, UseFormOptions, applyNumericPrecision, clampNumber, countNestedErrors, formatNumberWithSeparator, getArrayRowLabel, getFieldWidthStyle, getNestedFieldPaths, getSelectOptionLabel, getSelectOptionLabelString, getSelectOptionValue, isSelectOptionDisabled, normalizeSelectOption, parseFormattedNumber, parseToDate, resolveFieldState, transformFormOutput, useForm };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { F as Field, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-u4raoNx9.js';
2
- export { g as AdapterFactory, f as AdapterOptions, z as ArrayField, A as ArrayHelpers, B as BaseField, Q as BuzzFormSchema, t as CheckboxField, s as CheckboxGroupField, K as CollapsibleField, C as ConditionContext, M as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, L as FieldType, W as FormSettings, c as FormState, G as GroupField, O as LayoutField, N as NumberField, P as PasswordField, w as RadioField, e as Resolver, R as ResolverResult, H as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, u as SwitchField, I as Tab, J as TabsField, x as TagsField, T as TextField, o as TextareaField, y as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-u4raoNx9.js';
3
- export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-oLqFuT9W.js';
1
+ import { F as Field, O as OutputConfig, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-Bd0fYuAE.js';
2
+ export { g as AdapterFactory, f as AdapterOptions, z as ArrayField, A as ArrayHelpers, B as BaseField, W as BuzzFormSchema, t as CheckboxField, s as CheckboxGroupField, K as CollapsibleField, C as ConditionContext, M as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, L as FieldType, X as FormSettings, c as FormState, G as GroupField, Q as LayoutField, N as NumberField, Y as OutputType, P as PasswordField, Z as PathDelimiter, w as RadioField, e as Resolver, R as ResolverResult, H as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, u as SwitchField, I as Tab, J as TabsField, x as TagsField, T as TextField, o as TextareaField, y as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-Bd0fYuAE.js';
3
+ export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-DHF346op.js';
4
4
  import * as React from 'react';
5
5
  import React__default, { ReactNode } from 'react';
6
6
  import 'zod';
@@ -212,6 +212,15 @@ declare function parseFormattedNumber(str: string, separator?: string): number |
212
212
  */
213
213
  declare function parseToDate(value: unknown): Date | undefined;
214
214
 
215
+ /**
216
+ * Transform form data into the configured output shape.
217
+ *
218
+ * NOTE: The input data (typically from RHF with GroupField) is already nested.
219
+ * - 'flat' / 'nested' → pass through as-is (already nested)
220
+ * - 'path' → flatten nested object into path-delimited keys
221
+ */
222
+ declare function transformFormOutput<TData>(data: TData, config?: OutputConfig): TData;
223
+
215
224
  /**
216
225
  * Provider for global form configuration.
217
226
  * Set the adapter, resolver, and default mode for all forms in the app.
@@ -267,4 +276,4 @@ declare const FormConfigContext: React.Context<FormConfig | null>;
267
276
  */
268
277
  declare function useForm<TData extends Record<string, unknown> = Record<string, unknown>>(options: UseFormOptions<TData>): FormAdapter<TData>;
269
278
 
270
- export { Field, FormAdapter, FormConfig, FormConfigContext, FormProvider, UseFormOptions, applyNumericPrecision, clampNumber, countNestedErrors, formatNumberWithSeparator, getArrayRowLabel, getFieldWidthStyle, getNestedFieldPaths, getSelectOptionLabel, getSelectOptionLabelString, getSelectOptionValue, isSelectOptionDisabled, normalizeSelectOption, parseFormattedNumber, parseToDate, resolveFieldState, useForm };
279
+ export { Field, FormAdapter, FormConfig, FormConfigContext, FormProvider, OutputConfig, UseFormOptions, applyNumericPrecision, clampNumber, countNestedErrors, formatNumberWithSeparator, getArrayRowLabel, getFieldWidthStyle, getNestedFieldPaths, getSelectOptionLabel, getSelectOptionLabelString, getSelectOptionValue, isSelectOptionDisabled, normalizeSelectOption, parseFormattedNumber, parseToDate, resolveFieldState, transformFormOutput, useForm };