hazo_ui 2.7.1 → 2.7.2

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
@@ -174,6 +174,8 @@ The following components support both global config and prop-level color overrid
174
174
 
175
175
  - **[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.
176
176
 
177
+ - **[HazoUiPillRadio](#hazouipillradio)** - Pill-shaped radio selection buttons with optional icons, customizable accent colors, size variants, and equal-width support. Ideal for action choices, status selection, and compact option groups.
178
+
177
179
  - **[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.
178
180
 
179
181
  - **[HazoUiRte](#hazouirte)** - A comprehensive rich text editor for email template generation with variable insertion support, file attachments, and full formatting controls. Built on Tiptap with support for tables, lists, images, and multiple view modes (HTML, Plain Text, Raw HTML).
@@ -884,6 +886,122 @@ The component supports the following react-icons packages:
884
886
 
885
887
  ---
886
888
 
889
+ ## HazoUiPillRadio
890
+
891
+ Pill-shaped radio selection buttons with optional icons, customizable accent colors per pill, size variants, and equal-width support. Ideal for action choices, status selection, and compact option groups.
892
+
893
+ #### Features
894
+
895
+ - **Pill Design**: Rounded-full pill buttons with border, selected state shows accent color tint
896
+ - **Icon Support**: Integration with react-icons library (same icon sets as HazoUiFlexRadio)
897
+ - **Custom Colors**: Each pill can have its own accent color for the selected state
898
+ - **Size Variants**: Three sizes — `sm`, `md` (default), `lg`
899
+ - **Layout Options**: Horizontal (default) or vertical arrangement
900
+ - **Equal Width**: Optional `equal_width` prop makes all pills the same width
901
+ - **Auto-fit Vertical**: Vertical layout auto-fits to the widest pill instead of stretching full-width
902
+ - **Tooltips**: Hover tooltips with 1-second delay
903
+ - **Accessible**: Uses `role="radiogroup"` and `role="radio"` with `aria-checked`
904
+
905
+ #### Props
906
+
907
+ ```typescript
908
+ interface HazoUiPillRadioItem {
909
+ label: string; // Text displayed in the pill
910
+ value: string; // Unique value identifier
911
+ icon?: string; // react-icons icon name (e.g., "FaFolder")
912
+ color?: string; // Accent color when selected (default: "#3b82f6" blue)
913
+ }
914
+
915
+ interface HazoUiPillRadioProps {
916
+ layout?: 'horizontal' | 'vertical'; // Layout direction (default: 'horizontal')
917
+ icon_set?: string; // Icon set package name (default: 'fa')
918
+ data: HazoUiPillRadioItem[]; // Array of pill options
919
+ value: string; // Controlled selected value
920
+ onChange: (value: string) => void; // Change handler
921
+ className?: string; // Additional CSS classes
922
+ pill_size?: 'sm' | 'md' | 'lg'; // Pill size variant (default: 'md')
923
+ equal_width?: boolean; // Make all pills equal width (default: false)
924
+ }
925
+ ```
926
+
927
+ #### Usage
928
+
929
+ **Basic Horizontal Pills**
930
+
931
+ ```tsx
932
+ import { HazoUiPillRadio, type HazoUiPillRadioItem } from 'hazo_ui';
933
+ import { useState } from 'react';
934
+
935
+ function ResponseSelector() {
936
+ const [selected, setSelected] = useState<string>('');
937
+
938
+ const options: HazoUiPillRadioItem[] = [
939
+ { value: 'upload', label: 'Upload corrected document', icon: 'FaFolder' },
940
+ { value: 'comment', label: 'Provide comment', icon: 'FaComment' },
941
+ ];
942
+
943
+ return (
944
+ <HazoUiPillRadio
945
+ data={options}
946
+ value={selected}
947
+ onChange={setSelected}
948
+ />
949
+ );
950
+ }
951
+ ```
952
+
953
+ **Vertical Layout**
954
+
955
+ ```tsx
956
+ <HazoUiPillRadio
957
+ data={options}
958
+ value={selected}
959
+ onChange={setSelected}
960
+ layout="vertical"
961
+ />
962
+ ```
963
+
964
+ **Custom Colors per Pill**
965
+
966
+ ```tsx
967
+ const priority_options: HazoUiPillRadioItem[] = [
968
+ { value: 'low', label: 'Low', icon: 'FaArrowDown', color: '#22c55e' },
969
+ { value: 'medium', label: 'Medium', icon: 'FaMinus', color: '#f59e0b' },
970
+ { value: 'high', label: 'High', icon: 'FaArrowUp', color: '#ef4444' },
971
+ ];
972
+
973
+ <HazoUiPillRadio
974
+ data={priority_options}
975
+ value={selected}
976
+ onChange={setSelected}
977
+ />
978
+ ```
979
+
980
+ **Equal Width Pills**
981
+
982
+ ```tsx
983
+ <HazoUiPillRadio
984
+ data={options}
985
+ value={selected}
986
+ onChange={setSelected}
987
+ equal_width
988
+ />
989
+ ```
990
+
991
+ **Different Icon Set and Size**
992
+
993
+ ```tsx
994
+ <HazoUiPillRadio
995
+ data={options}
996
+ value={selected}
997
+ onChange={setSelected}
998
+ icon_set="md"
999
+ pill_size="lg"
1000
+ />
1001
+ ```
1002
+
1003
+ ---
1004
+
887
1005
  ## HazoUiFlexInput
888
1006
 
889
1007
  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.
package/dist/index.cjs CHANGED
@@ -1739,6 +1739,109 @@ function HazoUiFlexRadio({
1739
1739
  }
1740
1740
  }
1741
1741
  }
1742
+ var icon_set_map = {
1743
+ fa: FaIcons__namespace,
1744
+ md: MdIcons__namespace,
1745
+ hi: HiIcons__namespace,
1746
+ bi: BiIcons__namespace,
1747
+ ai: AiIcons__namespace,
1748
+ bs: BsIcons__namespace,
1749
+ fi: FiIcons__namespace,
1750
+ io: IoIcons__namespace,
1751
+ io5: IoIcons__namespace,
1752
+ ri: RiIcons__namespace,
1753
+ tb: TbIcons__namespace,
1754
+ ci: CiIcons__namespace
1755
+ };
1756
+ function get_icon_component(icon_set, icon_name) {
1757
+ if (!icon_set || !icon_name) return null;
1758
+ const library = icon_set_map[icon_set.toLowerCase()];
1759
+ if (!library) return null;
1760
+ return library[icon_name] || null;
1761
+ }
1762
+ var DEFAULT_COLOR = "#3b82f6";
1763
+ function color_with_opacity(color2, opacity) {
1764
+ if (color2.startsWith("#")) {
1765
+ const hex = color2.replace("#", "");
1766
+ const r = parseInt(hex.substring(0, 2), 16);
1767
+ const g = parseInt(hex.substring(2, 4), 16);
1768
+ const b = parseInt(hex.substring(4, 6), 16);
1769
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
1770
+ }
1771
+ return color2;
1772
+ }
1773
+ var size_classes = {
1774
+ sm: "px-3 py-1.5 text-xs gap-1.5",
1775
+ md: "px-4 py-2 text-sm gap-2",
1776
+ lg: "px-5 py-2.5 text-base gap-2.5"
1777
+ };
1778
+ var icon_size_classes = {
1779
+ sm: "h-3.5 w-3.5",
1780
+ md: "h-4 w-4",
1781
+ lg: "h-5 w-5"
1782
+ };
1783
+ function HazoUiPillRadio({
1784
+ layout = "horizontal",
1785
+ icon_set = "fa",
1786
+ data,
1787
+ value,
1788
+ onChange,
1789
+ className,
1790
+ pill_size = "md",
1791
+ equal_width = false
1792
+ }) {
1793
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 1e3, children: /* @__PURE__ */ jsxRuntime.jsx(
1794
+ "div",
1795
+ {
1796
+ className: cn(
1797
+ "cls_hazo_ui_pill_radio",
1798
+ layout === "horizontal" ? "flex flex-row flex-wrap gap-3" : "inline-flex flex-col gap-3",
1799
+ className
1800
+ ),
1801
+ role: "radiogroup",
1802
+ children: data.map((item) => {
1803
+ const is_selected = value === item.value;
1804
+ const accent = item.color || DEFAULT_COLOR;
1805
+ const IconComponent = get_icon_component(icon_set, item.icon);
1806
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { delayDuration: 1e3, children: [
1807
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1808
+ "button",
1809
+ {
1810
+ type: "button",
1811
+ role: "radio",
1812
+ "aria-checked": is_selected,
1813
+ onClick: () => onChange(item.value),
1814
+ className: cn(
1815
+ "cls_pill_radio_item",
1816
+ "inline-flex items-center rounded-full border cursor-pointer",
1817
+ "transition-all duration-200 font-medium whitespace-nowrap",
1818
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
1819
+ size_classes[pill_size],
1820
+ equal_width && "justify-center flex-1",
1821
+ !is_selected && "border-border bg-card text-muted-foreground hover:bg-accent/50"
1822
+ ),
1823
+ style: is_selected ? {
1824
+ borderColor: accent,
1825
+ backgroundColor: color_with_opacity(accent, 0.08),
1826
+ color: accent
1827
+ } : void 0,
1828
+ children: [
1829
+ IconComponent && /* @__PURE__ */ jsxRuntime.jsx(
1830
+ IconComponent,
1831
+ {
1832
+ className: cn("cls_pill_radio_icon shrink-0", icon_size_classes[pill_size])
1833
+ }
1834
+ ),
1835
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_pill_radio_label", children: item.label })
1836
+ ]
1837
+ }
1838
+ ) }),
1839
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "cls_tooltip_text", children: item.label }) })
1840
+ ] }, item.value);
1841
+ })
1842
+ }
1843
+ ) });
1844
+ }
1742
1845
  function validateInput(value, input_type, text_len_min, text_len_max, num_min, num_max, regex, num_decimals) {
1743
1846
  if (value === "") {
1744
1847
  return { isValid: true };
@@ -6937,6 +7040,7 @@ exports.HazoUiFlexInput = HazoUiFlexInput;
6937
7040
  exports.HazoUiFlexRadio = HazoUiFlexRadio;
6938
7041
  exports.HazoUiMultiFilterDialog = HazoUiMultiFilterDialog;
6939
7042
  exports.HazoUiMultiSortDialog = HazoUiMultiSortDialog;
7043
+ exports.HazoUiPillRadio = HazoUiPillRadio;
6940
7044
  exports.HazoUiRte = HazoUiRte;
6941
7045
  exports.HazoUiTextarea = HazoUiTextarea;
6942
7046
  exports.HazoUiTextbox = HazoUiTextbox;