@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.
@@ -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: selectedKey != null ? String(selectedKey) : void 0,
137
- inputValue: selectedKey != null ? void 0 : field2.value ?? "",
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 (autocompleteProps?.allowsCustomValue) {
146
+ if (allowsCustomValue) {
144
147
  field2.onChange(value);
145
148
  }
146
149
  },
147
- defaultItems: items
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: placeholder ? { placeholder } : void 0,
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
- condition,
2461
- field: field2,
2462
- name,
2463
- type: "conditional"
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 = "text") => ({
2502
- inputProps: { type },
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: { placeholder },
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
- disabled: props.isDisabled || false,
2674
- max: props.max || 100,
2675
- min: props.min || 0,
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
- disabled: props.isDisabled || false,
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: { max, min, step, ...fieldOptions },
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.4.0",
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/",