@rachelallyson/hero-hook-form 2.13.0 → 2.15.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.15.0] - 2026-02-02
6
+
7
+ ### Added
8
+
9
+ - **ConfigProvider: autocomplete defaults** – `HeroHookFormDefaultsConfig` and `useHeroHookFormDefaults()` support `defaults.autocomplete`. `AutocompleteField` spreads these defaults so Autocomplete respects the same global styling (color, size, variant, radius, labelPlacement) as Input, Textarea, and Select when using `HeroHookFormProvider`.
10
+ - **createFieldArrayCustomConfig: readOnly** – New `readOnly?: boolean` option. When true, the add button (and empty-state add block) is not rendered. `readOnly` is passed into each item’s props so custom `renderItem` / `getItemFieldConfig` can hide remove/reorder controls. Use instead of `renderAddButton: () => null` for display-only arrays.
11
+
12
+ ### Fixed
13
+
14
+ - **ServerActionForm autocomplete options** – `AutocompleteItem` for autocomplete fields now receives `textValue={item.label ?? String(item.value)}` so options have a stable plain-text value for accessibility, type-to-select, and Cypress/automation even when using custom `renderItem`.
15
+
16
+ ### Changed
17
+
18
+ - **AutocompleteField** – Uses `useHeroHookFormDefaults()` and spreads `defaults.autocomplete` so the control picks up provider styling (e.g. `HeroHookFormProvider` with `defaults.common` or `defaults.autocomplete`).
19
+ - **Example: Custom Field Array Demo** – Uses `readOnly: true` instead of `renderAddButton: () => null`. E2E test added to assert “Add Item” is not shown when readOnly is true.
20
+
21
+ ## [2.14.0] - 2026-01-29
22
+
23
+ ### Added
24
+
25
+ - **Dynamic custom fields in field arrays** – When each array item can be a different control type (e.g. member custom field values: one row is a date, another a dropdown, another short text), you can use **getItemFieldConfig** with **createCustomFieldConfigForItem** instead of wiring multiple conditionals yourself.
26
+ - **getItemFieldConfig** – Pass this to `createFieldArrayCustomConfig`; for each item you return a single field config (or `null`). The library renders one field per item for you.
27
+ - **createCustomFieldConfigForItem(name, def)** – Given a field path and a definition with `fieldType` (e.g. `'DATE'`, `'SHORT_TEXT'`, `'LONG_TEXT'`, `'NUMBER'`, `'DROPDOWN'`), `name` (label), and optional `options` for dropdowns (newline-separated string or `{ label, value }[]`), returns the right config so you don’t write a switch or five conditionals per item.
28
+ - Use it in ZodForm by adding a `createFieldArrayCustomConfig` with `getItemFieldConfig: ({ field, index }) => createCustomFieldConfigForItem(\`items.\${index}.value\`, { fieldType: def.fieldType, name: def.name, options: def.options })` after looking up the definition for that item (e.g. by `customFieldId`). See the **Custom Field Array Demo** in the example app for a full example.
29
+
5
30
  ## [2.13.0] - 2026-01-29
6
31
 
7
32
  ### Added
package/dist/index.d.ts CHANGED
@@ -4179,6 +4179,67 @@ interface ArraySyncResult<TItem> {
4179
4179
  */
4180
4180
  declare function syncArrays<TItem>(options: ArraySyncOptions<TItem>): ArraySyncResult<TItem>;
4181
4181
 
4182
+ /**
4183
+ * Supported input types for dynamic custom fields (e.g. member custom field values).
4184
+ * Use with createCustomFieldConfigForItem so each array item can render the right control.
4185
+ */
4186
+ type CustomFieldInputType = "DATE" | "DROPDOWN" | "LONG_TEXT" | "NUMBER" | "SHORT_TEXT";
4187
+ /**
4188
+ * Minimal field definition for creating a single field config by type.
4189
+ * Matches common patterns where each array item has a type and label (e.g. customFieldId → field def).
4190
+ */
4191
+ interface CustomFieldDef {
4192
+ fieldType: CustomFieldInputType;
4193
+ name: string;
4194
+ /** For DROPDOWN: newline-separated string or array of { label, value } */
4195
+ options?: string | {
4196
+ label: string;
4197
+ value: string | number;
4198
+ }[];
4199
+ }
4200
+ /**
4201
+ * Create the right ZodFormFieldConfig for a single custom field by type.
4202
+ * Use inside createFieldArrayCustomConfig getItemFieldConfig (or renderItem) so each
4203
+ * array item renders one control (date, short text, long text, number, or dropdown)
4204
+ * instead of multiple conditionals.
4205
+ *
4206
+ * @param name - Form path for the value (e.g. `customFieldValues.${index}.value`)
4207
+ * @param def - Field definition with fieldType, name (label), and optional options for DROPDOWN
4208
+ * @returns ZodFormFieldConfig for use with FormField
4209
+ *
4210
+ * @example
4211
+ * ```tsx
4212
+ * createFieldArrayCustomConfig({
4213
+ * name: 'customFieldValues',
4214
+ * getItemFieldConfig: ({ field, form, index }) => {
4215
+ * const fieldDef = fields.find(f => f.id === field.customFieldId);
4216
+ * if (!fieldDef) return null;
4217
+ * return createCustomFieldConfigForItem(
4218
+ * `customFieldValues.${index}.value`,
4219
+ * { fieldType: fieldDef.fieldType, name: fieldDef.name, options: fieldDef.options }
4220
+ * );
4221
+ * },
4222
+ * defaultItem: () => ({ customFieldId: '', value: '' }),
4223
+ * });
4224
+ * ```
4225
+ */
4226
+ declare function createCustomFieldConfigForItem<T extends FieldValues>(name: Path<T>, def: CustomFieldDef): ZodFormFieldConfig<T>;
4227
+ /** Props passed to renderItem or getItemFieldConfig for each array item */
4228
+ interface FieldArrayItemRenderProps<TFieldValues extends FieldValues, TArrayPath extends ArrayPath<TFieldValues>> {
4229
+ index: number;
4230
+ field: FieldArrayWithId<TFieldValues, TArrayPath>;
4231
+ fields: FieldArrayWithId<TFieldValues, TArrayPath>[];
4232
+ form: UseFormReturn<TFieldValues>;
4233
+ control: Control<TFieldValues>;
4234
+ errors: FieldErrors<TFieldValues>;
4235
+ canMoveUp: boolean;
4236
+ canMoveDown: boolean;
4237
+ onMoveUp: () => void;
4238
+ onMoveDown: () => void;
4239
+ onRemove: () => void;
4240
+ /** When true, add/remove/reorder are hidden; use to hide your own buttons */
4241
+ readOnly?: boolean;
4242
+ }
4182
4243
  /**
4183
4244
  * Options for creating a custom field array config
4184
4245
  *
@@ -4189,20 +4250,15 @@ interface CreateFieldArrayCustomConfigOptions<TFieldValues extends FieldValues>
4189
4250
  name: ArrayPath<TFieldValues>;
4190
4251
  /** Optional label for the field array */
4191
4252
  label?: string;
4192
- /** Render function for each array item */
4193
- renderItem: (props: {
4194
- index: number;
4195
- field: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>;
4196
- fields: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>[];
4197
- form: UseFormReturn<TFieldValues>;
4198
- control: Control<TFieldValues>;
4199
- errors: FieldErrors<TFieldValues>;
4200
- canMoveUp: boolean;
4201
- canMoveDown: boolean;
4202
- onMoveUp: () => void;
4203
- onMoveDown: () => void;
4204
- onRemove: () => void;
4205
- }) => React$1.ReactNode;
4253
+ /**
4254
+ * Return a single field config for this item; the array helper will render one FormField.
4255
+ * Use with createCustomFieldConfigForItem when each item's control type depends on item data
4256
+ * (e.g. custom fields: look up field def by customFieldId, then createCustomFieldConfigForItem).
4257
+ * When provided, renderItem is optional.
4258
+ */
4259
+ getItemFieldConfig?: (props: FieldArrayItemRenderProps<TFieldValues, ArrayPath<TFieldValues>>) => ZodFormFieldConfig<TFieldValues> | null;
4260
+ /** Render function for each array item (optional if getItemFieldConfig is provided) */
4261
+ renderItem?: (props: FieldArrayItemRenderProps<TFieldValues, ArrayPath<TFieldValues>>) => React$1.ReactNode;
4206
4262
  /** Optional render function for add button */
4207
4263
  renderAddButton?: (props: {
4208
4264
  onAdd: () => void;
@@ -4216,6 +4272,8 @@ interface CreateFieldArrayCustomConfigOptions<TFieldValues extends FieldValues>
4216
4272
  max?: number;
4217
4273
  /** Enable reordering of array items */
4218
4274
  enableReordering?: boolean;
4275
+ /** When true, no add button is shown; readOnly is passed to renderItem/getItemFieldConfig so you can hide remove/reorder */
4276
+ readOnly?: boolean;
4219
4277
  /** Optional className */
4220
4278
  className?: string;
4221
4279
  }
@@ -4379,4 +4437,4 @@ declare const validationUtils: {
4379
4437
  }>;
4380
4438
  };
4381
4439
 
4382
- export { AdvancedFieldBuilder, type ArraySyncOptions, type ArraySyncResult, type AutocompleteDefaults, AutocompleteField, type AutocompleteFieldProps, type AutocompleteOption, type AutocompletePassthroughProps, type BaseFormFieldConfig, BasicFormBuilder, type BooleanFieldConfig, type ButtonDefaults, type CheckboxDefaults, CheckboxField, type CheckboxFieldProps, CheckboxGroupField, type CheckboxGroupFieldConfig, type CheckboxGroupFieldProps, type CheckboxGroupPassthroughProps, type CheckboxPassthroughProps, type CommonFieldDefaults, CommonFields, ConditionalField, type ConditionalFieldConfig, type ConditionalFieldProps, type ConditionalValidation, ConfigurableForm, ContentField, type ContentFieldConfig, type CreateFieldArrayCustomConfigOptions, type CustomFieldConfig, DateField, type DateFieldConfig, type DateFieldProps, type DateInputDefaults, type DateInputPassthroughProps, type DynamicSectionConfig, DynamicSectionField, type DynamicSectionFieldProps, type EnhancedFormState, FieldArrayBuilder, type FieldArrayConfig, FieldArrayField, type FieldArrayFieldProps, FieldArrayItemBuilder, type FieldBaseProps, type FieldCreationParams, type FieldGroup, FileField, type FileFieldConfig, type FileFieldProps, type FileInputPassthroughProps, FontPickerField, type FontPickerFieldConfig, type FontPickerFieldProps, type FormConfig, FormField, type FormFieldConfig, FormFieldHelpers, type FormFieldType, type FormProps, FormProvider, FormStatus, type FormStatusProps, type FormStep, type FormSubmissionState, type FormTestUtils, FormToast, type FormToastProps, type FormValidationError, type HeroHookFormDefaultsConfig, HeroHookFormProvider, type HeroHookFormProviderProps, type InputDefaults, InputField, type InputFieldProps, type InputPassthroughProps, type RadioFieldConfig, type RadioGroupDefaults, RadioGroupField, type RadioGroupFieldProps, type RadioGroupPassthroughProps, type SelectDefaults, SelectField, type SelectFieldProps, type SelectPassthroughProps, ServerActionForm, type ServerFieldError, type ServerFormError, SimpleForm, type SimpleFormProps, type SliderDefaults, SliderField, type SliderFieldConfig, type SliderFieldProps, type SliderPassthroughProps, type StringArrayFieldConfig, type StringFieldConfig, SubmitButton, type SubmitButtonProps, type SwitchDefaults, SwitchField, type SwitchFieldProps, type SwitchPassthroughProps, type TextareaDefaults, TextareaField, type TextareaFieldProps, type TextareaPassthroughProps, TypeInferredBuilder, type UseDebouncedValidationOptions, type UseEnhancedFormStateOptions, type UseInferredFormOptions, type ValidationUtils, type WithControl, type WizardFormConfig, ZodForm, type ZodFormConfig, type ZodFormFieldConfig, applyServerErrors, asyncValidation, commonValidations, createAdvancedBuilder, createBasicFormBuilder, createDateSchema, createEmailSchema, createField, createFieldArrayBuilder, createFieldArrayCustomConfig, createFieldArrayItemBuilder, createFileSchema, createFormTestUtils, createFutureDateSchema, createMaxLengthSchema, createMinLengthSchema, createMockFormData, createMockFormErrors, createNestedPathBuilder, createNumberRangeSchema, createOptimizedFieldHandler, createPasswordSchema, createPastDateSchema, createPhoneSchema, createRequiredCheckboxSchema, createRequiredSchema, createTypeInferredBuilder, createUrlSchema, createZodFormConfig, crossFieldValidation, debounce, deepEqual, defineInferredForm, errorMessages, field, getFieldError, getFormErrors, hasFieldError, hasFormErrors, memorySafeFieldArray, pathToString, serverValidation, shallowEqual, simulateFieldInput, simulateFormSubmission, suggestGarbageCollection, syncArrays, throttle, useDebouncedFieldValidation, useDebouncedValidation, useEnhancedFormState, useFieldArrayMemoryCleanup, useFormHelper, useHeroForm, useHeroHookFormDefaults, useInferredForm, useLazyFieldArrayRegistration, useLazyFieldRegistration, useMemoizedCallback, useMemoizedFieldProps, usePerformanceMonitor, useTypeInferredForm, useZodForm, validationPatterns, validationUtils, waitForFormState };
4440
+ export { AdvancedFieldBuilder, type ArraySyncOptions, type ArraySyncResult, type AutocompleteDefaults, AutocompleteField, type AutocompleteFieldProps, type AutocompleteOption, type AutocompletePassthroughProps, type BaseFormFieldConfig, BasicFormBuilder, type BooleanFieldConfig, type ButtonDefaults, type CheckboxDefaults, CheckboxField, type CheckboxFieldProps, CheckboxGroupField, type CheckboxGroupFieldConfig, type CheckboxGroupFieldProps, type CheckboxGroupPassthroughProps, type CheckboxPassthroughProps, type CommonFieldDefaults, CommonFields, ConditionalField, type ConditionalFieldConfig, type ConditionalFieldProps, type ConditionalValidation, ConfigurableForm, ContentField, type ContentFieldConfig, type CreateFieldArrayCustomConfigOptions, type CustomFieldConfig, type CustomFieldDef, type CustomFieldInputType, DateField, type DateFieldConfig, type DateFieldProps, type DateInputDefaults, type DateInputPassthroughProps, type DynamicSectionConfig, DynamicSectionField, type DynamicSectionFieldProps, type EnhancedFormState, FieldArrayBuilder, type FieldArrayConfig, FieldArrayField, type FieldArrayFieldProps, FieldArrayItemBuilder, type FieldArrayItemRenderProps, type FieldBaseProps, type FieldCreationParams, type FieldGroup, FileField, type FileFieldConfig, type FileFieldProps, type FileInputPassthroughProps, FontPickerField, type FontPickerFieldConfig, type FontPickerFieldProps, type FormConfig, FormField, type FormFieldConfig, FormFieldHelpers, type FormFieldType, type FormProps, FormProvider, FormStatus, type FormStatusProps, type FormStep, type FormSubmissionState, type FormTestUtils, FormToast, type FormToastProps, type FormValidationError, type HeroHookFormDefaultsConfig, HeroHookFormProvider, type HeroHookFormProviderProps, type InputDefaults, InputField, type InputFieldProps, type InputPassthroughProps, type RadioFieldConfig, type RadioGroupDefaults, RadioGroupField, type RadioGroupFieldProps, type RadioGroupPassthroughProps, type SelectDefaults, SelectField, type SelectFieldProps, type SelectPassthroughProps, ServerActionForm, type ServerFieldError, type ServerFormError, SimpleForm, type SimpleFormProps, type SliderDefaults, SliderField, type SliderFieldConfig, type SliderFieldProps, type SliderPassthroughProps, type StringArrayFieldConfig, type StringFieldConfig, SubmitButton, type SubmitButtonProps, type SwitchDefaults, SwitchField, type SwitchFieldProps, type SwitchPassthroughProps, type TextareaDefaults, TextareaField, type TextareaFieldProps, type TextareaPassthroughProps, TypeInferredBuilder, type UseDebouncedValidationOptions, type UseEnhancedFormStateOptions, type UseInferredFormOptions, type ValidationUtils, type WithControl, type WizardFormConfig, ZodForm, type ZodFormConfig, type ZodFormFieldConfig, applyServerErrors, asyncValidation, commonValidations, createAdvancedBuilder, createBasicFormBuilder, createCustomFieldConfigForItem, createDateSchema, createEmailSchema, createField, createFieldArrayBuilder, createFieldArrayCustomConfig, createFieldArrayItemBuilder, createFileSchema, createFormTestUtils, createFutureDateSchema, createMaxLengthSchema, createMinLengthSchema, createMockFormData, createMockFormErrors, createNestedPathBuilder, createNumberRangeSchema, createOptimizedFieldHandler, createPasswordSchema, createPastDateSchema, createPhoneSchema, createRequiredCheckboxSchema, createRequiredSchema, createTypeInferredBuilder, createUrlSchema, createZodFormConfig, crossFieldValidation, debounce, deepEqual, defineInferredForm, errorMessages, field, getFieldError, getFormErrors, hasFieldError, hasFormErrors, memorySafeFieldArray, pathToString, serverValidation, shallowEqual, simulateFieldInput, simulateFormSubmission, suggestGarbageCollection, syncArrays, throttle, useDebouncedFieldValidation, useDebouncedValidation, useEnhancedFormState, useFieldArrayMemoryCleanup, useFormHelper, useHeroForm, useHeroHookFormDefaults, useInferredForm, useLazyFieldArrayRegistration, useLazyFieldRegistration, useMemoizedCallback, useMemoizedFieldProps, usePerformanceMonitor, useTypeInferredForm, useZodForm, validationPatterns, validationUtils, waitForFormState };
package/dist/index.js CHANGED
@@ -231,8 +231,14 @@ function useHeroHookFormDefaults() {
231
231
  size: "md",
232
232
  variant: "bordered"
233
233
  };
234
+ const autocompleteBase = {
235
+ radius: "md",
236
+ size: "md",
237
+ variant: "bordered"
238
+ };
234
239
  return {
235
240
  autocomplete: {
241
+ ...autocompleteBase,
236
242
  ...commonAutocomplete,
237
243
  ...cfg.autocomplete ?? {}
238
244
  },
@@ -486,11 +492,16 @@ function AutocompleteField(props) {
486
492
  { isDisabled, label },
487
493
  { allowsCustomValue }
488
494
  );
495
+ const autocompleteMerged = { ...defaults.autocomplete };
496
+ for (const [key, value] of Object.entries(rest)) {
497
+ if (value !== void 0) {
498
+ autocompleteMerged[key] = value;
499
+ }
500
+ }
489
501
  return /* @__PURE__ */ React2.createElement("div", { className }, /* @__PURE__ */ React2.createElement(
490
502
  Autocomplete,
491
503
  {
492
- ...defaults.autocomplete,
493
- ...rest,
504
+ ...autocompleteMerged,
494
505
  ...defaultItems && {
495
506
  defaultItems
496
507
  },
@@ -3193,7 +3204,14 @@ function ServerActionField({
3193
3204
  onInputChange: setValue,
3194
3205
  items
3195
3206
  },
3196
- items.map((item) => /* @__PURE__ */ React21.createElement(AutocompleteItem, { key: String(item.value) }, typeof stringConfig.renderItem === "function" ? stringConfig.renderItem(item) : item.label))
3207
+ items.map((item) => /* @__PURE__ */ React21.createElement(
3208
+ AutocompleteItem,
3209
+ {
3210
+ key: String(item.value),
3211
+ textValue: item.label ?? String(item.value)
3212
+ },
3213
+ typeof stringConfig.renderItem === "function" ? stringConfig.renderItem(item) : item.label
3214
+ ))
3197
3215
  );
3198
3216
  }
3199
3217
  case "slider": {
@@ -5785,18 +5803,53 @@ function syncArrays(options) {
5785
5803
  import React27 from "react";
5786
5804
  import { useFieldArray as useFieldArray2 } from "react-hook-form";
5787
5805
  import { Button as Button6 } from "@heroui/react";
5806
+ function parseDropdownOptions(options) {
5807
+ if (options == null) return [];
5808
+ if (Array.isArray(options)) return options;
5809
+ return options.split("\n").map((o) => o.trim()).filter((o) => o.length > 0).map((o) => ({ label: o, value: o }));
5810
+ }
5811
+ function createCustomFieldConfigForItem(name, def) {
5812
+ const { fieldType, name: label, options } = def;
5813
+ switch (fieldType) {
5814
+ case "DATE":
5815
+ return FormFieldHelpers.date(name, label, { granularity: "day" });
5816
+ case "SHORT_TEXT":
5817
+ return FormFieldHelpers.input(name, label);
5818
+ case "LONG_TEXT":
5819
+ return FormFieldHelpers.textarea(name, label);
5820
+ case "NUMBER":
5821
+ return FormFieldHelpers.input(name, label, { type: "number" });
5822
+ case "DROPDOWN":
5823
+ return FormFieldHelpers.select(
5824
+ name,
5825
+ label,
5826
+ parseDropdownOptions(options)
5827
+ );
5828
+ default: {
5829
+ void fieldType;
5830
+ return FormFieldHelpers.input(name, label);
5831
+ }
5832
+ }
5833
+ }
5788
5834
  function createFieldArrayCustomConfig(options) {
5789
5835
  const {
5790
5836
  className,
5791
5837
  defaultItem,
5792
5838
  enableReordering = false,
5839
+ getItemFieldConfig,
5793
5840
  label,
5794
5841
  max = 10,
5795
5842
  min = 0,
5796
5843
  name,
5844
+ readOnly = false,
5797
5845
  renderAddButton,
5798
5846
  renderItem
5799
5847
  } = options;
5848
+ if (!getItemFieldConfig && !renderItem) {
5849
+ throw new Error(
5850
+ "createFieldArrayCustomConfig: provide either getItemFieldConfig or renderItem"
5851
+ );
5852
+ }
5800
5853
  return {
5801
5854
  className,
5802
5855
  label,
@@ -5834,24 +5887,42 @@ function createFieldArrayCustomConfig(options) {
5834
5887
  move(index, index + 1);
5835
5888
  }
5836
5889
  };
5890
+ const submissionState = {
5891
+ error: void 0,
5892
+ isSubmitted: form.formState.isSubmitted,
5893
+ isSubmitting: form.formState.isSubmitting,
5894
+ isSuccess: false
5895
+ };
5896
+ const itemProps = (index) => ({
5897
+ canMoveDown: enableReordering && index < fields.length - 1,
5898
+ canMoveUp: enableReordering && index > 0,
5899
+ control,
5900
+ errors,
5901
+ field: fields[index],
5902
+ fields,
5903
+ form,
5904
+ index,
5905
+ onMoveDown: () => handleMoveDown(index),
5906
+ onMoveUp: () => handleMoveUp(index),
5907
+ onRemove: () => handleRemove(index),
5908
+ readOnly
5909
+ });
5837
5910
  return /* @__PURE__ */ React27.createElement("div", { className }, /* @__PURE__ */ React27.createElement("div", { className: "space-y-4" }, fields.map((field2, index) => {
5838
- const canMoveUp = enableReordering && index > 0;
5839
- const canMoveDown = enableReordering && index < fields.length - 1;
5840
- return /* @__PURE__ */ React27.createElement(React27.Fragment, { key: field2.id }, renderItem({
5841
- canMoveDown,
5842
- canMoveUp,
5843
- control,
5844
- errors,
5845
- // fields from useFieldArray are already typed correctly
5846
- field: field2,
5847
- fields,
5848
- form,
5849
- index,
5850
- onMoveDown: () => handleMoveDown(index),
5851
- onMoveUp: () => handleMoveUp(index),
5852
- onRemove: () => handleRemove(index)
5853
- }));
5854
- }), fields.length === 0 && renderAddButton ? /* @__PURE__ */ React27.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React27.createElement("p", null, "No ", label?.toLowerCase() || "items", " added yet."), renderAddButton({ canAdd, onAdd: handleAdd })) : null, fields.length > 0 && renderAddButton ? renderAddButton({ canAdd, onAdd: handleAdd }) : canAdd && /* @__PURE__ */ React27.createElement(
5911
+ if (getItemFieldConfig) {
5912
+ const config = getItemFieldConfig(itemProps(index));
5913
+ if (!config) return /* @__PURE__ */ React27.createElement(React27.Fragment, { key: field2.id });
5914
+ return /* @__PURE__ */ React27.createElement(
5915
+ FormField,
5916
+ {
5917
+ key: field2.id,
5918
+ config,
5919
+ form,
5920
+ submissionState
5921
+ }
5922
+ );
5923
+ }
5924
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, { key: field2.id }, renderItem(itemProps(index)));
5925
+ }), !readOnly && fields.length === 0 && renderAddButton ? /* @__PURE__ */ React27.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React27.createElement("p", null, "No ", label?.toLowerCase() || "items", " added yet."), renderAddButton({ canAdd, onAdd: handleAdd })) : null, !readOnly && (fields.length > 0 && renderAddButton ? renderAddButton({ canAdd, onAdd: handleAdd }) : canAdd && /* @__PURE__ */ React27.createElement(
5855
5926
  Button6,
5856
5927
  {
5857
5928
  variant: "bordered",
@@ -5859,7 +5930,7 @@ function createFieldArrayCustomConfig(options) {
5859
5930
  className: "w-full"
5860
5931
  },
5861
5932
  "Add Item"
5862
- )));
5933
+ ))));
5863
5934
  },
5864
5935
  type: "custom"
5865
5936
  };
@@ -6121,6 +6192,7 @@ export {
6121
6192
  commonValidations,
6122
6193
  createAdvancedBuilder,
6123
6194
  createBasicFormBuilder,
6195
+ createCustomFieldConfigForItem,
6124
6196
  createDateSchema,
6125
6197
  createEmailSchema,
6126
6198
  createField,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rachelallyson/hero-hook-form",
3
- "version": "2.13.0",
3
+ "version": "2.15.0",
4
4
  "description": "Typed form helpers that combine React Hook Form and HeroUI components.",
5
5
  "author": "Rachel Higley",
6
6
  "homepage": "https://rachelallyson.github.io/hero-hook-form/",