@rachelallyson/hero-hook-form 2.10.0 → 2.11.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 +12 -0
- package/dist/index.d.ts +34 -15
- package/dist/index.js +33 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.11.0] - 2026-01-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Dynamic options for autocomplete** – `FormFieldHelpers.autocomplete()` and the builder chain now accept either a static options array or a getter function `() => options`. Use a getter for API-driven autocomplete (e.g. PCO Person, search-as-you-type): the getter is called each render so items stay in sync with state. Config supports `getOptions`; `FormField`, `ServerActionForm`, and `AdvancedFormBuilder` resolve items from `getOptions()` when present, else `options`. No need for `FormFieldHelpers.custom` when you only need dynamic items.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **FormFieldHelpers.autocomplete** – Third parameter can be `options[]` or `() => options[]`; JSDoc documents dynamic usage with `onInputChange`.
|
|
14
|
+
- **StringFieldConfig** – Added optional `getOptions?: () => { label: string; value: string | number }[]` for autocomplete fields.
|
|
15
|
+
- **AutocompleteField JSDoc** – Notes dynamic options via getter + `onInputChange`.
|
|
16
|
+
|
|
5
17
|
## [2.10.0] - 2026-01-28
|
|
6
18
|
|
|
7
19
|
### Added
|
package/dist/index.d.ts
CHANGED
|
@@ -80,10 +80,16 @@ interface StringFieldConfig<TFieldValues extends FieldValues> extends BaseFormFi
|
|
|
80
80
|
textareaProps?: TextareaPassthroughProps;
|
|
81
81
|
selectProps?: SelectPassthroughProps;
|
|
82
82
|
autocompleteProps?: AutocompletePassthroughProps;
|
|
83
|
+
/** Static options for autocomplete/select. Omit when using getOptions for dynamic items. */
|
|
83
84
|
options?: {
|
|
84
85
|
label: string;
|
|
85
86
|
value: string | number;
|
|
86
87
|
}[];
|
|
88
|
+
/** Dynamic options for autocomplete: called each render to get current items (e.g. from API/state). */
|
|
89
|
+
getOptions?: () => {
|
|
90
|
+
label: string;
|
|
91
|
+
value: string | number;
|
|
92
|
+
}[];
|
|
87
93
|
}
|
|
88
94
|
interface BooleanFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
89
95
|
type: "checkbox" | "switch";
|
|
@@ -635,7 +641,9 @@ type AutocompleteFieldProps<TFieldValues extends FieldValues, TValue extends str
|
|
|
635
641
|
*
|
|
636
642
|
* This component provides a type-safe autocomplete field with validation support,
|
|
637
643
|
* error handling, and accessibility features. It supports both static option lists
|
|
638
|
-
* and async loading via the items prop or children render function.
|
|
644
|
+
* and async loading via the items prop or children render function. For dynamic
|
|
645
|
+
* options (e.g. API search), use FormFieldHelpers.autocomplete with a getter:
|
|
646
|
+
* () => people.map(p => ({ label: p.name, value: p.id })) and onInputChange to fetch.
|
|
639
647
|
*
|
|
640
648
|
* @template TFieldValues - The form data type
|
|
641
649
|
* @template TValue - The value type for the autocomplete field (string or number)
|
|
@@ -2424,12 +2432,15 @@ declare class BasicFormBuilder<T extends FieldValues> {
|
|
|
2424
2432
|
value: string | number;
|
|
2425
2433
|
}[]): this;
|
|
2426
2434
|
/**
|
|
2427
|
-
* Add an autocomplete field
|
|
2435
|
+
* Add an autocomplete field (static options array or dynamic getOptions getter).
|
|
2428
2436
|
*/
|
|
2429
2437
|
autocomplete(name: Path<T>, label: string, items: {
|
|
2430
2438
|
label: string;
|
|
2431
2439
|
value: string | number;
|
|
2432
|
-
}[]
|
|
2440
|
+
}[] | (() => {
|
|
2441
|
+
label: string;
|
|
2442
|
+
value: string | number;
|
|
2443
|
+
}[]), placeholder?: string): this;
|
|
2433
2444
|
/**
|
|
2434
2445
|
* Add a checkbox field
|
|
2435
2446
|
*/
|
|
@@ -2530,27 +2541,31 @@ declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string
|
|
|
2530
2541
|
declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string, type: "text" | "email" | "tel" | "password", inputProps: InputPassthroughProps): ZodFormFieldConfig<T>;
|
|
2531
2542
|
declare const FormFieldHelpers: {
|
|
2532
2543
|
/**
|
|
2533
|
-
* Create an autocomplete field
|
|
2544
|
+
* Create an autocomplete field with static or dynamic options.
|
|
2545
|
+
*
|
|
2546
|
+
* Pass an array for a fixed list, or a getter function for dynamic/API-driven options
|
|
2547
|
+
* (e.g. search-as-you-type). The getter is called each render so it sees current state;
|
|
2548
|
+
* use with autocompleteProps.onInputChange to fetch options when the user types.
|
|
2534
2549
|
*
|
|
2535
2550
|
* @example
|
|
2536
2551
|
* ```tsx
|
|
2537
|
-
* //
|
|
2538
|
-
* FormFieldHelpers.autocomplete("country", "Country", options)
|
|
2539
|
-
*
|
|
2540
|
-
* // With placeholder
|
|
2541
|
-
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries")
|
|
2552
|
+
* // Static
|
|
2553
|
+
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", { allowsCustomValue: true })
|
|
2542
2554
|
*
|
|
2543
|
-
* //
|
|
2544
|
-
*
|
|
2545
|
-
*
|
|
2546
|
-
*
|
|
2555
|
+
* // Dynamic (e.g. PCO Person)
|
|
2556
|
+
* const [people, setPeople] = useState([]);
|
|
2557
|
+
* FormFieldHelpers.autocomplete("personId", "Person", () => people.map(p => ({ label: p.name, value: p.id })), "Search people", {
|
|
2558
|
+
* onInputChange: (q) => fetchPeople(q).then(setPeople),
|
|
2547
2559
|
* })
|
|
2548
2560
|
* ```
|
|
2549
2561
|
*/
|
|
2550
2562
|
autocomplete: <T extends FieldValues>(name: Path<T>, label: string, items: {
|
|
2551
2563
|
label: string;
|
|
2552
2564
|
value: string | number;
|
|
2553
|
-
}[]
|
|
2565
|
+
}[] | (() => {
|
|
2566
|
+
label: string;
|
|
2567
|
+
value: string | number;
|
|
2568
|
+
}[]), placeholder?: string, autocompleteProps?: AutocompletePassthroughProps) => ZodFormFieldConfig<T>;
|
|
2554
2569
|
/**
|
|
2555
2570
|
* Create a checkbox field
|
|
2556
2571
|
*
|
|
@@ -2988,7 +3003,11 @@ type FieldCreationParams<T extends FieldValues> = {
|
|
|
2988
3003
|
type: "autocomplete";
|
|
2989
3004
|
name: Path<T>;
|
|
2990
3005
|
label: string;
|
|
2991
|
-
options
|
|
3006
|
+
options?: {
|
|
3007
|
+
label: string;
|
|
3008
|
+
value: string | number;
|
|
3009
|
+
}[];
|
|
3010
|
+
getOptions?: () => {
|
|
2992
3011
|
label: string;
|
|
2993
3012
|
value: string | number;
|
|
2994
3013
|
}[];
|
package/dist/index.js
CHANGED
|
@@ -2335,6 +2335,7 @@ function FormFieldComponent({
|
|
|
2335
2335
|
);
|
|
2336
2336
|
}
|
|
2337
2337
|
case "autocomplete": {
|
|
2338
|
+
const autocompleteOptions = "getOptions" in fieldConfig && typeof fieldConfig.getOptions === "function" ? fieldConfig.getOptions() : "options" in fieldConfig && fieldConfig.options ? fieldConfig.options : [];
|
|
2338
2339
|
return /* @__PURE__ */ React19.createElement(
|
|
2339
2340
|
AutocompleteField,
|
|
2340
2341
|
{
|
|
@@ -2342,7 +2343,7 @@ function FormFieldComponent({
|
|
|
2342
2343
|
name: fieldConfig.name,
|
|
2343
2344
|
control,
|
|
2344
2345
|
defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
|
|
2345
|
-
items:
|
|
2346
|
+
items: autocompleteOptions.map((opt) => ({
|
|
2346
2347
|
label: opt.label,
|
|
2347
2348
|
value: String(opt.value)
|
|
2348
2349
|
})),
|
|
@@ -3120,10 +3121,11 @@ function ServerActionField({
|
|
|
3120
3121
|
}
|
|
3121
3122
|
case "autocomplete": {
|
|
3122
3123
|
const stringConfig = fieldConfig;
|
|
3123
|
-
const
|
|
3124
|
+
const rawItems = typeof stringConfig.getOptions === "function" ? stringConfig.getOptions() : stringConfig.options ?? [];
|
|
3125
|
+
const items = rawItems.map((opt) => ({
|
|
3124
3126
|
label: opt.label,
|
|
3125
3127
|
value: String(opt.value)
|
|
3126
|
-
}))
|
|
3128
|
+
}));
|
|
3127
3129
|
return /* @__PURE__ */ React21.createElement(
|
|
3128
3130
|
Autocomplete,
|
|
3129
3131
|
{
|
|
@@ -4048,14 +4050,15 @@ var BasicFormBuilder = class {
|
|
|
4048
4050
|
return this;
|
|
4049
4051
|
}
|
|
4050
4052
|
/**
|
|
4051
|
-
* Add an autocomplete field
|
|
4053
|
+
* Add an autocomplete field (static options array or dynamic getOptions getter).
|
|
4052
4054
|
*/
|
|
4053
4055
|
autocomplete(name, label, items, placeholder) {
|
|
4056
|
+
const isGetter = typeof items === "function";
|
|
4054
4057
|
this.fields.push({
|
|
4055
4058
|
autocompleteProps: placeholder ? { placeholder } : void 0,
|
|
4056
4059
|
label,
|
|
4057
4060
|
name,
|
|
4058
|
-
options: items,
|
|
4061
|
+
...isGetter ? { getOptions: items } : { options: items },
|
|
4059
4062
|
type: "autocomplete"
|
|
4060
4063
|
});
|
|
4061
4064
|
return this;
|
|
@@ -4132,33 +4135,37 @@ function inputHelper(name, label, typeOrProps, inputProps) {
|
|
|
4132
4135
|
}
|
|
4133
4136
|
var FormFieldHelpers = {
|
|
4134
4137
|
/**
|
|
4135
|
-
* Create an autocomplete field
|
|
4138
|
+
* Create an autocomplete field with static or dynamic options.
|
|
4139
|
+
*
|
|
4140
|
+
* Pass an array for a fixed list, or a getter function for dynamic/API-driven options
|
|
4141
|
+
* (e.g. search-as-you-type). The getter is called each render so it sees current state;
|
|
4142
|
+
* use with autocompleteProps.onInputChange to fetch options when the user types.
|
|
4136
4143
|
*
|
|
4137
4144
|
* @example
|
|
4138
4145
|
* ```tsx
|
|
4139
|
-
* //
|
|
4140
|
-
* FormFieldHelpers.autocomplete("country", "Country", options)
|
|
4146
|
+
* // Static
|
|
4147
|
+
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", { allowsCustomValue: true })
|
|
4141
4148
|
*
|
|
4142
|
-
* //
|
|
4143
|
-
*
|
|
4144
|
-
*
|
|
4145
|
-
*
|
|
4146
|
-
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", {
|
|
4147
|
-
* classNames: { base: "custom-autocomplete" },
|
|
4148
|
-
* allowsCustomValue: true
|
|
4149
|
+
* // Dynamic (e.g. PCO Person)
|
|
4150
|
+
* const [people, setPeople] = useState([]);
|
|
4151
|
+
* FormFieldHelpers.autocomplete("personId", "Person", () => people.map(p => ({ label: p.name, value: p.id })), "Search people", {
|
|
4152
|
+
* onInputChange: (q) => fetchPeople(q).then(setPeople),
|
|
4149
4153
|
* })
|
|
4150
4154
|
* ```
|
|
4151
4155
|
*/
|
|
4152
|
-
autocomplete: (name, label, items, placeholder, autocompleteProps) =>
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4156
|
+
autocomplete: (name, label, items, placeholder, autocompleteProps) => {
|
|
4157
|
+
const isGetter = typeof items === "function";
|
|
4158
|
+
return {
|
|
4159
|
+
autocompleteProps: {
|
|
4160
|
+
...placeholder && { placeholder },
|
|
4161
|
+
...autocompleteProps
|
|
4162
|
+
},
|
|
4163
|
+
...isGetter ? { getOptions: items } : { options: items },
|
|
4164
|
+
label,
|
|
4165
|
+
name,
|
|
4166
|
+
type: "autocomplete"
|
|
4167
|
+
};
|
|
4168
|
+
},
|
|
4162
4169
|
/**
|
|
4163
4170
|
* Create a checkbox field
|
|
4164
4171
|
*
|
|
@@ -4830,7 +4837,7 @@ function createFieldFromParams(params) {
|
|
|
4830
4837
|
autocompleteProps: params.props,
|
|
4831
4838
|
label: params.label,
|
|
4832
4839
|
name: params.name,
|
|
4833
|
-
options: params.options,
|
|
4840
|
+
...typeof params.getOptions === "function" ? { getOptions: params.getOptions } : { options: params.options },
|
|
4834
4841
|
type: "autocomplete"
|
|
4835
4842
|
};
|
|
4836
4843
|
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.11.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/",
|