@rachelallyson/hero-hook-form 2.4.0 → 2.6.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 +71 -0
- package/dist/index.d.ts +229 -14
- package/dist/index.js +279 -35
- package/dist/react/index.d.ts +228 -13
- package/dist/react/index.js +279 -35
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -123,6 +123,9 @@ function AutocompleteField(props) {
|
|
|
123
123
|
name,
|
|
124
124
|
render: ({ field: field2, fieldState }) => {
|
|
125
125
|
const selectedKey = field2.value;
|
|
126
|
+
const hasSelectedValue = selectedKey != null && selectedKey !== "";
|
|
127
|
+
const allowsCustomValue = autocompleteProps?.allowsCustomValue ?? false;
|
|
128
|
+
const shouldShowInputValue = allowsCustomValue || !hasSelectedValue;
|
|
126
129
|
return /* @__PURE__ */ React.createElement("div", { className }, /* @__PURE__ */ React.createElement(
|
|
127
130
|
Autocomplete,
|
|
128
131
|
{
|
|
@@ -133,18 +136,18 @@ function AutocompleteField(props) {
|
|
|
133
136
|
isInvalid: Boolean(fieldState.error),
|
|
134
137
|
label,
|
|
135
138
|
placeholder,
|
|
136
|
-
selectedKey:
|
|
137
|
-
inputValue:
|
|
139
|
+
selectedKey: allowsCustomValue ? void 0 : hasSelectedValue ? String(selectedKey) : void 0,
|
|
140
|
+
inputValue: shouldShowInputValue ? field2.value ?? "" : void 0,
|
|
138
141
|
onSelectionChange: (key) => {
|
|
139
142
|
const next = key ?? "";
|
|
140
143
|
field2.onChange(next);
|
|
141
144
|
},
|
|
142
145
|
onInputChange: (value) => {
|
|
143
|
-
if (
|
|
146
|
+
if (allowsCustomValue) {
|
|
144
147
|
field2.onChange(value);
|
|
145
148
|
}
|
|
146
149
|
},
|
|
147
|
-
|
|
150
|
+
items
|
|
148
151
|
},
|
|
149
152
|
children ? children : (item) => /* @__PURE__ */ React.createElement(
|
|
150
153
|
AutocompleteItem,
|
|
@@ -2378,6 +2381,19 @@ var BasicFormBuilder = class {
|
|
|
2378
2381
|
});
|
|
2379
2382
|
return this;
|
|
2380
2383
|
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Add an autocomplete field
|
|
2386
|
+
*/
|
|
2387
|
+
autocomplete(name, label, items, placeholder) {
|
|
2388
|
+
this.fields.push({
|
|
2389
|
+
autocompleteProps: placeholder ? { placeholder } : void 0,
|
|
2390
|
+
label,
|
|
2391
|
+
name,
|
|
2392
|
+
options: items,
|
|
2393
|
+
type: "autocomplete"
|
|
2394
|
+
});
|
|
2395
|
+
return this;
|
|
2396
|
+
}
|
|
2381
2397
|
/**
|
|
2382
2398
|
* Add a checkbox field
|
|
2383
2399
|
*/
|
|
@@ -2428,9 +2444,27 @@ function createBasicFormBuilder() {
|
|
|
2428
2444
|
var FormFieldHelpers = {
|
|
2429
2445
|
/**
|
|
2430
2446
|
* Create an autocomplete field
|
|
2447
|
+
*
|
|
2448
|
+
* @example
|
|
2449
|
+
* ```tsx
|
|
2450
|
+
* // Simple autocomplete
|
|
2451
|
+
* FormFieldHelpers.autocomplete("country", "Country", options)
|
|
2452
|
+
*
|
|
2453
|
+
* // With placeholder
|
|
2454
|
+
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries")
|
|
2455
|
+
*
|
|
2456
|
+
* // With full customization
|
|
2457
|
+
* FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", {
|
|
2458
|
+
* classNames: { base: "custom-autocomplete" },
|
|
2459
|
+
* allowsCustomValue: true
|
|
2460
|
+
* })
|
|
2461
|
+
* ```
|
|
2431
2462
|
*/
|
|
2432
|
-
autocomplete: (name, label, items, placeholder) => ({
|
|
2433
|
-
autocompleteProps:
|
|
2463
|
+
autocomplete: (name, label, items, placeholder, autocompleteProps) => ({
|
|
2464
|
+
autocompleteProps: {
|
|
2465
|
+
...placeholder && { placeholder },
|
|
2466
|
+
...autocompleteProps
|
|
2467
|
+
},
|
|
2434
2468
|
label,
|
|
2435
2469
|
name,
|
|
2436
2470
|
options: items,
|
|
@@ -2438,8 +2472,21 @@ var FormFieldHelpers = {
|
|
|
2438
2472
|
}),
|
|
2439
2473
|
/**
|
|
2440
2474
|
* Create a checkbox field
|
|
2475
|
+
*
|
|
2476
|
+
* @example
|
|
2477
|
+
* ```tsx
|
|
2478
|
+
* // Simple checkbox
|
|
2479
|
+
* FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter")
|
|
2480
|
+
*
|
|
2481
|
+
* // With full customization
|
|
2482
|
+
* FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter", {
|
|
2483
|
+
* classNames: { base: "custom-checkbox" },
|
|
2484
|
+
* size: "lg"
|
|
2485
|
+
* })
|
|
2486
|
+
* ```
|
|
2441
2487
|
*/
|
|
2442
|
-
checkbox: (name, label) => ({
|
|
2488
|
+
checkbox: (name, label, checkboxProps) => ({
|
|
2489
|
+
checkboxProps,
|
|
2443
2490
|
label,
|
|
2444
2491
|
name,
|
|
2445
2492
|
type: "checkbox"
|
|
@@ -2455,13 +2502,26 @@ var FormFieldHelpers = {
|
|
|
2455
2502
|
* FormFieldHelpers.input("phone", "Phone Number", "tel")
|
|
2456
2503
|
* )
|
|
2457
2504
|
* ```
|
|
2505
|
+
*
|
|
2506
|
+
* @example
|
|
2507
|
+
* With explicit type in condition function (similar to content helper pattern):
|
|
2508
|
+
* ```tsx
|
|
2509
|
+
* FormFieldHelpers.conditional(
|
|
2510
|
+
* "options",
|
|
2511
|
+
* (formData: Partial<z.infer<typeof fieldSchema>>) =>
|
|
2512
|
+
* formData.fieldType === 'DROPDOWN',
|
|
2513
|
+
* FormFieldHelpers.textarea("options", "Dropdown Options", "One per line")
|
|
2514
|
+
* )
|
|
2515
|
+
* ```
|
|
2458
2516
|
*/
|
|
2459
|
-
conditional: (name, condition, field2) =>
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2517
|
+
conditional: (name, condition, field2) => {
|
|
2518
|
+
return {
|
|
2519
|
+
condition,
|
|
2520
|
+
field: field2,
|
|
2521
|
+
name,
|
|
2522
|
+
type: "conditional"
|
|
2523
|
+
};
|
|
2524
|
+
},
|
|
2465
2525
|
/**
|
|
2466
2526
|
* Create a content field for headers, questions, or custom content between fields
|
|
2467
2527
|
*
|
|
@@ -2488,6 +2548,19 @@ var FormFieldHelpers = {
|
|
|
2488
2548
|
},
|
|
2489
2549
|
/**
|
|
2490
2550
|
* Create a date field
|
|
2551
|
+
*
|
|
2552
|
+
* @example
|
|
2553
|
+
* ```tsx
|
|
2554
|
+
* // Simple date field
|
|
2555
|
+
* FormFieldHelpers.date("birthDate", "Birth Date")
|
|
2556
|
+
*
|
|
2557
|
+
* // With full customization
|
|
2558
|
+
* FormFieldHelpers.date("birthDate", "Birth Date", {
|
|
2559
|
+
* label: "Select your birth date",
|
|
2560
|
+
* granularity: "day",
|
|
2561
|
+
* minValue: new CalendarDate(1900, 1, 1)
|
|
2562
|
+
* })
|
|
2563
|
+
* ```
|
|
2491
2564
|
*/
|
|
2492
2565
|
date: (name, label, dateProps) => ({
|
|
2493
2566
|
dateProps,
|
|
@@ -2495,40 +2568,211 @@ var FormFieldHelpers = {
|
|
|
2495
2568
|
name,
|
|
2496
2569
|
type: "date"
|
|
2497
2570
|
}),
|
|
2571
|
+
/**
|
|
2572
|
+
* Create a file upload field
|
|
2573
|
+
*
|
|
2574
|
+
* @example
|
|
2575
|
+
* ```tsx
|
|
2576
|
+
* // Simple file field
|
|
2577
|
+
* FormFieldHelpers.file("avatar", "Profile Picture")
|
|
2578
|
+
*
|
|
2579
|
+
* // With accept and multiple
|
|
2580
|
+
* FormFieldHelpers.file("avatar", "Profile Picture", {
|
|
2581
|
+
* accept: "image/*",
|
|
2582
|
+
* multiple: true
|
|
2583
|
+
* })
|
|
2584
|
+
*
|
|
2585
|
+
* // With full customization
|
|
2586
|
+
* FormFieldHelpers.file("avatar", "Profile Picture", {
|
|
2587
|
+
* accept: "image/*",
|
|
2588
|
+
* multiple: false,
|
|
2589
|
+
* fileProps: { className: "custom-file-input" }
|
|
2590
|
+
* })
|
|
2591
|
+
* ```
|
|
2592
|
+
*/
|
|
2593
|
+
file: (name, label, options) => ({
|
|
2594
|
+
accept: options?.accept,
|
|
2595
|
+
fileProps: options?.fileProps,
|
|
2596
|
+
label,
|
|
2597
|
+
multiple: options?.multiple,
|
|
2598
|
+
name,
|
|
2599
|
+
type: "file"
|
|
2600
|
+
}),
|
|
2601
|
+
/**
|
|
2602
|
+
* Create a font picker field
|
|
2603
|
+
*
|
|
2604
|
+
* @example
|
|
2605
|
+
* ```tsx
|
|
2606
|
+
* // Simple font picker
|
|
2607
|
+
* FormFieldHelpers.fontPicker("font", "Choose Font")
|
|
2608
|
+
*
|
|
2609
|
+
* // With full customization
|
|
2610
|
+
* FormFieldHelpers.fontPicker("font", "Choose Font", {
|
|
2611
|
+
* showFontPreview: true,
|
|
2612
|
+
* loadAllVariants: false,
|
|
2613
|
+
* fontsLoadedTimeout: 5000
|
|
2614
|
+
* })
|
|
2615
|
+
* ```
|
|
2616
|
+
*/
|
|
2617
|
+
fontPicker: (name, label, fontPickerProps) => ({
|
|
2618
|
+
fontPickerProps,
|
|
2619
|
+
label,
|
|
2620
|
+
name,
|
|
2621
|
+
type: "fontPicker"
|
|
2622
|
+
}),
|
|
2498
2623
|
/**
|
|
2499
2624
|
* Create an input field
|
|
2625
|
+
*
|
|
2626
|
+
* @example
|
|
2627
|
+
* ```tsx
|
|
2628
|
+
* // Simple input
|
|
2629
|
+
* FormFieldHelpers.input("name", "Name")
|
|
2630
|
+
*
|
|
2631
|
+
* // With type
|
|
2632
|
+
* FormFieldHelpers.input("email", "Email", "email")
|
|
2633
|
+
*
|
|
2634
|
+
* // With full customization
|
|
2635
|
+
* FormFieldHelpers.input("email", "Email", "email", {
|
|
2636
|
+
* placeholder: "Enter your email",
|
|
2637
|
+
* classNames: { input: "custom-input" },
|
|
2638
|
+
* startContent: <MailIcon />,
|
|
2639
|
+
* description: "We'll never share your email"
|
|
2640
|
+
* })
|
|
2641
|
+
* ```
|
|
2500
2642
|
*/
|
|
2501
|
-
input: (name, label, type
|
|
2502
|
-
inputProps: {
|
|
2643
|
+
input: (name, label, type, inputProps) => ({
|
|
2644
|
+
inputProps: {
|
|
2645
|
+
type: type || "text",
|
|
2646
|
+
...inputProps
|
|
2647
|
+
},
|
|
2503
2648
|
label,
|
|
2504
2649
|
name,
|
|
2505
2650
|
type: "input"
|
|
2506
2651
|
}),
|
|
2652
|
+
/**
|
|
2653
|
+
* Create a radio group field
|
|
2654
|
+
*
|
|
2655
|
+
* @example
|
|
2656
|
+
* ```tsx
|
|
2657
|
+
* // Simple radio group
|
|
2658
|
+
* FormFieldHelpers.radio("gender", "Gender", [
|
|
2659
|
+
* { label: "Male", value: "male" },
|
|
2660
|
+
* { label: "Female", value: "female" }
|
|
2661
|
+
* ])
|
|
2662
|
+
*
|
|
2663
|
+
* // With full customization
|
|
2664
|
+
* FormFieldHelpers.radio("gender", "Gender", options, {
|
|
2665
|
+
* orientation: "horizontal",
|
|
2666
|
+
* classNames: { base: "custom-radio" }
|
|
2667
|
+
* })
|
|
2668
|
+
* ```
|
|
2669
|
+
*/
|
|
2670
|
+
radio: (name, label, options, radioProps) => ({
|
|
2671
|
+
label,
|
|
2672
|
+
name,
|
|
2673
|
+
radioOptions: options,
|
|
2674
|
+
radioProps,
|
|
2675
|
+
type: "radio"
|
|
2676
|
+
}),
|
|
2507
2677
|
/**
|
|
2508
2678
|
* Create a select field
|
|
2679
|
+
*
|
|
2680
|
+
* @example
|
|
2681
|
+
* ```tsx
|
|
2682
|
+
* // Simple select
|
|
2683
|
+
* FormFieldHelpers.select("country", "Country", options)
|
|
2684
|
+
*
|
|
2685
|
+
* // With full customization
|
|
2686
|
+
* FormFieldHelpers.select("country", "Country", options, {
|
|
2687
|
+
* placeholder: "Select a country",
|
|
2688
|
+
* classNames: { trigger: "custom-select" },
|
|
2689
|
+
* selectionMode: "multiple"
|
|
2690
|
+
* })
|
|
2691
|
+
* ```
|
|
2509
2692
|
*/
|
|
2510
|
-
select: (name, label, options) => ({
|
|
2693
|
+
select: (name, label, options, selectProps) => ({
|
|
2511
2694
|
label,
|
|
2512
2695
|
name,
|
|
2513
2696
|
options,
|
|
2697
|
+
selectProps,
|
|
2514
2698
|
type: "select"
|
|
2515
2699
|
}),
|
|
2700
|
+
/**
|
|
2701
|
+
* Create a slider field
|
|
2702
|
+
*
|
|
2703
|
+
* @example
|
|
2704
|
+
* ```tsx
|
|
2705
|
+
* // Simple slider
|
|
2706
|
+
* FormFieldHelpers.slider("rating", "Rating")
|
|
2707
|
+
*
|
|
2708
|
+
* // With full customization
|
|
2709
|
+
* FormFieldHelpers.slider("rating", "Rating", {
|
|
2710
|
+
* minValue: 1,
|
|
2711
|
+
* maxValue: 5,
|
|
2712
|
+
* step: 1,
|
|
2713
|
+
* showSteps: true,
|
|
2714
|
+
* classNames: { base: "custom-slider" }
|
|
2715
|
+
* })
|
|
2716
|
+
* ```
|
|
2717
|
+
*/
|
|
2718
|
+
slider: (name, label, sliderProps) => ({
|
|
2719
|
+
label,
|
|
2720
|
+
name,
|
|
2721
|
+
sliderProps,
|
|
2722
|
+
type: "slider"
|
|
2723
|
+
}),
|
|
2516
2724
|
/**
|
|
2517
2725
|
* Create a switch field
|
|
2726
|
+
*
|
|
2727
|
+
* @example
|
|
2728
|
+
* ```tsx
|
|
2729
|
+
* // Simple switch
|
|
2730
|
+
* FormFieldHelpers.switch("notifications", "Enable notifications")
|
|
2731
|
+
*
|
|
2732
|
+
* // With description
|
|
2733
|
+
* FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications")
|
|
2734
|
+
*
|
|
2735
|
+
* // With full customization
|
|
2736
|
+
* FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications", {
|
|
2737
|
+
* classNames: { base: "custom-switch" },
|
|
2738
|
+
* size: "lg",
|
|
2739
|
+
* color: "primary"
|
|
2740
|
+
* })
|
|
2741
|
+
* ```
|
|
2518
2742
|
*/
|
|
2519
|
-
switch: (name, label, description) => ({
|
|
2743
|
+
switch: (name, label, description, switchProps) => ({
|
|
2520
2744
|
description,
|
|
2521
2745
|
label,
|
|
2522
2746
|
name,
|
|
2747
|
+
switchProps,
|
|
2523
2748
|
type: "switch"
|
|
2524
2749
|
}),
|
|
2525
2750
|
/**
|
|
2526
2751
|
* Create a textarea field
|
|
2752
|
+
*
|
|
2753
|
+
* @example
|
|
2754
|
+
* ```tsx
|
|
2755
|
+
* // Simple textarea
|
|
2756
|
+
* FormFieldHelpers.textarea("message", "Message")
|
|
2757
|
+
*
|
|
2758
|
+
* // With placeholder
|
|
2759
|
+
* FormFieldHelpers.textarea("message", "Message", "Enter your message")
|
|
2760
|
+
*
|
|
2761
|
+
* // With full customization
|
|
2762
|
+
* FormFieldHelpers.textarea("message", "Message", "Enter your message", {
|
|
2763
|
+
* classNames: { input: "custom-textarea" },
|
|
2764
|
+
* minRows: 3,
|
|
2765
|
+
* maxRows: 10
|
|
2766
|
+
* })
|
|
2767
|
+
* ```
|
|
2527
2768
|
*/
|
|
2528
|
-
textarea: (name, label, placeholder) => ({
|
|
2769
|
+
textarea: (name, label, placeholder, textareaProps) => ({
|
|
2529
2770
|
label,
|
|
2530
2771
|
name,
|
|
2531
|
-
textareaProps: {
|
|
2772
|
+
textareaProps: {
|
|
2773
|
+
...placeholder && { placeholder },
|
|
2774
|
+
...textareaProps
|
|
2775
|
+
},
|
|
2532
2776
|
type: "textarea"
|
|
2533
2777
|
})
|
|
2534
2778
|
};
|
|
@@ -2669,11 +2913,10 @@ function sliderField(name, label, props) {
|
|
|
2669
2913
|
type: "slider",
|
|
2670
2914
|
...props && {
|
|
2671
2915
|
sliderProps: {
|
|
2672
|
-
className: props.className
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
step: props.step || 1
|
|
2916
|
+
className: props.className,
|
|
2917
|
+
maxValue: props.max ?? 100,
|
|
2918
|
+
minValue: props.min ?? 0,
|
|
2919
|
+
step: props.step ?? 1
|
|
2677
2920
|
}
|
|
2678
2921
|
}
|
|
2679
2922
|
};
|
|
@@ -2685,9 +2928,8 @@ function dateField(name, label, props) {
|
|
|
2685
2928
|
type: "date",
|
|
2686
2929
|
...props && {
|
|
2687
2930
|
dateProps: {
|
|
2688
|
-
className: props.className
|
|
2689
|
-
|
|
2690
|
-
placeholder: props.placeholder || ""
|
|
2931
|
+
className: props.className,
|
|
2932
|
+
placeholder: props.placeholder
|
|
2691
2933
|
}
|
|
2692
2934
|
}
|
|
2693
2935
|
};
|
|
@@ -2709,15 +2951,12 @@ function fileField(name, label, props) {
|
|
|
2709
2951
|
}
|
|
2710
2952
|
function fontPickerField(name, label, props) {
|
|
2711
2953
|
return {
|
|
2954
|
+
className: props?.className,
|
|
2955
|
+
description: props?.description,
|
|
2956
|
+
fontPickerProps: props?.fontPickerProps,
|
|
2712
2957
|
label,
|
|
2713
2958
|
name,
|
|
2714
|
-
type: "fontPicker"
|
|
2715
|
-
...props && {
|
|
2716
|
-
fontPickerProps: {
|
|
2717
|
-
className: props.className || "",
|
|
2718
|
-
disabled: props.isDisabled || false
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2959
|
+
type: "fontPicker"
|
|
2721
2960
|
};
|
|
2722
2961
|
}
|
|
2723
2962
|
function contentField(title, description, options) {
|
|
@@ -3039,7 +3278,12 @@ var TypeInferredBuilder = class {
|
|
|
3039
3278
|
this.formFields.push({
|
|
3040
3279
|
label,
|
|
3041
3280
|
name,
|
|
3042
|
-
sliderProps: {
|
|
3281
|
+
sliderProps: {
|
|
3282
|
+
maxValue: max,
|
|
3283
|
+
minValue: min,
|
|
3284
|
+
step,
|
|
3285
|
+
...fieldOptions
|
|
3286
|
+
},
|
|
3043
3287
|
type: "slider"
|
|
3044
3288
|
});
|
|
3045
3289
|
return this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rachelallyson/hero-hook-form",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.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/",
|