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