hazo_ui 2.1.1 → 2.2.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/README.md CHANGED
@@ -12,25 +12,25 @@ 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
20
 
21
21
  ---
22
22
 
23
- ## MultiFilterDialog
23
+ ## HazoUiMultiFilterDialog
24
24
 
25
25
  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
26
 
27
- ![MultiFilterDialog - Filter Button with Active Filters Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-button-tooltip.png)
27
+ ![HazoUiMultiFilterDialog - Filter Button with Active Filters Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-button-tooltip.png)
28
28
 
29
- ![MultiFilterDialog - Dialog with Multiple Filters](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog.png)
29
+ ![HazoUiMultiFilterDialog - Dialog with Multiple Filters](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog.png)
30
30
 
31
- ![MultiFilterDialog - Calendar Date Picker](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog-calendar.png)
31
+ ![HazoUiMultiFilterDialog - Calendar Date Picker](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-dialog-calendar.png)
32
32
 
33
- ![MultiFilterDialog - Filter Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-output.png)
33
+ ![HazoUiMultiFilterDialog - Filter Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multifilterdialog/filter-output.png)
34
34
 
35
35
  #### Features
36
36
 
@@ -71,7 +71,7 @@ A powerful, flexible dialog component for multi-field filtering with support for
71
71
  #### Usage
72
72
 
73
73
  ```tsx
74
- import { MultiFilterDialog, type FilterField, type FilterConfig } from 'hazo_ui';
74
+ import { HazoUiMultiFilterDialog, type FilterField, type FilterConfig } from 'hazo_ui';
75
75
  import { useState } from 'react';
76
76
 
77
77
  function DataTable() {
@@ -145,7 +145,7 @@ function DataTable() {
145
145
 
146
146
  return (
147
147
  <div>
148
- <MultiFilterDialog
148
+ <HazoUiMultiFilterDialog
149
149
  availableFields={availableFields}
150
150
  onFilterChange={handleFilterChange}
151
151
  initialFilters={filters}
@@ -239,17 +239,17 @@ When users apply filters, the `onFilterChange` callback receives an array of `Fi
239
239
 
240
240
  ---
241
241
 
242
- ## MultiSortDialog
242
+ ## HazoUiMultiSortDialog
243
243
 
244
244
  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
245
 
246
- ![MultiSortDialog - Sort Button with Active Sorts Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-button-tooltip.png)
246
+ ![HazoUiMultiSortDialog - Sort Button with Active Sorts Tooltip](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-button-tooltip.png)
247
247
 
248
- ![MultiSortDialog - Dialog with Multiple Sort Fields](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-dialog.png)
248
+ ![HazoUiMultiSortDialog - Dialog with Multiple Sort Fields](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-dialog.png)
249
249
 
250
- ![MultiSortDialog - Drag and Drop Reordering](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-drag-drop.png)
250
+ ![HazoUiMultiSortDialog - Drag and Drop Reordering](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-drag-drop.png)
251
251
 
252
- ![MultiSortDialog - Sort Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-output.png)
252
+ ![HazoUiMultiSortDialog - Sort Output Example](https://github.com/pub12/hazo_ui/raw/main/docs/multisortdialog/sort-output.png)
253
253
 
254
254
  #### Features
255
255
 
@@ -278,7 +278,7 @@ The component returns an array of sort configurations in priority order, where t
278
278
  #### Usage
279
279
 
280
280
  ```tsx
281
- import { MultiSortDialog, type SortField, type SortConfig } from 'hazo_ui';
281
+ import { HazoUiMultiSortDialog, type SortField, type SortConfig } from 'hazo_ui';
282
282
  import { useState } from 'react';
283
283
 
284
284
  function DataTable() {
@@ -319,7 +319,7 @@ function DataTable() {
319
319
 
320
320
  return (
321
321
  <div>
322
- <MultiSortDialog
322
+ <HazoUiMultiSortDialog
323
323
  availableFields={availableFields}
324
324
  onSortChange={handleSortChange}
325
325
  initialSortFields={sorts}
@@ -446,7 +446,7 @@ const sortedData = applySorts(originalData, sorts);
446
446
 
447
447
  ---
448
448
 
449
- ## MultiStateRadio
449
+ ## HazoUiFlexRadio
450
450
 
451
451
  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
452
 
@@ -466,19 +466,19 @@ A flexible radio button/icon selection component with support for single and mul
466
466
  #### Props
467
467
 
468
468
  ```typescript
469
- interface MultiStateRadioItem {
469
+ interface HazoUiFlexRadioItem {
470
470
  label: string; // Display label for the option
471
471
  value: string; // Unique value identifier
472
472
  icon_selected?: string; // Icon name when selected (e.g., "FaHome")
473
473
  icon_unselected?: string; // Icon name when unselected (e.g., "FaRegHome")
474
474
  }
475
475
 
476
- interface MultiStateRadioProps {
476
+ interface HazoUiFlexRadioProps {
477
477
  layout?: 'horizontal' | 'vertical'; // Layout direction (default: 'horizontal')
478
478
  style?: 'radio' | 'icons'; // Display style (default: 'radio')
479
479
  display_label?: boolean; // Show/hide labels (default: true)
480
480
  icon_set?: string; // Icon set package name (e.g., 'fa', 'md')
481
- data: MultiStateRadioItem[]; // Array of options
481
+ data: HazoUiFlexRadioItem[]; // Array of options
482
482
  selection: 'single' | 'multi'; // Selection mode
483
483
  value: string | string[]; // Controlled value (string for single, array for multi)
484
484
  onChange: (value: string | string[]) => void; // Change handler
@@ -491,13 +491,13 @@ interface MultiStateRadioProps {
491
491
  **Basic Single Selection (Radio Style)**
492
492
 
493
493
  ```tsx
494
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
494
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
495
495
  import { useState } from 'react';
496
496
 
497
497
  function SettingsPanel() {
498
498
  const [selectedOption, setSelectedOption] = useState<string>('option1');
499
499
 
500
- const options: MultiStateRadioItem[] = [
500
+ const options: HazoUiFlexRadioItem[] = [
501
501
  { label: 'Option 1', value: 'option1' },
502
502
  { label: 'Option 2', value: 'option2' },
503
503
  { label: 'Option 3', value: 'option3' },
@@ -505,7 +505,7 @@ function SettingsPanel() {
505
505
  ];
506
506
 
507
507
  return (
508
- <MultiStateRadio
508
+ <HazoUiFlexRadio
509
509
  data={options}
510
510
  value={selectedOption}
511
511
  onChange={setSelectedOption}
@@ -521,13 +521,13 @@ function SettingsPanel() {
521
521
  **Icon Style with React Icons**
522
522
 
523
523
  ```tsx
524
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
524
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
525
525
  import { useState } from 'react';
526
526
 
527
527
  function IconSelector() {
528
528
  const [selectedIcon, setSelectedIcon] = useState<string>('home');
529
529
 
530
- const iconOptions: MultiStateRadioItem[] = [
530
+ const iconOptions: HazoUiFlexRadioItem[] = [
531
531
  {
532
532
  label: 'Home',
533
533
  value: 'home',
@@ -549,7 +549,7 @@ function IconSelector() {
549
549
  ];
550
550
 
551
551
  return (
552
- <MultiStateRadio
552
+ <HazoUiFlexRadio
553
553
  data={iconOptions}
554
554
  value={selectedIcon}
555
555
  onChange={setSelectedIcon}
@@ -566,13 +566,13 @@ function IconSelector() {
566
566
  **Multi-Selection Mode**
567
567
 
568
568
  ```tsx
569
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
569
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
570
570
  import { useState } from 'react';
571
571
 
572
572
  function MultiSelectExample() {
573
573
  const [selectedOptions, setSelectedOptions] = useState<string[]>(['option1', 'option3']);
574
574
 
575
- const options: MultiStateRadioItem[] = [
575
+ const options: HazoUiFlexRadioItem[] = [
576
576
  { label: 'Option 1', value: 'option1' },
577
577
  { label: 'Option 2', value: 'option2' },
578
578
  { label: 'Option 3', value: 'option3' },
@@ -580,7 +580,7 @@ function MultiSelectExample() {
580
580
  ];
581
581
 
582
582
  return (
583
- <MultiStateRadio
583
+ <HazoUiFlexRadio
584
584
  data={options}
585
585
  value={selectedOptions}
586
586
  onChange={setSelectedOptions}
@@ -596,13 +596,13 @@ function MultiSelectExample() {
596
596
  **Vertical Layout with Icons Only (No Labels)**
597
597
 
598
598
  ```tsx
599
- import { MultiStateRadio, type MultiStateRadioItem } from 'hazo_ui';
599
+ import { HazoUiFlexRadio, type HazoUiFlexRadioItem } from 'hazo_ui';
600
600
  import { useState } from 'react';
601
601
 
602
602
  function VerticalIconSelector() {
603
603
  const [selected, setSelected] = useState<string>('favorite');
604
604
 
605
- const options: MultiStateRadioItem[] = [
605
+ const options: HazoUiFlexRadioItem[] = [
606
606
  {
607
607
  label: 'Favorite',
608
608
  value: 'favorite',
@@ -618,7 +618,7 @@ function VerticalIconSelector() {
618
618
  ];
619
619
 
620
620
  return (
621
- <MultiStateRadio
621
+ <HazoUiFlexRadio
622
622
  data={options}
623
623
  value={selected}
624
624
  onChange={setSelected}
package/dist/index.cjs CHANGED
@@ -28,6 +28,7 @@ var FiIcons = require('react-icons/fi');
28
28
  var IoIcons = require('react-icons/io5');
29
29
  var RiIcons = require('react-icons/ri');
30
30
  var TbIcons = require('react-icons/tb');
31
+ var CiIcons = require('react-icons/ci');
31
32
 
32
33
  function _interopNamespace(e) {
33
34
  if (e && e.__esModule) return e;
@@ -64,6 +65,7 @@ var FiIcons__namespace = /*#__PURE__*/_interopNamespace(FiIcons);
64
65
  var IoIcons__namespace = /*#__PURE__*/_interopNamespace(IoIcons);
65
66
  var RiIcons__namespace = /*#__PURE__*/_interopNamespace(RiIcons);
66
67
  var TbIcons__namespace = /*#__PURE__*/_interopNamespace(TbIcons);
68
+ var CiIcons__namespace = /*#__PURE__*/_interopNamespace(CiIcons);
67
69
 
68
70
  var ExampleComponent = ({ children, className = "" }) => {
69
71
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `cls_example_component ${className}`, children });
@@ -660,7 +662,7 @@ function FilterFieldItem({
660
662
  )
661
663
  ] });
662
664
  }
663
- function MultiFilterDialog({
665
+ function HazoUiMultiFilterDialog({
664
666
  availableFields,
665
667
  onFilterChange,
666
668
  initialFilters = []
@@ -980,7 +982,7 @@ function SortableSortFieldItem({
980
982
  }
981
983
  );
982
984
  }
983
- function MultiSortDialog({
985
+ function HazoUiMultiSortDialog({
984
986
  availableFields,
985
987
  onSortChange,
986
988
  initialSortFields = []
@@ -1230,7 +1232,8 @@ var iconSetMap = {
1230
1232
  io: IoIcons__namespace,
1231
1233
  io5: IoIcons__namespace,
1232
1234
  ri: RiIcons__namespace,
1233
- tb: TbIcons__namespace
1235
+ tb: TbIcons__namespace,
1236
+ ci: CiIcons__namespace
1234
1237
  };
1235
1238
  function getIconLibrary(iconSet) {
1236
1239
  if (!iconSet) return null;
@@ -1244,7 +1247,7 @@ function getIconComponent(iconSet, iconName) {
1244
1247
  const IconComponent = iconLibrary[iconName];
1245
1248
  return IconComponent || null;
1246
1249
  }
1247
- function MultiStateRadio({
1250
+ function HazoUiFlexRadio({
1248
1251
  layout = "horizontal",
1249
1252
  style = "radio",
1250
1253
  display_label = true,
@@ -1376,6 +1379,10 @@ function MultiStateRadio({
1376
1379
  const SelectedIcon = icon_set && item.icon_selected ? getIconComponent(icon_set, item.icon_selected) : null;
1377
1380
  const UnselectedIcon = icon_set && item.icon_unselected ? getIconComponent(icon_set, item.icon_unselected) : null;
1378
1381
  const IconComponent = selected && SelectedIcon ? SelectedIcon : UnselectedIcon || SelectedIcon;
1382
+ const buttonStyles = {};
1383
+ if (item.bgcolor) {
1384
+ buttonStyles.backgroundColor = item.bgcolor;
1385
+ }
1379
1386
  const buttonContent = /* @__PURE__ */ jsxRuntime.jsxs(
1380
1387
  Button,
1381
1388
  {
@@ -1386,9 +1393,11 @@ function MultiStateRadio({
1386
1393
  layout === "horizontal" ? "flex-row" : "flex-col",
1387
1394
  "gap-2 h-auto",
1388
1395
  compressed ? "py-0 px-0" : "py-2 px-3 sm:py-3 sm:px-4",
1389
- selected && "bg-primary text-primary-foreground",
1390
- !selected && "hover:bg-accent"
1396
+ // Only apply default colors if custom colors are not provided
1397
+ !item.bgcolor && selected && "bg-primary text-primary-foreground",
1398
+ !item.bgcolor && !selected && "hover:bg-accent"
1391
1399
  ),
1400
+ style: Object.keys(buttonStyles).length > 0 ? buttonStyles : void 0,
1392
1401
  onClick: () => {
1393
1402
  if (selection === "single") {
1394
1403
  handleSingleSelection(item.value);
@@ -1399,8 +1408,21 @@ function MultiStateRadio({
1399
1408
  "aria-label": item.label,
1400
1409
  "aria-pressed": selected,
1401
1410
  children: [
1402
- IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "cls_icon h-4 w-4 sm:h-5 sm:w-5" }),
1403
- display_label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_icon_label text-sm font-medium", children: item.label })
1411
+ IconComponent && /* @__PURE__ */ jsxRuntime.jsx(
1412
+ IconComponent,
1413
+ {
1414
+ className: "cls_icon h-4 w-4 sm:h-5 sm:w-5",
1415
+ style: item.fgcolor ? { color: item.fgcolor } : void 0
1416
+ }
1417
+ ),
1418
+ display_label && /* @__PURE__ */ jsxRuntime.jsx(
1419
+ "span",
1420
+ {
1421
+ className: "cls_icon_label text-sm font-medium",
1422
+ style: item.fgcolor ? { color: item.fgcolor } : void 0,
1423
+ children: item.label
1424
+ }
1425
+ )
1404
1426
  ]
1405
1427
  }
1406
1428
  );
@@ -1410,7 +1432,7 @@ function MultiStateRadio({
1410
1432
  ] }, item.value);
1411
1433
  };
1412
1434
  const containerClasses = cn(
1413
- "cls_multi_state_radio border border-input rounded-md",
1435
+ "cls_hazo_ui_flex_radio border border-input rounded-md",
1414
1436
  compressed ? "" : "p-2 sm:p-3",
1415
1437
  layout === "horizontal" ? cn(
1416
1438
  "flex flex-row flex-wrap",
@@ -1444,10 +1466,208 @@ function MultiStateRadio({
1444
1466
  }
1445
1467
  }
1446
1468
  }
1469
+ function validateInput(value, input_type, text_len_min, text_len_max, num_min, num_max, regex, num_decimals) {
1470
+ if (value === "") {
1471
+ return { isValid: true };
1472
+ }
1473
+ switch (input_type) {
1474
+ case "numeric": {
1475
+ const numValue = parseFloat(value);
1476
+ if (isNaN(numValue)) {
1477
+ return { isValid: false, errorMessage: "Must be a valid number" };
1478
+ }
1479
+ if (num_decimals !== void 0) {
1480
+ const decimalPlaces = value.split(".")[1]?.length || 0;
1481
+ if (decimalPlaces > num_decimals) {
1482
+ return {
1483
+ isValid: false,
1484
+ errorMessage: `Maximum ${num_decimals} decimal place${num_decimals !== 1 ? "s" : ""} allowed`
1485
+ };
1486
+ }
1487
+ }
1488
+ if (num_min !== void 0 && numValue < num_min) {
1489
+ return { isValid: false, errorMessage: `Must be at least ${num_min}` };
1490
+ }
1491
+ if (num_max !== void 0 && numValue > num_max) {
1492
+ return { isValid: false, errorMessage: `Must be at most ${num_max}` };
1493
+ }
1494
+ break;
1495
+ }
1496
+ case "alpha": {
1497
+ const alphaRegex = /^[A-Za-z\s]*$/;
1498
+ if (!alphaRegex.test(value)) {
1499
+ return { isValid: false, errorMessage: "Only letters are allowed" };
1500
+ }
1501
+ break;
1502
+ }
1503
+ case "email": {
1504
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1505
+ if (!emailRegex.test(value)) {
1506
+ return { isValid: false, errorMessage: "Must be a valid email address" };
1507
+ }
1508
+ break;
1509
+ }
1510
+ case "mixed": {
1511
+ if (text_len_min !== void 0 && value.length < text_len_min) {
1512
+ return {
1513
+ isValid: false,
1514
+ errorMessage: `Must be at least ${text_len_min} character${text_len_min !== 1 ? "s" : ""}`
1515
+ };
1516
+ }
1517
+ if (text_len_max !== void 0 && value.length > text_len_max) {
1518
+ return {
1519
+ isValid: false,
1520
+ errorMessage: `Must be at most ${text_len_max} character${text_len_max !== 1 ? "s" : ""}`
1521
+ };
1522
+ }
1523
+ break;
1524
+ }
1525
+ }
1526
+ if (regex) {
1527
+ const regexPattern = typeof regex === "string" ? new RegExp(regex) : regex;
1528
+ if (!regexPattern.test(value)) {
1529
+ return { isValid: false, errorMessage: "Invalid format" };
1530
+ }
1531
+ }
1532
+ return { isValid: true };
1533
+ }
1534
+ function filterInputValue(value, input_type, num_decimals) {
1535
+ switch (input_type) {
1536
+ case "numeric": {
1537
+ let filtered = value.replace(/[^\d.-]/g, "");
1538
+ const parts = filtered.split(".");
1539
+ if (parts.length > 2) {
1540
+ filtered = parts[0] + "." + parts.slice(1).join("");
1541
+ }
1542
+ if (num_decimals === 0 && filtered.includes(".")) {
1543
+ filtered = filtered.replace(".", "");
1544
+ }
1545
+ if (num_decimals !== void 0 && num_decimals > 0) {
1546
+ const parts2 = filtered.split(".");
1547
+ if (parts2.length === 2 && parts2[1].length > num_decimals) {
1548
+ filtered = parts2[0] + "." + parts2[1].substring(0, num_decimals);
1549
+ }
1550
+ }
1551
+ return filtered;
1552
+ }
1553
+ case "alpha": {
1554
+ return value.replace(/[^A-Za-z\s]/g, "");
1555
+ }
1556
+ case "email":
1557
+ case "mixed":
1558
+ default: {
1559
+ return value;
1560
+ }
1561
+ }
1562
+ }
1563
+ var HazoUiFlexInput = React6__namespace.forwardRef(
1564
+ ({
1565
+ className,
1566
+ input_type = "mixed",
1567
+ text_len_min,
1568
+ text_len_max,
1569
+ num_min,
1570
+ num_max,
1571
+ regex,
1572
+ num_decimals,
1573
+ format_guide,
1574
+ format_guide_info = false,
1575
+ value: controlledValue,
1576
+ onChange,
1577
+ onBlur,
1578
+ ...props
1579
+ }, ref) => {
1580
+ const [internalValue, setInternalValue] = React6__namespace.useState(
1581
+ typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
1582
+ );
1583
+ const [errorMessage, setErrorMessage] = React6__namespace.useState();
1584
+ const isControlled = controlledValue !== void 0;
1585
+ const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
1586
+ React6__namespace.useEffect(() => {
1587
+ if (isControlled) {
1588
+ const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
1589
+ if (newValue !== internalValue) {
1590
+ setInternalValue(newValue);
1591
+ }
1592
+ }
1593
+ }, [controlledValue, isControlled]);
1594
+ const handleChange = (e) => {
1595
+ let newValue = e.target.value;
1596
+ if (input_type === "numeric" || input_type === "alpha") {
1597
+ newValue = filterInputValue(newValue, input_type, num_decimals);
1598
+ }
1599
+ if (!isControlled) {
1600
+ setInternalValue(newValue);
1601
+ }
1602
+ if (errorMessage) {
1603
+ setErrorMessage(void 0);
1604
+ }
1605
+ if (onChange) {
1606
+ const syntheticEvent = {
1607
+ ...e,
1608
+ target: { ...e.target, value: newValue }
1609
+ };
1610
+ onChange(syntheticEvent);
1611
+ }
1612
+ };
1613
+ const handleBlur = (e) => {
1614
+ const validation = validateInput(
1615
+ currentValue,
1616
+ input_type,
1617
+ text_len_min,
1618
+ text_len_max,
1619
+ num_min,
1620
+ num_max,
1621
+ regex,
1622
+ num_decimals
1623
+ );
1624
+ if (!validation.isValid) {
1625
+ setErrorMessage(validation.errorMessage || format_guide || "Invalid input");
1626
+ } else {
1627
+ setErrorMessage(void 0);
1628
+ }
1629
+ if (onBlur) {
1630
+ onBlur(e);
1631
+ }
1632
+ };
1633
+ const htmlInputType = input_type === "email" ? "email" : input_type === "numeric" ? "text" : "text";
1634
+ const hasError = errorMessage !== void 0;
1635
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_ui_flex_input_container w-full", children: [
1636
+ /* @__PURE__ */ jsxRuntime.jsx(
1637
+ Input,
1638
+ {
1639
+ ref,
1640
+ type: htmlInputType,
1641
+ value: currentValue,
1642
+ onChange: handleChange,
1643
+ onBlur: handleBlur,
1644
+ className: cn(
1645
+ hasError && "border-destructive focus-visible:ring-destructive",
1646
+ className
1647
+ ),
1648
+ ...props
1649
+ }
1650
+ ),
1651
+ hasError && errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "cls_error_message mt-1 text-sm text-destructive", children: errorMessage }),
1652
+ format_guide_info && format_guide && /* @__PURE__ */ jsxRuntime.jsx(
1653
+ "p",
1654
+ {
1655
+ className: cn(
1656
+ "cls_format_guide_info mt-1 text-xs italic text-muted-foreground",
1657
+ hasError && "mt-0"
1658
+ ),
1659
+ children: format_guide
1660
+ }
1661
+ )
1662
+ ] });
1663
+ }
1664
+ );
1665
+ HazoUiFlexInput.displayName = "HazoUiFlexInput";
1447
1666
 
1448
1667
  exports.ExampleComponent = ExampleComponent;
1449
- exports.MultiFilterDialog = MultiFilterDialog;
1450
- exports.MultiSortDialog = MultiSortDialog;
1451
- exports.MultiStateRadio = MultiStateRadio;
1668
+ exports.HazoUiFlexInput = HazoUiFlexInput;
1669
+ exports.HazoUiFlexRadio = HazoUiFlexRadio;
1670
+ exports.HazoUiMultiFilterDialog = HazoUiMultiFilterDialog;
1671
+ exports.HazoUiMultiSortDialog = HazoUiMultiSortDialog;
1452
1672
  //# sourceMappingURL=index.cjs.map
1453
1673
  //# sourceMappingURL=index.cjs.map