hazo_ui 2.1.2 → 2.2.1

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/README.md CHANGED
@@ -12,25 +12,27 @@ npm install hazo_ui
12
12
 
13
13
  ### Component Overview
14
14
 
15
- - **[MultiFilterDialog](#multifilterdialog)** - A powerful dialog component for multi-field filtering with support for text, number, combobox, boolean, and date fields. Includes operator support, validation, and visual feedback.
15
+ - **[HazoUiMultiFilterDialog](#hazouimultifilterdialog)** - A powerful dialog component for multi-field filtering with support for text, number, combobox, boolean, and date fields. Includes operator support, validation, and visual feedback.
16
16
 
17
- - **[MultiSortDialog](#multisortdialog)** - A flexible dialog component for multi-field sorting with drag-and-drop reordering. Allows users to set sort priority and direction (ascending/descending) for multiple fields.
17
+ - **[HazoUiMultiSortDialog](#hazouimultisortdialog)** - A flexible dialog component for multi-field sorting with drag-and-drop reordering. Allows users to set sort priority and direction (ascending/descending) for multiple fields.
18
18
 
19
- - **[MultiStateRadio](#multistateradio)** - A flexible radio button/icon selection component with support for single and multi-selection modes, customizable layouts, and react-icons integration. Perfect for settings panels, preference selection, and option groups.
19
+ - **[HazoUiFlexRadio](#hazouiflexradio)** - A flexible radio button/icon selection component with support for single and multi-selection modes, customizable layouts, and react-icons integration. Perfect for settings panels, preference selection, and option groups.
20
+
21
+ - **[HazoUiFlexInput](#hazouiflexinput)** - An enhanced input component with type validation, character restrictions, and error messaging. Supports numeric, alpha, email, and mixed input types with built-in validation and formatting guides.
20
22
 
21
23
  ---
22
24
 
23
- ## MultiFilterDialog
25
+ ## HazoUiMultiFilterDialog
24
26
 
25
27
  A powerful, flexible dialog component for multi-field filtering with support for various input types. Perfect for table headers, grid views, or any interface where users need to apply multiple filters simultaneously.
26
28
 
27
- ![MultiFilterDialog - Filter Button with Active Filters Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-button-tooltip.png)
29
+ ![HazoUiMultiFilterDialog - Filter Button with Active Filters Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-button-tooltip.png)
28
30
 
29
- ![MultiFilterDialog - Dialog with Multiple Filters](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog.png)
31
+ ![HazoUiMultiFilterDialog - Dialog with Multiple Filters](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog.png)
30
32
 
31
- ![MultiFilterDialog - Calendar Date Picker](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog-calendar.png)
33
+ ![HazoUiMultiFilterDialog - Calendar Date Picker](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog-calendar.png)
32
34
 
33
- ![MultiFilterDialog - Filter Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-output.png)
35
+ ![HazoUiMultiFilterDialog - Filter Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-output.png)
34
36
 
35
37
  #### Features
36
38
 
@@ -71,7 +73,7 @@ A powerful, flexible dialog component for multi-field filtering with support for
71
73
  #### Usage
72
74
 
73
75
  ```tsx
74
- import { MultiFilterDialog, type FilterField, type FilterConfig } from 'hazo_ui';
76
+ import { HazoUiMultiFilterDialog, type FilterField, type FilterConfig } from 'hazo_ui';
75
77
  import { useState } from 'react';
76
78
 
77
79
  function DataTable() {
@@ -145,7 +147,7 @@ function DataTable() {
145
147
 
146
148
  return (
147
149
  <div>
148
- <MultiFilterDialog
150
+ <HazoUiMultiFilterDialog
149
151
  availableFields={availableFields}
150
152
  onFilterChange={handleFilterChange}
151
153
  initialFilters={filters}
@@ -239,17 +241,17 @@ When users apply filters, the `onFilterChange` callback receives an array of `Fi
239
241
 
240
242
  ---
241
243
 
242
- ## MultiSortDialog
244
+ ## HazoUiMultiSortDialog
243
245
 
244
246
  A powerful dialog component for multi-field sorting with drag-and-drop reordering. Allows users to select multiple fields for sorting, reorder them by priority, and set ascending/descending direction for each field.
245
247
 
246
- ![MultiSortDialog - Sort Button with Active Sorts Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-button-tooltip.png)
248
+ ![HazoUiMultiSortDialog - Sort Button with Active Sorts Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-button-tooltip.png)
247
249
 
248
- ![MultiSortDialog - Dialog with Multiple Sort Fields](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-dialog.png)
250
+ ![HazoUiMultiSortDialog - Dialog with Multiple Sort Fields](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-dialog.png)
249
251
 
250
- ![MultiSortDialog - Drag and Drop Reordering](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-drag-drop.png)
252
+ ![HazoUiMultiSortDialog - Drag and Drop Reordering](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-drag-drop.png)
251
253
 
252
- ![MultiSortDialog - Sort Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-output.png)
254
+ ![HazoUiMultiSortDialog - Sort Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-output.png)
253
255
 
254
256
  #### Features
255
257
 
@@ -278,7 +280,7 @@ The component returns an array of sort configurations in priority order, where t
278
280
  #### Usage
279
281
 
280
282
  ```tsx
281
- import { MultiSortDialog, type SortField, type SortConfig } from 'hazo_ui';
283
+ import { HazoUiMultiSortDialog, type SortField, type SortConfig } from 'hazo_ui';
282
284
  import { useState } from 'react';
283
285
 
284
286
  function DataTable() {
@@ -319,7 +321,7 @@ function DataTable() {
319
321
 
320
322
  return (
321
323
  <div>
322
- <MultiSortDialog
324
+ <HazoUiMultiSortDialog
323
325
  availableFields={availableFields}
324
326
  onSortChange={handleSortChange}
325
327
  initialSortFields={sorts}
@@ -446,7 +448,7 @@ const sortedData = applySorts(originalData, sorts);
446
448
 
447
449
  ---
448
450
 
449
- ## MultiStateRadio
451
+ ## HazoUiFlexRadio
450
452
 
451
453
  A flexible radio button/icon selection component with support for single and multi-selection modes, customizable layouts, and react-icons integration. Perfect for settings panels, preference selection, and option groups.
452
454
 
@@ -466,19 +468,19 @@ A flexible radio button/icon selection component with support for single and mul
466
468
  #### Props
467
469
 
468
470
  ```typescript
469
- interface MultiStateRadioItem {
471
+ interface HazoUiFlexRadioItem {
470
472
  label: string; // Display label for the option
471
473
  value: string; // Unique value identifier
472
474
  icon_selected?: string; // Icon name when selected (e.g., "FaHome")
473
475
  icon_unselected?: string; // Icon name when unselected (e.g., "FaRegHome")
474
476
  }
475
477
 
476
- interface MultiStateRadioProps {
478
+ interface HazoUiFlexRadioProps {
477
479
  layout?: 'horizontal' | 'vertical'; // Layout direction (default: 'horizontal')
478
480
  style?: 'radio' | 'icons'; // Display style (default: 'radio')
479
481
  display_label?: boolean; // Show/hide labels (default: true)
480
482
  icon_set?: string; // Icon set package name (e.g., 'fa', 'md')
481
- data: MultiStateRadioItem[]; // Array of options
483
+ data: HazoUiFlexRadioItem[]; // Array of options
482
484
  selection: 'single' | 'multi'; // Selection mode
483
485
  value: string | string[]; // Controlled value (string for single, array for multi)
484
486
  onChange: (value: string | string[]) => void; // Change handler
@@ -491,13 +493,13 @@ interface MultiStateRadioProps {
491
493
  **Basic Single Selection (Radio Style)**
492
494
 
493
495
  ```tsx
494
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
496
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
495
497
  import { useState } from 'react';
496
498
 
497
499
  function SettingsPanel() {
498
500
  const [selectedOption, setSelectedOption] = useState<string>('option1');
499
501
 
500
- const options: MultiStateRadioItem[] = [
502
+ const options: HazoUiFlexRadioItem[] = [
501
503
  { label: 'Option 1', value: 'option1' },
502
504
  { label: 'Option 2', value: 'option2' },
503
505
  { label: 'Option 3', value: 'option3' },
@@ -505,7 +507,7 @@ function SettingsPanel() {
505
507
  ];
506
508
 
507
509
  return (
508
- <MultiStateRadio
510
+ <HazoUiFlexRadio
509
511
  data={options}
510
512
  value={selectedOption}
511
513
  onChange={setSelectedOption}
@@ -521,13 +523,13 @@ function SettingsPanel() {
521
523
  **Icon Style with React Icons**
522
524
 
523
525
  ```tsx
524
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
526
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
525
527
  import { useState } from 'react';
526
528
 
527
529
  function IconSelector() {
528
530
  const [selectedIcon, setSelectedIcon] = useState<string>('home');
529
531
 
530
- const iconOptions: MultiStateRadioItem[] = [
532
+ const iconOptions: HazoUiFlexRadioItem[] = [
531
533
  {
532
534
  label: 'Home',
533
535
  value: 'home',
@@ -549,7 +551,7 @@ function IconSelector() {
549
551
  ];
550
552
 
551
553
  return (
552
- <MultiStateRadio
554
+ <HazoUiFlexRadio
553
555
  data={iconOptions}
554
556
  value={selectedIcon}
555
557
  onChange={setSelectedIcon}
@@ -566,13 +568,13 @@ function IconSelector() {
566
568
  **Multi-Selection Mode**
567
569
 
568
570
  ```tsx
569
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
571
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
570
572
  import { useState } from 'react';
571
573
 
572
574
  function MultiSelectExample() {
573
575
  const [selectedOptions, setSelectedOptions] = useState<string[]>(['option1', 'option3']);
574
576
 
575
- const options: MultiStateRadioItem[] = [
577
+ const options: HazoUiFlexRadioItem[] = [
576
578
  { label: 'Option 1', value: 'option1' },
577
579
  { label: 'Option 2', value: 'option2' },
578
580
  { label: 'Option 3', value: 'option3' },
@@ -580,7 +582,7 @@ function MultiSelectExample() {
580
582
  ];
581
583
 
582
584
  return (
583
- <MultiStateRadio
585
+ <HazoUiFlexRadio
584
586
  data={options}
585
587
  value={selectedOptions}
586
588
  onChange={setSelectedOptions}
@@ -596,13 +598,13 @@ function MultiSelectExample() {
596
598
  **Vertical Layout with Icons Only (No Labels)**
597
599
 
598
600
  ```tsx
599
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
601
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
600
602
  import { useState } from 'react';
601
603
 
602
604
  function VerticalIconSelector() {
603
605
  const [selected, setSelected] = useState<string>('favorite');
604
606
 
605
- const options: MultiStateRadioItem[] = [
607
+ const options: HazoUiFlexRadioItem[] = [
606
608
  {
607
609
  label: 'Favorite',
608
610
  value: 'favorite',
@@ -618,7 +620,7 @@ function VerticalIconSelector() {
618
620
  ];
619
621
 
620
622
  return (
621
- <MultiStateRadio
623
+ <HazoUiFlexRadio
622
624
  data={options}
623
625
  value={selected}
624
626
  onChange={setSelected}
@@ -667,6 +669,257 @@ The component supports the following react-icons packages:
667
669
 
668
670
  ---
669
671
 
672
+ ## HazoUiFlexInput
673
+
674
+ An enhanced input component with type validation, character restrictions, and error messaging. Extends shadcn Input component with additional validation props for numeric, alpha, email, and mixed input types.
675
+
676
+ #### Features
677
+
678
+ - **Multiple Input Types**: Supports mixed (text), numeric, alpha (letters only), and email input types
679
+ - **Real-time Character Filtering**: Automatically prevents invalid characters from being entered (e.g., numbers in alpha fields)
680
+ - **Validation on Blur**: Validates input when the field loses focus and displays error messages
681
+ - **Numeric Constraints**: Min/max value validation and decimal precision control
682
+ - **Length Constraints**: Configurable minimum and maximum character lengths
683
+ - **Regex Validation**: Custom regex pattern support for complex validation rules
684
+ - **Format Guide**: Optional helper text displayed below the input
685
+ - **Error Messaging**: Clear error messages displayed when validation fails
686
+ - **Controlled & Uncontrolled**: Supports both controlled and uncontrolled usage patterns
687
+ - **TypeScript Support**: Fully typed with TypeScript interfaces
688
+ - **Accessible**: Built with accessibility in mind using shadcn/ui components
689
+
690
+ #### Input Types
691
+
692
+ 1. **Mixed (text)**
693
+ - Allows any characters
694
+ - Supports length constraints (min/max)
695
+ - Supports regex validation
696
+
697
+ 2. **Numeric**
698
+ - Only allows numbers, decimal point, and minus sign
699
+ - Supports min/max value constraints
700
+ - Configurable decimal precision (including integers with 0 decimals)
701
+ - Automatically filters out non-numeric characters
702
+
703
+ 3. **Alpha**
704
+ - Only allows letters and spaces
705
+ - Automatically filters out numbers and special characters
706
+ - Supports length constraints
707
+
708
+ 4. **Email**
709
+ - Validates email format on blur
710
+ - Uses standard email regex pattern
711
+
712
+ #### Props
713
+
714
+ ```typescript
715
+ interface HazoUiFlexInputProps extends Omit<InputProps, "type"> {
716
+ input_type?: "mixed" | "numeric" | "email" | "alpha"; // Input type (default: "mixed")
717
+ text_len_min?: number; // Minimum character length
718
+ text_len_max?: number; // Maximum character length
719
+ num_min?: number; // Minimum numeric value
720
+ num_max?: number; // Maximum numeric value
721
+ regex?: string | RegExp; // Custom regex pattern
722
+ num_decimals?: number; // Number of decimal places allowed
723
+ format_guide?: string; // Helper text displayed below input
724
+ format_guide_info?: boolean; // Show format guide (default: false)
725
+ }
726
+ ```
727
+
728
+ #### Usage
729
+
730
+ **Basic Mixed Input**
731
+
732
+ ```tsx
733
+ import { HazoUiFlexInput } from 'hazo_ui';
734
+ import { useState } from 'react';
735
+
736
+ function BasicForm() {
737
+ const [value, setValue] = useState<string>("");
738
+
739
+ return (
740
+ <HazoUiFlexInput
741
+ input_type="mixed"
742
+ placeholder="Enter text..."
743
+ value={value}
744
+ onChange={(e) => setValue(e.target.value)}
745
+ />
746
+ );
747
+ }
748
+ ```
749
+
750
+ **Numeric Input with Constraints**
751
+
752
+ ```tsx
753
+ import { HazoUiFlexInput } from 'hazo_ui';
754
+ import { useState } from 'react';
755
+
756
+ function PriceInput() {
757
+ const [price, setPrice] = useState<string>("");
758
+
759
+ return (
760
+ <HazoUiFlexInput
761
+ input_type="numeric"
762
+ placeholder="Enter price (0-100)..."
763
+ num_min={0}
764
+ num_max={100}
765
+ num_decimals={2}
766
+ format_guide="Enter a number between 0 and 100 with up to 2 decimal places"
767
+ format_guide_info={true}
768
+ value={price}
769
+ onChange={(e) => setPrice(e.target.value)}
770
+ />
771
+ );
772
+ }
773
+ ```
774
+
775
+ **Integer Input (No Decimals)**
776
+
777
+ ```tsx
778
+ import { HazoUiFlexInput } from 'hazo_ui';
779
+ import { useState } from 'react';
780
+
781
+ function AgeInput() {
782
+ const [age, setAge] = useState<string>("");
783
+
784
+ return (
785
+ <HazoUiFlexInput
786
+ input_type="numeric"
787
+ placeholder="Enter age (1-120)..."
788
+ num_min={1}
789
+ num_max={120}
790
+ num_decimals={0}
791
+ format_guide="Enter a whole number between 1 and 120"
792
+ format_guide_info={true}
793
+ value={age}
794
+ onChange={(e) => setAge(e.target.value)}
795
+ />
796
+ );
797
+ }
798
+ ```
799
+
800
+ **Alpha Input (Letters Only)**
801
+
802
+ ```tsx
803
+ import { HazoUiFlexInput } from 'hazo_ui';
804
+ import { useState } from 'react';
805
+
806
+ function NameInput() {
807
+ const [name, setName] = useState<string>("");
808
+
809
+ return (
810
+ <HazoUiFlexInput
811
+ input_type="alpha"
812
+ placeholder="Enter name (letters only)..."
813
+ format_guide="Only letters and spaces are allowed"
814
+ format_guide_info={true}
815
+ value={name}
816
+ onChange={(e) => setName(e.target.value)}
817
+ />
818
+ );
819
+ }
820
+ ```
821
+
822
+ **Email Input with Validation**
823
+
824
+ ```tsx
825
+ import { HazoUiFlexInput } from 'hazo_ui';
826
+ import { useState } from 'react';
827
+
828
+ function EmailForm() {
829
+ const [email, setEmail] = useState<string>("");
830
+
831
+ return (
832
+ <HazoUiFlexInput
833
+ input_type="email"
834
+ placeholder="Enter email address..."
835
+ format_guide="Enter a valid email address (e.g., user@example.com)"
836
+ format_guide_info={true}
837
+ value={email}
838
+ onChange={(e) => setEmail(e.target.value)}
839
+ />
840
+ );
841
+ }
842
+ ```
843
+
844
+ **Mixed Input with Length Constraints**
845
+
846
+ ```tsx
847
+ import { HazoUiFlexInput } from 'hazo_ui';
848
+ import { useState } from 'react';
849
+
850
+ function UsernameInput() {
851
+ const [username, setUsername] = useState<string>("");
852
+
853
+ return (
854
+ <HazoUiFlexInput
855
+ input_type="mixed"
856
+ placeholder="Enter username (5-20 characters)..."
857
+ text_len_min={5}
858
+ text_len_max={20}
859
+ format_guide="Must be between 5 and 20 characters"
860
+ format_guide_info={true}
861
+ value={username}
862
+ onChange={(e) => setUsername(e.target.value)}
863
+ />
864
+ );
865
+ }
866
+ ```
867
+
868
+ **Input with Regex Validation**
869
+
870
+ ```tsx
871
+ import { HazoUiFlexInput } from 'hazo_ui';
872
+ import { useState } from 'react';
873
+
874
+ function PhoneInput() {
875
+ const [phone, setPhone] = useState<string>("");
876
+
877
+ return (
878
+ <HazoUiFlexInput
879
+ input_type="mixed"
880
+ placeholder="Enter phone number (XXX-XXX-XXXX)..."
881
+ regex={/^\d{3}-\d{3}-\d{4}$/}
882
+ format_guide="Format: XXX-XXX-XXXX (e.g., 123-456-7890)"
883
+ format_guide_info={true}
884
+ value={phone}
885
+ onChange={(e) => setPhone(e.target.value)}
886
+ />
887
+ );
888
+ }
889
+ ```
890
+
891
+ #### Validation Behavior
892
+
893
+ - **Character Filtering**: For `numeric` and `alpha` types, invalid characters are automatically filtered out as the user types
894
+ - **Validation Timing**: Validation occurs when the input loses focus (onBlur event)
895
+ - **Error Display**: Error messages appear below the input in red text when validation fails
896
+ - **Format Guide**: Optional helper text can be displayed below the input (set `format_guide_info={true}`)
897
+ - **Error Priority**: If both an error message and format guide are present, only the error message is shown
898
+
899
+ #### Expected Output
900
+
901
+ The component behaves like a standard input element:
902
+
903
+ ```typescript
904
+ // onChange receives a standard React.ChangeEvent<HTMLInputElement>
905
+ onChange={(e) => {
906
+ const value = e.target.value; // Current input value as string
907
+ // Handle value change
908
+ }}
909
+ ```
910
+
911
+ #### Error Messages
912
+
913
+ The component provides default error messages for common validation failures:
914
+
915
+ - **Numeric**: "Must be a valid number", "Must be at least X", "Must be at most X", "Maximum X decimal places allowed"
916
+ - **Alpha**: "Only letters are allowed"
917
+ - **Email**: "Must be a valid email address"
918
+ - **Mixed**: "Must be at least X characters", "Must be at most X characters"
919
+ - **Regex**: "Invalid format" (or custom message via `format_guide`)
920
+
921
+ ---
922
+
670
923
  ## Styling
671
924
 
672
925
  Both components use Tailwind CSS and follow shadcn/ui design patterns. Make sure your project has Tailwind CSS configured with the following CSS variables: