@rachelallyson/hero-hook-form 2.11.0 → 2.13.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 +26 -0
- package/dist/index.d.ts +39 -6
- package/dist/index.js +223 -166
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.13.0] - 2026-01-29
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **ConfigProvider: autocomplete defaults** – `HeroHookFormDefaultsConfig` and `useHeroHookFormDefaults()` now support `defaults.autocomplete`. AutocompleteField spreads these defaults so global Autocomplete styling (color, size, variant, radius, labelPlacement) applies like Input, Textarea, and Select.
|
|
10
|
+
- **FieldArrayField: readOnly** – New `readOnly?: boolean` on `FieldArrayConfig`. When true, hides the add button, remove buttons, and reorder buttons so the field array is display-only.
|
|
11
|
+
- **StringArrayField: readOnly** – New `readOnly?: boolean` on `StringArrayFieldConfig`. When true, hides the input, add button, and remove buttons so the list is display-only.
|
|
12
|
+
- **AutocompleteFieldHandlers: store custom value from selection** – `createAutocompleteFieldHandlers` now allows `onSelectionChange` to return a value (string or number); that value is stored in the form field instead of the selected key (e.g. "store key, show label" by returning the display string).
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **AutocompleteField** – `AutocompleteItem` `textValue` now uses `item.label ?? String(item.value)` so options with labels display correctly.
|
|
17
|
+
- **StringArrayField** – Uses `useHeroHookFormDefaults()` for Input and Button; switched to HeroUI-style props (`onValueChange`, `onPress`, `isDisabled`). Enter key handling uses `onKeyDown` instead of deprecated `onKeyPress`.
|
|
18
|
+
|
|
19
|
+
## [2.12.0] - 2026-01-28
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Custom option layout for autocomplete (renderItem)** – `FormFieldHelpers.autocomplete()` and the builder chain accept an optional 6th param `options?: { renderItem?: (item) => ReactNode }` so each option can show custom content (e.g. name + email + phone). Config supports `renderItem`; `FormField`, `ServerActionForm`, and `AdvancedFormBuilder` pass it through; `AutocompleteField` wraps custom children in `AutocompleteItem` so HeroUI receives valid listbox items. Use with static options or with `getOptions` for dynamic items + custom layout.
|
|
24
|
+
- **StringFieldConfig.renderItem** – Optional `renderItem?: (item: { label: string; value: string | number }) => ReactNode` for autocomplete fields.
|
|
25
|
+
- **Component tests** – Autocomplete: `renderItem` config and render (static and getOptions + renderItem).
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **AutocompleteField custom children** – Custom `children` (renderItem) are now wrapped in `AutocompleteItem` before passing to HeroUI Autocomplete so the listbox receives valid items and the form renders correctly.
|
|
30
|
+
|
|
5
31
|
## [2.11.0] - 2026-01-28
|
|
6
32
|
|
|
7
33
|
### Added
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React$1, { ComponentProps } from 'react';
|
|
1
|
+
import React$1, { ComponentProps, ReactNode } from 'react';
|
|
2
2
|
import { Button } from '@heroui/react';
|
|
3
3
|
import * as react_hook_form from 'react-hook-form';
|
|
4
4
|
import { FieldValues, Path, RegisterOptions, ArrayPath, Control, UseFormReturn, FieldErrors, UseFormProps, SubmitHandler, DefaultValues, UseFormSetError, FieldPath, FieldArrayWithId } from 'react-hook-form';
|
|
@@ -90,6 +90,11 @@ interface StringFieldConfig<TFieldValues extends FieldValues> extends BaseFormFi
|
|
|
90
90
|
label: string;
|
|
91
91
|
value: string | number;
|
|
92
92
|
}[];
|
|
93
|
+
/** Custom render for each autocomplete option (e.g. name + email + phone). When provided, used instead of default label-only. */
|
|
94
|
+
renderItem?: (item: {
|
|
95
|
+
label: string;
|
|
96
|
+
value: string | number;
|
|
97
|
+
}) => ReactNode;
|
|
93
98
|
}
|
|
94
99
|
interface BooleanFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
95
100
|
type: "checkbox" | "switch";
|
|
@@ -165,6 +170,8 @@ interface StringArrayFieldConfig<TFieldValues extends FieldValues> extends BaseF
|
|
|
165
170
|
addButtonText?: string;
|
|
166
171
|
/** Whether to show add button or use enter key */
|
|
167
172
|
showAddButton?: boolean;
|
|
173
|
+
/** When true, only display items: no input, no add button, no remove buttons */
|
|
174
|
+
readOnly?: boolean;
|
|
168
175
|
};
|
|
169
176
|
}
|
|
170
177
|
interface CustomFieldConfig<TFieldValues extends FieldValues> extends Omit<BaseFormFieldConfig<TFieldValues>, "name"> {
|
|
@@ -217,6 +224,8 @@ interface FieldArrayConfig<TFieldValues extends FieldValues> extends Omit<BaseFo
|
|
|
217
224
|
};
|
|
218
225
|
/** Function to create default item when adding new array item */
|
|
219
226
|
defaultItem?: () => any;
|
|
227
|
+
/** When true, hide add button, remove buttons, and reorder buttons (display-only) */
|
|
228
|
+
readOnly?: boolean;
|
|
220
229
|
/** Whether this field array should always be registered (for conditional rendering) */
|
|
221
230
|
alwaysRegistered?: boolean;
|
|
222
231
|
/** Custom render function for array items */
|
|
@@ -1761,7 +1770,7 @@ declare function useFormHelper<T extends FieldValues>({ defaultValues, methods,
|
|
|
1761
1770
|
* @category Hooks
|
|
1762
1771
|
*/
|
|
1763
1772
|
declare function useHeroForm<TFieldValues extends FieldValues>(): {
|
|
1764
|
-
defaults: Required<Pick<HeroHookFormDefaultsConfig, "input" | "select" | "textarea" | "switch" | "radioGroup" | "checkbox" | "slider" | "dateInput" | "submitButton">>;
|
|
1773
|
+
defaults: Required<Pick<HeroHookFormDefaultsConfig, "input" | "select" | "textarea" | "switch" | "radioGroup" | "checkbox" | "slider" | "autocomplete" | "dateInput" | "submitButton">>;
|
|
1765
1774
|
watch: react_hook_form.UseFormWatch<TFieldValues>;
|
|
1766
1775
|
getValues: react_hook_form.UseFormGetValues<TFieldValues>;
|
|
1767
1776
|
getFieldState: react_hook_form.UseFormGetFieldState<TFieldValues>;
|
|
@@ -1800,6 +1809,8 @@ type TextareaDefaults = Partial<Omit<TextareaProps, "value" | "onValueChange" |
|
|
|
1800
1809
|
type CheckboxDefaults = Partial<Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">>;
|
|
1801
1810
|
type RadioGroupDefaults = Partial<Omit<React$1.ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">>;
|
|
1802
1811
|
type SelectDefaults = Partial<Omit<SelectProps, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
|
|
1812
|
+
type AutocompleteProps = React$1.ComponentProps<typeof Autocomplete>;
|
|
1813
|
+
type AutocompleteDefaults = Partial<Omit<AutocompleteProps, "selectedKey" | "inputValue" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "items" | "defaultItems" | "children">>;
|
|
1803
1814
|
type DateInputProps = React$1.ComponentProps<typeof DateInput>;
|
|
1804
1815
|
type DateInputDefaults = Partial<Omit<DateInputProps, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
|
|
1805
1816
|
type SliderDefaults = Partial<Omit<React$1.ComponentProps<typeof Slider>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
|
|
@@ -1807,6 +1818,7 @@ type SwitchDefaults = Partial<Omit<React$1.ComponentProps<typeof Switch>, "isSel
|
|
|
1807
1818
|
type ButtonDefaults = Partial<Omit<React$1.ComponentProps<typeof Button$1>, "type" | "isLoading">>;
|
|
1808
1819
|
interface HeroHookFormDefaultsConfig {
|
|
1809
1820
|
common?: CommonFieldDefaults;
|
|
1821
|
+
autocomplete?: AutocompleteDefaults;
|
|
1810
1822
|
input?: InputDefaults;
|
|
1811
1823
|
textarea?: TextareaDefaults;
|
|
1812
1824
|
checkbox?: CheckboxDefaults;
|
|
@@ -1822,7 +1834,7 @@ interface HeroHookFormProviderProps {
|
|
|
1822
1834
|
defaults?: HeroHookFormDefaultsConfig;
|
|
1823
1835
|
}
|
|
1824
1836
|
declare function HeroHookFormProvider(props: HeroHookFormProviderProps): React$1.JSX.Element;
|
|
1825
|
-
declare function useHeroHookFormDefaults(): Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "checkbox" | "radioGroup" | "select" | "dateInput" | "slider" | "switch" | "submitButton">>;
|
|
1837
|
+
declare function useHeroHookFormDefaults(): Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "checkbox" | "radioGroup" | "select" | "autocomplete" | "dateInput" | "slider" | "switch" | "submitButton">>;
|
|
1826
1838
|
|
|
1827
1839
|
interface FormProps<TFieldValues extends FieldValues> {
|
|
1828
1840
|
methods: UseFormReturn<TFieldValues>;
|
|
@@ -2433,6 +2445,7 @@ declare class BasicFormBuilder<T extends FieldValues> {
|
|
|
2433
2445
|
}[]): this;
|
|
2434
2446
|
/**
|
|
2435
2447
|
* Add an autocomplete field (static options array or dynamic getOptions getter).
|
|
2448
|
+
* Optional options.renderItem for custom option layout (e.g. name + email + phone).
|
|
2436
2449
|
*/
|
|
2437
2450
|
autocomplete(name: Path<T>, label: string, items: {
|
|
2438
2451
|
label: string;
|
|
@@ -2440,7 +2453,12 @@ declare class BasicFormBuilder<T extends FieldValues> {
|
|
|
2440
2453
|
}[] | (() => {
|
|
2441
2454
|
label: string;
|
|
2442
2455
|
value: string | number;
|
|
2443
|
-
}[]), placeholder?: string
|
|
2456
|
+
}[]), placeholder?: string, options?: {
|
|
2457
|
+
renderItem?: (item: {
|
|
2458
|
+
label: string;
|
|
2459
|
+
value: string | number;
|
|
2460
|
+
}) => React$1.ReactNode;
|
|
2461
|
+
}): this;
|
|
2444
2462
|
/**
|
|
2445
2463
|
* Add a checkbox field
|
|
2446
2464
|
*/
|
|
@@ -2557,6 +2575,11 @@ declare const FormFieldHelpers: {
|
|
|
2557
2575
|
* FormFieldHelpers.autocomplete("personId", "Person", () => people.map(p => ({ label: p.name, value: p.id })), "Search people", {
|
|
2558
2576
|
* onInputChange: (q) => fetchPeople(q).then(setPeople),
|
|
2559
2577
|
* })
|
|
2578
|
+
*
|
|
2579
|
+
* // Custom option layout (e.g. name + email + phone per option)
|
|
2580
|
+
* FormFieldHelpers.autocomplete("personId", "Person", getOptions, "Search", undefined, {
|
|
2581
|
+
* renderItem: (item) => <div><strong>{item.label}</strong><br /><small>{getSubtitle(item.value)}</small></div>,
|
|
2582
|
+
* })
|
|
2560
2583
|
* ```
|
|
2561
2584
|
*/
|
|
2562
2585
|
autocomplete: <T extends FieldValues>(name: Path<T>, label: string, items: {
|
|
@@ -2565,7 +2588,13 @@ declare const FormFieldHelpers: {
|
|
|
2565
2588
|
}[] | (() => {
|
|
2566
2589
|
label: string;
|
|
2567
2590
|
value: string | number;
|
|
2568
|
-
}[]), placeholder?: string, autocompleteProps?: AutocompletePassthroughProps
|
|
2591
|
+
}[]), placeholder?: string, autocompleteProps?: AutocompletePassthroughProps, options?: {
|
|
2592
|
+
/** Custom render for each option (e.g. name + email + phone). When provided, used instead of default label-only. */
|
|
2593
|
+
renderItem?: (item: {
|
|
2594
|
+
label: string;
|
|
2595
|
+
value: string | number;
|
|
2596
|
+
}) => React$1.ReactNode;
|
|
2597
|
+
}) => ZodFormFieldConfig<T>;
|
|
2569
2598
|
/**
|
|
2570
2599
|
* Create a checkbox field
|
|
2571
2600
|
*
|
|
@@ -3012,6 +3041,10 @@ type FieldCreationParams<T extends FieldValues> = {
|
|
|
3012
3041
|
value: string | number;
|
|
3013
3042
|
}[];
|
|
3014
3043
|
props?: Record<string, unknown>;
|
|
3044
|
+
renderItem?: (item: {
|
|
3045
|
+
label: string;
|
|
3046
|
+
value: string | number;
|
|
3047
|
+
}) => React$1.ReactNode;
|
|
3015
3048
|
} | {
|
|
3016
3049
|
type: "checkbox";
|
|
3017
3050
|
name: Path<T>;
|
|
@@ -4346,4 +4379,4 @@ declare const validationUtils: {
|
|
|
4346
4379
|
}>;
|
|
4347
4380
|
};
|
|
4348
4381
|
|
|
4349
|
-
export { AdvancedFieldBuilder, type ArraySyncOptions, type ArraySyncResult, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -88,9 +88,170 @@ import React19 from "react";
|
|
|
88
88
|
import { get, useWatch as useWatch3 } from "react-hook-form";
|
|
89
89
|
|
|
90
90
|
// src/fields/AutocompleteField.tsx
|
|
91
|
-
import
|
|
91
|
+
import React2 from "react";
|
|
92
92
|
import { Controller } from "react-hook-form";
|
|
93
93
|
|
|
94
|
+
// src/providers/ConfigProvider.tsx
|
|
95
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
96
|
+
var DefaultsContext = createContext(null);
|
|
97
|
+
function HeroHookFormProvider(props) {
|
|
98
|
+
const value = useMemo(() => props.defaults ?? {}, [props.defaults]);
|
|
99
|
+
return /* @__PURE__ */ React.createElement(DefaultsContext.Provider, { value }, props.children);
|
|
100
|
+
}
|
|
101
|
+
function extractInputCommon(common) {
|
|
102
|
+
const result = {};
|
|
103
|
+
if (common.color !== void 0) {
|
|
104
|
+
const color = common.color;
|
|
105
|
+
result.color = color;
|
|
106
|
+
}
|
|
107
|
+
if (common.size !== void 0) {
|
|
108
|
+
const size = common.size;
|
|
109
|
+
result.size = size;
|
|
110
|
+
}
|
|
111
|
+
if (common.variant !== void 0) {
|
|
112
|
+
const variant = common.variant;
|
|
113
|
+
result.variant = variant;
|
|
114
|
+
}
|
|
115
|
+
if (common.radius !== void 0) {
|
|
116
|
+
const radius = common.radius;
|
|
117
|
+
result.radius = radius;
|
|
118
|
+
}
|
|
119
|
+
if (common.labelPlacement !== void 0) {
|
|
120
|
+
const labelPlacement = common.labelPlacement;
|
|
121
|
+
result.labelPlacement = labelPlacement;
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
function extractTextareaCommon(common) {
|
|
126
|
+
const result = {};
|
|
127
|
+
if (common.color !== void 0) {
|
|
128
|
+
const color = common.color;
|
|
129
|
+
result.color = color;
|
|
130
|
+
}
|
|
131
|
+
if (common.size !== void 0) {
|
|
132
|
+
const size = common.size;
|
|
133
|
+
result.size = size;
|
|
134
|
+
}
|
|
135
|
+
if (common.variant !== void 0) {
|
|
136
|
+
const variant = common.variant;
|
|
137
|
+
result.variant = variant;
|
|
138
|
+
}
|
|
139
|
+
if (common.radius !== void 0) {
|
|
140
|
+
const radius = common.radius;
|
|
141
|
+
result.radius = radius;
|
|
142
|
+
}
|
|
143
|
+
if (common.labelPlacement !== void 0) {
|
|
144
|
+
const labelPlacement = common.labelPlacement;
|
|
145
|
+
result.labelPlacement = labelPlacement;
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
function extractSelectCommon(common) {
|
|
150
|
+
const result = {};
|
|
151
|
+
if (common.color !== void 0) {
|
|
152
|
+
const color = common.color;
|
|
153
|
+
result.color = color;
|
|
154
|
+
}
|
|
155
|
+
if (common.size !== void 0) {
|
|
156
|
+
const size = common.size;
|
|
157
|
+
result.size = size;
|
|
158
|
+
}
|
|
159
|
+
if (common.variant !== void 0) {
|
|
160
|
+
const variant = common.variant;
|
|
161
|
+
result.variant = variant;
|
|
162
|
+
}
|
|
163
|
+
if (common.radius !== void 0) {
|
|
164
|
+
const radius = common.radius;
|
|
165
|
+
result.radius = radius;
|
|
166
|
+
}
|
|
167
|
+
if (common.labelPlacement !== void 0) {
|
|
168
|
+
const labelPlacement = common.labelPlacement;
|
|
169
|
+
result.labelPlacement = labelPlacement;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
function extractAutocompleteCommon(common) {
|
|
174
|
+
const result = {};
|
|
175
|
+
if (common.color !== void 0) {
|
|
176
|
+
const color = common.color;
|
|
177
|
+
result.color = color;
|
|
178
|
+
}
|
|
179
|
+
if (common.size !== void 0) {
|
|
180
|
+
const size = common.size;
|
|
181
|
+
result.size = size;
|
|
182
|
+
}
|
|
183
|
+
if (common.variant !== void 0) {
|
|
184
|
+
const variant = common.variant;
|
|
185
|
+
result.variant = variant;
|
|
186
|
+
}
|
|
187
|
+
if (common.radius !== void 0) {
|
|
188
|
+
const radius = common.radius;
|
|
189
|
+
result.radius = radius;
|
|
190
|
+
}
|
|
191
|
+
if (common.labelPlacement !== void 0) {
|
|
192
|
+
const labelPlacement = common.labelPlacement;
|
|
193
|
+
result.labelPlacement = labelPlacement;
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
function extractDateInputCommon(common) {
|
|
198
|
+
const result = {};
|
|
199
|
+
if (common.color !== void 0) {
|
|
200
|
+
const color = common.color;
|
|
201
|
+
result.color = color;
|
|
202
|
+
}
|
|
203
|
+
if (common.size !== void 0) {
|
|
204
|
+
const size = common.size;
|
|
205
|
+
result.size = size;
|
|
206
|
+
}
|
|
207
|
+
if (common.variant !== void 0) {
|
|
208
|
+
const variant = common.variant;
|
|
209
|
+
result.variant = variant;
|
|
210
|
+
}
|
|
211
|
+
if (common.radius !== void 0) {
|
|
212
|
+
const radius = common.radius;
|
|
213
|
+
result.radius = radius;
|
|
214
|
+
}
|
|
215
|
+
if (common.labelPlacement !== void 0) {
|
|
216
|
+
const labelPlacement = common.labelPlacement;
|
|
217
|
+
result.labelPlacement = labelPlacement;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
function useHeroHookFormDefaults() {
|
|
222
|
+
const cfg = useContext(DefaultsContext) ?? {};
|
|
223
|
+
const common = cfg.common ?? {};
|
|
224
|
+
const commonInput = extractInputCommon(common);
|
|
225
|
+
const commonTextarea = extractTextareaCommon(common);
|
|
226
|
+
const commonSelect = extractSelectCommon(common);
|
|
227
|
+
const commonAutocomplete = extractAutocompleteCommon(common);
|
|
228
|
+
const commonDateInput = extractDateInputCommon(common);
|
|
229
|
+
const dateInputBase = {
|
|
230
|
+
radius: "md",
|
|
231
|
+
size: "md",
|
|
232
|
+
variant: "bordered"
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
autocomplete: {
|
|
236
|
+
...commonAutocomplete,
|
|
237
|
+
...cfg.autocomplete ?? {}
|
|
238
|
+
},
|
|
239
|
+
checkbox: cfg.checkbox ?? {},
|
|
240
|
+
dateInput: {
|
|
241
|
+
...dateInputBase,
|
|
242
|
+
...commonDateInput,
|
|
243
|
+
...cfg.dateInput ?? {}
|
|
244
|
+
},
|
|
245
|
+
input: { ...commonInput, ...cfg.input ?? {} },
|
|
246
|
+
radioGroup: cfg.radioGroup ?? {},
|
|
247
|
+
select: { ...commonSelect, ...cfg.select ?? {} },
|
|
248
|
+
slider: cfg.slider ?? {},
|
|
249
|
+
submitButton: cfg.submitButton ?? {},
|
|
250
|
+
switch: cfg.switch ?? {},
|
|
251
|
+
textarea: { ...commonTextarea, ...cfg.textarea ?? {} }
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
94
255
|
// src/utils/fieldHandlers.ts
|
|
95
256
|
function createBlurHandler(userHandler, formHandler) {
|
|
96
257
|
return (e) => {
|
|
@@ -235,10 +396,12 @@ function createAutocompleteFieldHandlers(props, field2, fieldLevel, options) {
|
|
|
235
396
|
const allowsCustomValue = options?.allowsCustomValue ?? false;
|
|
236
397
|
const handleSelectionChange = (key) => {
|
|
237
398
|
const next = key ?? "";
|
|
238
|
-
|
|
239
|
-
|
|
399
|
+
const valueToStore = typeof props?.onSelectionChange === "function" ? props.onSelectionChange(key) : void 0;
|
|
400
|
+
if (valueToStore !== void 0) {
|
|
401
|
+
field2.onChange(valueToStore);
|
|
402
|
+
} else {
|
|
403
|
+
field2.onChange(next);
|
|
240
404
|
}
|
|
241
|
-
field2.onChange(next);
|
|
242
405
|
};
|
|
243
406
|
const handleInputChange = (value) => {
|
|
244
407
|
const strValue = value != null ? String(value) : "";
|
|
@@ -305,7 +468,8 @@ function AutocompleteField(props) {
|
|
|
305
468
|
placeholder,
|
|
306
469
|
rules
|
|
307
470
|
} = props;
|
|
308
|
-
|
|
471
|
+
const defaults = useHeroHookFormDefaults();
|
|
472
|
+
return /* @__PURE__ */ React2.createElement(
|
|
309
473
|
Controller,
|
|
310
474
|
{
|
|
311
475
|
control,
|
|
@@ -322,9 +486,10 @@ function AutocompleteField(props) {
|
|
|
322
486
|
{ isDisabled, label },
|
|
323
487
|
{ allowsCustomValue }
|
|
324
488
|
);
|
|
325
|
-
return /* @__PURE__ */
|
|
489
|
+
return /* @__PURE__ */ React2.createElement("div", { className }, /* @__PURE__ */ React2.createElement(
|
|
326
490
|
Autocomplete,
|
|
327
491
|
{
|
|
492
|
+
...defaults.autocomplete,
|
|
328
493
|
...rest,
|
|
329
494
|
...defaultItems && {
|
|
330
495
|
defaultItems
|
|
@@ -338,11 +503,20 @@ function AutocompleteField(props) {
|
|
|
338
503
|
inputValue: shouldShowInputValue ? field2.value ?? "" : void 0,
|
|
339
504
|
items
|
|
340
505
|
},
|
|
341
|
-
children ?
|
|
506
|
+
children ? (item) => /* @__PURE__ */ React2.createElement(
|
|
507
|
+
AutocompleteItem,
|
|
508
|
+
{
|
|
509
|
+
key: String(item.value),
|
|
510
|
+
textValue: item.label ?? String(item.value),
|
|
511
|
+
description: item.description,
|
|
512
|
+
isDisabled: item.disabled
|
|
513
|
+
},
|
|
514
|
+
children(item)
|
|
515
|
+
) : (item) => /* @__PURE__ */ React2.createElement(
|
|
342
516
|
AutocompleteItem,
|
|
343
517
|
{
|
|
344
518
|
key: String(item.value),
|
|
345
|
-
textValue: String(item.value),
|
|
519
|
+
textValue: item.label ?? String(item.value),
|
|
346
520
|
description: item.description,
|
|
347
521
|
isDisabled: item.disabled
|
|
348
522
|
},
|
|
@@ -358,140 +532,6 @@ function AutocompleteField(props) {
|
|
|
358
532
|
// src/fields/CheckboxField.tsx
|
|
359
533
|
import React3 from "react";
|
|
360
534
|
import { Controller as Controller2 } from "react-hook-form";
|
|
361
|
-
|
|
362
|
-
// src/providers/ConfigProvider.tsx
|
|
363
|
-
import React2, { createContext, useContext, useMemo } from "react";
|
|
364
|
-
var DefaultsContext = createContext(null);
|
|
365
|
-
function HeroHookFormProvider(props) {
|
|
366
|
-
const value = useMemo(() => props.defaults ?? {}, [props.defaults]);
|
|
367
|
-
return /* @__PURE__ */ React2.createElement(DefaultsContext.Provider, { value }, props.children);
|
|
368
|
-
}
|
|
369
|
-
function extractInputCommon(common) {
|
|
370
|
-
const result = {};
|
|
371
|
-
if (common.color !== void 0) {
|
|
372
|
-
const color = common.color;
|
|
373
|
-
result.color = color;
|
|
374
|
-
}
|
|
375
|
-
if (common.size !== void 0) {
|
|
376
|
-
const size = common.size;
|
|
377
|
-
result.size = size;
|
|
378
|
-
}
|
|
379
|
-
if (common.variant !== void 0) {
|
|
380
|
-
const variant = common.variant;
|
|
381
|
-
result.variant = variant;
|
|
382
|
-
}
|
|
383
|
-
if (common.radius !== void 0) {
|
|
384
|
-
const radius = common.radius;
|
|
385
|
-
result.radius = radius;
|
|
386
|
-
}
|
|
387
|
-
if (common.labelPlacement !== void 0) {
|
|
388
|
-
const labelPlacement = common.labelPlacement;
|
|
389
|
-
result.labelPlacement = labelPlacement;
|
|
390
|
-
}
|
|
391
|
-
return result;
|
|
392
|
-
}
|
|
393
|
-
function extractTextareaCommon(common) {
|
|
394
|
-
const result = {};
|
|
395
|
-
if (common.color !== void 0) {
|
|
396
|
-
const color = common.color;
|
|
397
|
-
result.color = color;
|
|
398
|
-
}
|
|
399
|
-
if (common.size !== void 0) {
|
|
400
|
-
const size = common.size;
|
|
401
|
-
result.size = size;
|
|
402
|
-
}
|
|
403
|
-
if (common.variant !== void 0) {
|
|
404
|
-
const variant = common.variant;
|
|
405
|
-
result.variant = variant;
|
|
406
|
-
}
|
|
407
|
-
if (common.radius !== void 0) {
|
|
408
|
-
const radius = common.radius;
|
|
409
|
-
result.radius = radius;
|
|
410
|
-
}
|
|
411
|
-
if (common.labelPlacement !== void 0) {
|
|
412
|
-
const labelPlacement = common.labelPlacement;
|
|
413
|
-
result.labelPlacement = labelPlacement;
|
|
414
|
-
}
|
|
415
|
-
return result;
|
|
416
|
-
}
|
|
417
|
-
function extractSelectCommon(common) {
|
|
418
|
-
const result = {};
|
|
419
|
-
if (common.color !== void 0) {
|
|
420
|
-
const color = common.color;
|
|
421
|
-
result.color = color;
|
|
422
|
-
}
|
|
423
|
-
if (common.size !== void 0) {
|
|
424
|
-
const size = common.size;
|
|
425
|
-
result.size = size;
|
|
426
|
-
}
|
|
427
|
-
if (common.variant !== void 0) {
|
|
428
|
-
const variant = common.variant;
|
|
429
|
-
result.variant = variant;
|
|
430
|
-
}
|
|
431
|
-
if (common.radius !== void 0) {
|
|
432
|
-
const radius = common.radius;
|
|
433
|
-
result.radius = radius;
|
|
434
|
-
}
|
|
435
|
-
if (common.labelPlacement !== void 0) {
|
|
436
|
-
const labelPlacement = common.labelPlacement;
|
|
437
|
-
result.labelPlacement = labelPlacement;
|
|
438
|
-
}
|
|
439
|
-
return result;
|
|
440
|
-
}
|
|
441
|
-
function extractDateInputCommon(common) {
|
|
442
|
-
const result = {};
|
|
443
|
-
if (common.color !== void 0) {
|
|
444
|
-
const color = common.color;
|
|
445
|
-
result.color = color;
|
|
446
|
-
}
|
|
447
|
-
if (common.size !== void 0) {
|
|
448
|
-
const size = common.size;
|
|
449
|
-
result.size = size;
|
|
450
|
-
}
|
|
451
|
-
if (common.variant !== void 0) {
|
|
452
|
-
const variant = common.variant;
|
|
453
|
-
result.variant = variant;
|
|
454
|
-
}
|
|
455
|
-
if (common.radius !== void 0) {
|
|
456
|
-
const radius = common.radius;
|
|
457
|
-
result.radius = radius;
|
|
458
|
-
}
|
|
459
|
-
if (common.labelPlacement !== void 0) {
|
|
460
|
-
const labelPlacement = common.labelPlacement;
|
|
461
|
-
result.labelPlacement = labelPlacement;
|
|
462
|
-
}
|
|
463
|
-
return result;
|
|
464
|
-
}
|
|
465
|
-
function useHeroHookFormDefaults() {
|
|
466
|
-
const cfg = useContext(DefaultsContext) ?? {};
|
|
467
|
-
const common = cfg.common ?? {};
|
|
468
|
-
const commonInput = extractInputCommon(common);
|
|
469
|
-
const commonTextarea = extractTextareaCommon(common);
|
|
470
|
-
const commonSelect = extractSelectCommon(common);
|
|
471
|
-
const commonDateInput = extractDateInputCommon(common);
|
|
472
|
-
const dateInputBase = {
|
|
473
|
-
radius: "md",
|
|
474
|
-
size: "md",
|
|
475
|
-
variant: "bordered"
|
|
476
|
-
};
|
|
477
|
-
return {
|
|
478
|
-
checkbox: cfg.checkbox ?? {},
|
|
479
|
-
dateInput: {
|
|
480
|
-
...dateInputBase,
|
|
481
|
-
...commonDateInput,
|
|
482
|
-
...cfg.dateInput ?? {}
|
|
483
|
-
},
|
|
484
|
-
input: { ...commonInput, ...cfg.input ?? {} },
|
|
485
|
-
radioGroup: cfg.radioGroup ?? {},
|
|
486
|
-
select: { ...commonSelect, ...cfg.select ?? {} },
|
|
487
|
-
slider: cfg.slider ?? {},
|
|
488
|
-
submitButton: cfg.submitButton ?? {},
|
|
489
|
-
switch: cfg.switch ?? {},
|
|
490
|
-
textarea: { ...commonTextarea, ...cfg.textarea ?? {} }
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// src/fields/CheckboxField.tsx
|
|
495
535
|
function CheckboxField(props) {
|
|
496
536
|
const {
|
|
497
537
|
checkboxProps,
|
|
@@ -1446,6 +1486,7 @@ function FieldArrayField({
|
|
|
1446
1486
|
max = 10,
|
|
1447
1487
|
min = 0,
|
|
1448
1488
|
name,
|
|
1489
|
+
readOnly = false,
|
|
1449
1490
|
removeButtonText = "Remove",
|
|
1450
1491
|
renderAddButton,
|
|
1451
1492
|
renderItem,
|
|
@@ -1562,7 +1603,7 @@ function FieldArrayField({
|
|
|
1562
1603
|
key: field2.id,
|
|
1563
1604
|
className: "border border-gray-200 rounded-lg p-4 space-y-4"
|
|
1564
1605
|
},
|
|
1565
|
-
/* @__PURE__ */ React9.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React9.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), /* @__PURE__ */ React9.createElement("div", { className: "flex gap-2" }, enableReordering && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
|
|
1606
|
+
/* @__PURE__ */ React9.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React9.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), !readOnly && /* @__PURE__ */ React9.createElement("div", { className: "flex gap-2" }, enableReordering && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
|
|
1566
1607
|
Button2,
|
|
1567
1608
|
{
|
|
1568
1609
|
size: "sm",
|
|
@@ -1599,6 +1640,9 @@ function FieldArrayField({
|
|
|
1599
1640
|
});
|
|
1600
1641
|
};
|
|
1601
1642
|
const renderAddButtonElement = () => {
|
|
1643
|
+
if (readOnly) {
|
|
1644
|
+
return null;
|
|
1645
|
+
}
|
|
1602
1646
|
if (renderAddButton) {
|
|
1603
1647
|
return renderAddButton({
|
|
1604
1648
|
canAdd,
|
|
@@ -2067,10 +2111,12 @@ function StringArrayInput(props) {
|
|
|
2067
2111
|
maxItems,
|
|
2068
2112
|
minItems,
|
|
2069
2113
|
placeholder = "Add item...",
|
|
2114
|
+
readOnly = false,
|
|
2070
2115
|
showAddButton = true,
|
|
2071
2116
|
transformItem = (item) => item.trim(),
|
|
2072
2117
|
validateItem = () => true
|
|
2073
2118
|
} = stringArrayProps || {};
|
|
2119
|
+
const defaults = useHeroHookFormDefaults();
|
|
2074
2120
|
const canAddMore = !maxItems || items.length < maxItems;
|
|
2075
2121
|
const handleAddItem = () => {
|
|
2076
2122
|
const trimmedValue = inputValue.trim();
|
|
@@ -2087,33 +2133,32 @@ function StringArrayInput(props) {
|
|
|
2087
2133
|
const newItems = items.filter((_, index) => index !== indexToRemove);
|
|
2088
2134
|
field2.onChange(newItems);
|
|
2089
2135
|
};
|
|
2090
|
-
|
|
2091
|
-
if (e.key === "Enter") {
|
|
2092
|
-
e.preventDefault();
|
|
2093
|
-
if (!showAddButton) {
|
|
2094
|
-
handleAddItem();
|
|
2095
|
-
}
|
|
2096
|
-
}
|
|
2097
|
-
};
|
|
2098
|
-
return /* @__PURE__ */ React16.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React16.createElement("label", { className: "block text-sm font-medium text-foreground" }, label, minItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(min ", minItems, ")"), maxItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(max ", maxItems, ")")), description && /* @__PURE__ */ React16.createElement("p", { className: "text-sm text-muted-foreground" }, description), canAddMore && /* @__PURE__ */ React16.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React16.createElement(
|
|
2136
|
+
return /* @__PURE__ */ React16.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React16.createElement("label", { className: "block text-sm font-medium text-foreground" }, label, minItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(min ", minItems, ")"), maxItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(max ", maxItems, ")")), description && /* @__PURE__ */ React16.createElement("p", { className: "text-sm text-muted-foreground" }, description), !readOnly && canAddMore && /* @__PURE__ */ React16.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React16.createElement(
|
|
2099
2137
|
Input,
|
|
2100
2138
|
{
|
|
2139
|
+
...defaults.input,
|
|
2101
2140
|
className: "flex-1",
|
|
2102
|
-
|
|
2141
|
+
isInvalid: !!errorMessage,
|
|
2142
|
+
errorMessage,
|
|
2143
|
+
isDisabled: disabled,
|
|
2103
2144
|
placeholder,
|
|
2104
2145
|
value: inputValue,
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2146
|
+
onValueChange: setInputValue,
|
|
2147
|
+
onKeyDown: (e) => {
|
|
2148
|
+
if (e.key === "Enter") {
|
|
2149
|
+
e.preventDefault();
|
|
2150
|
+
if (!showAddButton) handleAddItem();
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2109
2153
|
}
|
|
2110
2154
|
), showAddButton && /* @__PURE__ */ React16.createElement(
|
|
2111
2155
|
Button,
|
|
2112
2156
|
{
|
|
2157
|
+
...defaults.submitButton,
|
|
2113
2158
|
type: "button",
|
|
2114
2159
|
variant: "flat",
|
|
2115
|
-
|
|
2116
|
-
|
|
2160
|
+
onPress: handleAddItem,
|
|
2161
|
+
isDisabled: disabled || !inputValue.trim(),
|
|
2117
2162
|
size: "sm"
|
|
2118
2163
|
},
|
|
2119
2164
|
addButtonText
|
|
@@ -2124,14 +2169,15 @@ function StringArrayInput(props) {
|
|
|
2124
2169
|
className: "flex items-center gap-2 p-2 bg-content2 rounded-md"
|
|
2125
2170
|
},
|
|
2126
2171
|
/* @__PURE__ */ React16.createElement("span", { className: "flex-1 text-sm" }, item),
|
|
2127
|
-
/* @__PURE__ */ React16.createElement(
|
|
2172
|
+
!readOnly && /* @__PURE__ */ React16.createElement(
|
|
2128
2173
|
Button,
|
|
2129
2174
|
{
|
|
2175
|
+
...defaults.submitButton,
|
|
2130
2176
|
type: "button",
|
|
2131
2177
|
variant: "light",
|
|
2132
2178
|
size: "sm",
|
|
2133
|
-
|
|
2134
|
-
disabled,
|
|
2179
|
+
onPress: () => handleRemoveItem(index),
|
|
2180
|
+
isDisabled: disabled,
|
|
2135
2181
|
className: "min-w-[60px]"
|
|
2136
2182
|
},
|
|
2137
2183
|
"Remove"
|
|
@@ -2336,6 +2382,7 @@ function FormFieldComponent({
|
|
|
2336
2382
|
}
|
|
2337
2383
|
case "autocomplete": {
|
|
2338
2384
|
const autocompleteOptions = "getOptions" in fieldConfig && typeof fieldConfig.getOptions === "function" ? fieldConfig.getOptions() : "options" in fieldConfig && fieldConfig.options ? fieldConfig.options : [];
|
|
2385
|
+
const autocompleteRenderItem = "renderItem" in fieldConfig && typeof fieldConfig.renderItem === "function" ? (item) => /* @__PURE__ */ React19.createElement(React19.Fragment, null, fieldConfig.renderItem(item)) : void 0;
|
|
2339
2386
|
return /* @__PURE__ */ React19.createElement(
|
|
2340
2387
|
AutocompleteField,
|
|
2341
2388
|
{
|
|
@@ -2347,7 +2394,8 @@ function FormFieldComponent({
|
|
|
2347
2394
|
label: opt.label,
|
|
2348
2395
|
value: String(opt.value)
|
|
2349
2396
|
})),
|
|
2350
|
-
autocompleteProps: "autocompleteProps" in fieldConfig ? fieldConfig.autocompleteProps : void 0
|
|
2397
|
+
autocompleteProps: "autocompleteProps" in fieldConfig ? fieldConfig.autocompleteProps : void 0,
|
|
2398
|
+
children: autocompleteRenderItem
|
|
2351
2399
|
}
|
|
2352
2400
|
);
|
|
2353
2401
|
}
|
|
@@ -3145,7 +3193,7 @@ function ServerActionField({
|
|
|
3145
3193
|
onInputChange: setValue,
|
|
3146
3194
|
items
|
|
3147
3195
|
},
|
|
3148
|
-
items.map((item) => /* @__PURE__ */ React21.createElement(AutocompleteItem, { key: String(item.value) }, item.label))
|
|
3196
|
+
items.map((item) => /* @__PURE__ */ React21.createElement(AutocompleteItem, { key: String(item.value) }, typeof stringConfig.renderItem === "function" ? stringConfig.renderItem(item) : item.label))
|
|
3149
3197
|
);
|
|
3150
3198
|
}
|
|
3151
3199
|
case "slider": {
|
|
@@ -4051,14 +4099,16 @@ var BasicFormBuilder = class {
|
|
|
4051
4099
|
}
|
|
4052
4100
|
/**
|
|
4053
4101
|
* Add an autocomplete field (static options array or dynamic getOptions getter).
|
|
4102
|
+
* Optional options.renderItem for custom option layout (e.g. name + email + phone).
|
|
4054
4103
|
*/
|
|
4055
|
-
autocomplete(name, label, items, placeholder) {
|
|
4104
|
+
autocomplete(name, label, items, placeholder, options) {
|
|
4056
4105
|
const isGetter = typeof items === "function";
|
|
4057
4106
|
this.fields.push({
|
|
4058
4107
|
autocompleteProps: placeholder ? { placeholder } : void 0,
|
|
4059
4108
|
label,
|
|
4060
4109
|
name,
|
|
4061
4110
|
...isGetter ? { getOptions: items } : { options: items },
|
|
4111
|
+
...options?.renderItem && { renderItem: options.renderItem },
|
|
4062
4112
|
type: "autocomplete"
|
|
4063
4113
|
});
|
|
4064
4114
|
return this;
|
|
@@ -4151,9 +4201,14 @@ var FormFieldHelpers = {
|
|
|
4151
4201
|
* FormFieldHelpers.autocomplete("personId", "Person", () => people.map(p => ({ label: p.name, value: p.id })), "Search people", {
|
|
4152
4202
|
* onInputChange: (q) => fetchPeople(q).then(setPeople),
|
|
4153
4203
|
* })
|
|
4204
|
+
*
|
|
4205
|
+
* // Custom option layout (e.g. name + email + phone per option)
|
|
4206
|
+
* FormFieldHelpers.autocomplete("personId", "Person", getOptions, "Search", undefined, {
|
|
4207
|
+
* renderItem: (item) => <div><strong>{item.label}</strong><br /><small>{getSubtitle(item.value)}</small></div>,
|
|
4208
|
+
* })
|
|
4154
4209
|
* ```
|
|
4155
4210
|
*/
|
|
4156
|
-
autocomplete: (name, label, items, placeholder, autocompleteProps) => {
|
|
4211
|
+
autocomplete: (name, label, items, placeholder, autocompleteProps, options) => {
|
|
4157
4212
|
const isGetter = typeof items === "function";
|
|
4158
4213
|
return {
|
|
4159
4214
|
autocompleteProps: {
|
|
@@ -4161,6 +4216,7 @@ var FormFieldHelpers = {
|
|
|
4161
4216
|
...autocompleteProps
|
|
4162
4217
|
},
|
|
4163
4218
|
...isGetter ? { getOptions: items } : { options: items },
|
|
4219
|
+
...options?.renderItem && { renderItem: options.renderItem },
|
|
4164
4220
|
label,
|
|
4165
4221
|
name,
|
|
4166
4222
|
type: "autocomplete"
|
|
@@ -4838,6 +4894,7 @@ function createFieldFromParams(params) {
|
|
|
4838
4894
|
label: params.label,
|
|
4839
4895
|
name: params.name,
|
|
4840
4896
|
...typeof params.getOptions === "function" ? { getOptions: params.getOptions } : { options: params.options },
|
|
4897
|
+
...params.renderItem && { renderItem: params.renderItem },
|
|
4841
4898
|
type: "autocomplete"
|
|
4842
4899
|
};
|
|
4843
4900
|
case "content":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rachelallyson/hero-hook-form",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.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/",
|