infinity-ui-elements 1.4.0 → 1.4.1-beta.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.
Files changed (47) hide show
  1. package/dist/components/Badge/Badge.d.ts +28 -0
  2. package/dist/components/Badge/Badge.d.ts.map +1 -0
  3. package/dist/components/Badge/Badge.stories.d.ts +16 -0
  4. package/dist/components/Badge/Badge.stories.d.ts.map +1 -0
  5. package/dist/components/Badge/index.d.ts +3 -0
  6. package/dist/components/Badge/index.d.ts.map +1 -0
  7. package/dist/components/Button/Button.d.ts +1 -1
  8. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  9. package/dist/components/Counter/Counter.d.ts +24 -0
  10. package/dist/components/Counter/Counter.d.ts.map +1 -0
  11. package/dist/components/Counter/Counter.stories.d.ts +14 -0
  12. package/dist/components/Counter/Counter.stories.d.ts.map +1 -0
  13. package/dist/components/Counter/index.d.ts +3 -0
  14. package/dist/components/Counter/index.d.ts.map +1 -0
  15. package/dist/components/Divider/Divider.d.ts +37 -0
  16. package/dist/components/Divider/Divider.d.ts.map +1 -0
  17. package/dist/components/Divider/Divider.stories.d.ts +12 -0
  18. package/dist/components/Divider/Divider.stories.d.ts.map +1 -0
  19. package/dist/components/Divider/index.d.ts +2 -0
  20. package/dist/components/Divider/index.d.ts.map +1 -0
  21. package/dist/components/ListItem/ListItem.d.ts +63 -0
  22. package/dist/components/ListItem/ListItem.d.ts.map +1 -0
  23. package/dist/components/ListItem/ListItem.stories.d.ts +66 -0
  24. package/dist/components/ListItem/ListItem.stories.d.ts.map +1 -0
  25. package/dist/components/ListItem/index.d.ts +3 -0
  26. package/dist/components/ListItem/index.d.ts.map +1 -0
  27. package/dist/components/Radio/Radio.d.ts +45 -0
  28. package/dist/components/Radio/Radio.d.ts.map +1 -0
  29. package/dist/components/Radio/Radio.stories.d.ts +23 -0
  30. package/dist/components/Radio/Radio.stories.d.ts.map +1 -0
  31. package/dist/components/Radio/index.d.ts +3 -0
  32. package/dist/components/Radio/index.d.ts.map +1 -0
  33. package/dist/components/Switch/Switch.d.ts +39 -0
  34. package/dist/components/Switch/Switch.d.ts.map +1 -0
  35. package/dist/components/Switch/Switch.stories.d.ts +37 -0
  36. package/dist/components/Switch/Switch.stories.d.ts.map +1 -0
  37. package/dist/components/Switch/index.d.ts +3 -0
  38. package/dist/components/Switch/index.d.ts.map +1 -0
  39. package/dist/components/TextArea/TextArea.d.ts.map +1 -1
  40. package/dist/index.css +1 -1
  41. package/dist/index.d.ts +6 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.esm.js +756 -23
  44. package/dist/index.esm.js.map +1 -1
  45. package/dist/index.js +765 -21
  46. package/dist/index.js.map +1 -1
  47. package/package.json +6 -2
package/dist/index.js CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
- var reactSlot = require('@radix-ui/react-slot');
6
5
  var classVarianceAuthority = require('class-variance-authority');
7
- var reactSpinners = require('react-spinners');
8
6
  var clsx = require('clsx');
9
7
  var tailwindMerge = require('tailwind-merge');
8
+ var reactSlot = require('@radix-ui/react-slot');
9
+ var reactSpinners = require('react-spinners');
10
10
 
11
11
  function _interopNamespaceDefault(e) {
12
12
  var n = Object.create(null);
@@ -66,6 +66,132 @@ function cn(...inputs) {
66
66
  return clsx.clsx(mergedStandard, customClasses);
67
67
  }
68
68
 
69
+ const badgeVariants = classVarianceAuthority.cva("inline-flex items-center whitespace-nowrap transition-colors", {
70
+ variants: {
71
+ variant: {
72
+ light: "",
73
+ filled: "",
74
+ },
75
+ color: {
76
+ primary: "",
77
+ positive: "",
78
+ negative: "",
79
+ notice: "",
80
+ info: "",
81
+ neutral: "",
82
+ },
83
+ size: {
84
+ small: "px-2 h-[var(--size-20)] gap-2 rounded-large text-body-small-medium",
85
+ medium: "px-3 h-[var(--size-24)] gap-3 rounded-large text-body-medium-medium",
86
+ large: "px-4 h-[var(--size-28)] gap-3 rounded-xlarge text-body-large-medium",
87
+ },
88
+ },
89
+ compoundVariants: [
90
+ // Light variant colors
91
+ {
92
+ variant: "light",
93
+ color: "primary",
94
+ class: "bg-action-fill-primary-faded text-action-ink-primary-normal",
95
+ },
96
+ {
97
+ variant: "light",
98
+ color: "positive",
99
+ class: "bg-action-fill-positive-faded text-action-ink-positive-normal",
100
+ },
101
+ {
102
+ variant: "light",
103
+ color: "negative",
104
+ class: "bg-action-fill-negative-faded text-action-ink-negative-normal",
105
+ },
106
+ {
107
+ variant: "light",
108
+ color: "notice",
109
+ class: "bg-action-fill-notice-faded text-action-ink-notice-normal",
110
+ },
111
+ {
112
+ variant: "light",
113
+ color: "info",
114
+ class: "bg-action-fill-info-faded text-action-ink-info-normal",
115
+ },
116
+ {
117
+ variant: "light",
118
+ color: "neutral",
119
+ class: "bg-action-fill-neutral-faded text-action-ink-neutral-normal",
120
+ },
121
+ // Filled variant colors
122
+ {
123
+ variant: "filled",
124
+ color: "primary",
125
+ class: "bg-action-fill-primary-default text-action-ink-on-primary-normal",
126
+ },
127
+ {
128
+ variant: "filled",
129
+ color: "positive",
130
+ class: "bg-action-fill-positive-default text-action-ink-on-primary-normal",
131
+ },
132
+ {
133
+ variant: "filled",
134
+ color: "negative",
135
+ class: "bg-action-fill-negative-default text-action-ink-on-primary-normal",
136
+ },
137
+ {
138
+ variant: "filled",
139
+ color: "notice",
140
+ class: "bg-action-fill-notice-default text-action-ink-on-primary-normal",
141
+ },
142
+ {
143
+ variant: "filled",
144
+ color: "info",
145
+ class: "bg-action-fill-info-default text-action-ink-on-primary-normal",
146
+ },
147
+ {
148
+ variant: "filled",
149
+ color: "neutral",
150
+ class: "bg-action-fill-neutral-default text-action-ink-on-primary-normal",
151
+ },
152
+ ],
153
+ defaultVariants: {
154
+ variant: "light",
155
+ color: "info",
156
+ size: "medium",
157
+ },
158
+ });
159
+ const Badge = React__namespace.forwardRef(({ className, variant, size, color, showDot = false, children, ...props }, ref) => {
160
+ const getDotColor = () => {
161
+ if (variant === "filled") {
162
+ return "bg-action-ink-on-primary-normal";
163
+ }
164
+ // Light variant - use the corresponding action color
165
+ switch (color) {
166
+ case "primary":
167
+ return "bg-action-fill-primary-default";
168
+ case "positive":
169
+ return "bg-action-fill-positive-default";
170
+ case "negative":
171
+ return "bg-action-fill-negative-default";
172
+ case "notice":
173
+ return "bg-action-fill-notice-default";
174
+ case "info":
175
+ return "bg-action-fill-info-default";
176
+ case "neutral":
177
+ return "bg-action-fill-neutral-default";
178
+ default:
179
+ return "bg-action-fill-info-default";
180
+ }
181
+ };
182
+ const getDotSize = () => {
183
+ if (size === "small") {
184
+ return "h-2 w-2";
185
+ }
186
+ if (size === "medium") {
187
+ return "h-[6px] w-[6px]";
188
+ }
189
+ return "h-3 w-3";
190
+ };
191
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn(badgeVariants({ variant, size, color }), className), ...props, children: [showDot && (jsxRuntime.jsx("span", { className: cn("rounded-full", getDotColor(), getDotSize()), "aria-hidden": "true" })), children] }));
192
+ });
193
+ Badge.displayName = "Badge";
194
+
69
195
  const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-center whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none", {
70
196
  variants: {
71
197
  variant: {
@@ -513,7 +639,7 @@ function hasIcon(name) {
513
639
  return name in iconRegistry;
514
640
  }
515
641
 
516
- const checkboxVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 border transition-all cursor-pointer", {
642
+ const checkboxVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 transition-all cursor-pointer", {
517
643
  variants: {
518
644
  size: {
519
645
  small: "w-[14px] h-[14px] rounded-small border-[1.5px]",
@@ -550,7 +676,7 @@ const checkboxVariants = classVarianceAuthority.cva("relative inline-flex items-
550
676
  isChecked: true,
551
677
  validationState: "none",
552
678
  isDisabled: false,
553
- class: "bg-action-fill-primary-hover border-surface-outline-neutral-muted",
679
+ class: "bg-action-fill-primary-default hover:bg-action-fill-primary-hover hover:border-action-fill-primary-hover border-action-fill-primary-default",
554
680
  },
555
681
  // Checked or Indeterminate state - error validation
556
682
  {
@@ -586,6 +712,7 @@ const Checkbox = React__namespace.forwardRef(({ label, errorText, size = "medium
586
712
  const [internalChecked, setInternalChecked] = React__namespace.useState(false);
587
713
  const [showRipple, setShowRipple] = React__namespace.useState(false);
588
714
  const inputRef = React__namespace.useRef(null);
715
+ const rippleTimeoutRef = React__namespace.useRef(null);
589
716
  // Use forwarded ref or internal ref
590
717
  React__namespace.useImperativeHandle(ref, () => inputRef.current);
591
718
  const isChecked = checked !== undefined ? checked : internalChecked;
@@ -595,6 +722,14 @@ const Checkbox = React__namespace.forwardRef(({ label, errorText, size = "medium
595
722
  inputRef.current.indeterminate = isIndeterminate;
596
723
  }
597
724
  }, [isIndeterminate]);
725
+ // Cleanup timeout on unmount
726
+ React__namespace.useEffect(() => {
727
+ return () => {
728
+ if (rippleTimeoutRef.current) {
729
+ clearTimeout(rippleTimeoutRef.current);
730
+ }
731
+ };
732
+ }, []);
598
733
  const handleChange = (e) => {
599
734
  if (onChange) {
600
735
  onChange(e);
@@ -604,31 +739,28 @@ const Checkbox = React__namespace.forwardRef(({ label, errorText, size = "medium
604
739
  }
605
740
  };
606
741
  const triggerRipple = () => {
607
- if (!isDisabled) {
742
+ if (!isDisabled && !showRipple) {
743
+ // Clear any existing timeout
744
+ if (rippleTimeoutRef.current) {
745
+ clearTimeout(rippleTimeoutRef.current);
746
+ }
608
747
  setShowRipple(true);
609
- setTimeout(() => {
748
+ rippleTimeoutRef.current = setTimeout(() => {
610
749
  setShowRipple(false);
611
- }, 360); // Match animation duration (0.36s)
750
+ rippleTimeoutRef.current = null;
751
+ }, 400); // Match animation duration (0.4s)
612
752
  }
613
753
  };
614
754
  const handleContainerClick = () => {
615
755
  if (!isDisabled && inputRef.current) {
616
- // Only show ripple when checking (not unchecking)
617
- const willBeChecked = !isChecked && !isIndeterminate;
618
- if (willBeChecked) {
619
- triggerRipple();
620
- }
756
+ triggerRipple();
621
757
  inputRef.current.click();
622
758
  }
623
759
  };
624
760
  const handleKeyDown = (e) => {
625
761
  if ((e.key === " " || e.key === "Enter") && !isDisabled) {
626
762
  e.preventDefault();
627
- // Only show ripple when checking (not unchecking)
628
- const willBeChecked = !isChecked && !isIndeterminate;
629
- if (willBeChecked) {
630
- triggerRipple();
631
- }
763
+ triggerRipple();
632
764
  inputRef.current?.click();
633
765
  }
634
766
  };
@@ -669,6 +801,215 @@ const Checkbox = React__namespace.forwardRef(({ label, errorText, size = "medium
669
801
  });
670
802
  Checkbox.displayName = "Checkbox";
671
803
 
804
+ const counterVariants = classVarianceAuthority.cva("inline-flex items-center justify-center transition-colors", {
805
+ variants: {
806
+ size: {
807
+ small: "text-body-xsmall-medium rounded-small px-1 py-0.5 min-w-[20px] h-[16px]",
808
+ medium: "text-body-small-medium rounded-medium px-2 py-1 min-w-[24px] h-[20px]",
809
+ large: "text-body-medium-medium rounded-medium px-2 py-1 min-w-[28px] h-[24px]",
810
+ },
811
+ color: {
812
+ positive: "",
813
+ negative: "",
814
+ notice: "",
815
+ information: "",
816
+ neutral: "",
817
+ primary: "",
818
+ },
819
+ emphasis: {
820
+ subtle: "",
821
+ intense: "",
822
+ },
823
+ },
824
+ compoundVariants: [
825
+ // Positive - Subtle
826
+ {
827
+ color: "positive",
828
+ emphasis: "subtle",
829
+ class: "bg-feedback-fill-positive-subtle text-feedback-ink-positive-intense",
830
+ },
831
+ // Positive - Intense
832
+ {
833
+ color: "positive",
834
+ emphasis: "intense",
835
+ class: "bg-feedback-fill-positive-intense text-action-ink-on-primary-normal",
836
+ },
837
+ // Negative - Subtle
838
+ {
839
+ color: "negative",
840
+ emphasis: "subtle",
841
+ class: "bg-feedback-fill-negative-subtle text-feedback-ink-negative-subtle",
842
+ },
843
+ // Negative - Intense
844
+ {
845
+ color: "negative",
846
+ emphasis: "intense",
847
+ class: "bg-feedback-fill-negative-intense text-action-ink-on-primary-normal",
848
+ },
849
+ // Notice - Subtle
850
+ {
851
+ color: "notice",
852
+ emphasis: "subtle",
853
+ class: "bg-feedback-fill-notice-subtle text-feedback-ink-notice-subtle",
854
+ },
855
+ // Notice - Intense
856
+ {
857
+ color: "notice",
858
+ emphasis: "intense",
859
+ class: "bg-feedback-fill-notice-intense text-action-ink-on-primary-normal",
860
+ },
861
+ // Information - Subtle
862
+ {
863
+ color: "information",
864
+ emphasis: "subtle",
865
+ class: "bg-feedback-fill-info-subtle text-feedback-ink-info-subtle",
866
+ },
867
+ // Information - Intense
868
+ {
869
+ color: "information",
870
+ emphasis: "intense",
871
+ class: "bg-feedback-fill-info-intense text-action-ink-on-primary-normal",
872
+ },
873
+ // Neutral - Subtle
874
+ {
875
+ color: "neutral",
876
+ emphasis: "subtle",
877
+ class: "bg-surface-fill-neutral-subtle text-surface-ink-neutral-normal",
878
+ },
879
+ // Neutral - Intense
880
+ {
881
+ color: "neutral",
882
+ emphasis: "intense",
883
+ class: "bg-feedback-fill-neutral-intense text-action-ink-on-primary-normal",
884
+ },
885
+ // Primary - Subtle
886
+ {
887
+ color: "primary",
888
+ emphasis: "subtle",
889
+ class: "bg-surface-fill-primary-moderate text-surface-ink-primary-normal",
890
+ },
891
+ // Primary - Intense
892
+ {
893
+ color: "primary",
894
+ emphasis: "intense",
895
+ class: "bg-surface-fill-primary-intense text-action-ink-on-primary-normal",
896
+ },
897
+ ],
898
+ defaultVariants: {
899
+ size: "medium",
900
+ color: "neutral",
901
+ emphasis: "subtle",
902
+ },
903
+ });
904
+ const Counter = React__namespace.forwardRef(({ value, max, size = "medium", color = "neutral", emphasis = "subtle", className, ...props }, ref) => {
905
+ // Handle max value logic
906
+ const displayValue = React__namespace.useMemo(() => {
907
+ if (max !== undefined && typeof value === "number" && value > max) {
908
+ return `${max}+`;
909
+ }
910
+ return value;
911
+ }, [value, max]);
912
+ return (jsxRuntime.jsx("span", { ref: ref, className: cn(counterVariants({
913
+ size,
914
+ color,
915
+ emphasis,
916
+ }), className), ...props, children: displayValue }));
917
+ });
918
+ Counter.displayName = "Counter";
919
+
920
+ const dividerVariants = classVarianceAuthority.cva("", {
921
+ variants: {
922
+ orientation: {
923
+ horizontal: "w-full",
924
+ vertical: "h-full",
925
+ },
926
+ thickness: {
927
+ thinner: "",
928
+ thin: "",
929
+ thick: "",
930
+ thicker: "",
931
+ },
932
+ lineStyle: {
933
+ solid: "border-solid",
934
+ dashed: "border-dashed",
935
+ },
936
+ variant: {
937
+ normal: "",
938
+ subtle: "",
939
+ muted: "",
940
+ },
941
+ },
942
+ compoundVariants: [
943
+ // Horizontal orientation with thickness
944
+ {
945
+ orientation: "horizontal",
946
+ thickness: "thinner",
947
+ class: "border-t-[0.5px]",
948
+ },
949
+ {
950
+ orientation: "horizontal",
951
+ thickness: "thin",
952
+ class: "border-t-[1px]",
953
+ },
954
+ {
955
+ orientation: "horizontal",
956
+ thickness: "thick",
957
+ class: "border-t-[2px]",
958
+ },
959
+ {
960
+ orientation: "horizontal",
961
+ thickness: "thicker",
962
+ class: "border-t-[3px]",
963
+ },
964
+ // Vertical orientation with thickness
965
+ {
966
+ orientation: "vertical",
967
+ thickness: "thinner",
968
+ class: "border-l-[0.5px]",
969
+ },
970
+ {
971
+ orientation: "vertical",
972
+ thickness: "thin",
973
+ class: "border-l-[1px]",
974
+ },
975
+ {
976
+ orientation: "vertical",
977
+ thickness: "thick",
978
+ class: "border-l-[2px]",
979
+ },
980
+ {
981
+ orientation: "vertical",
982
+ thickness: "thicker",
983
+ class: "border-l-[3px]",
984
+ },
985
+ // Normal variant colors
986
+ {
987
+ variant: "normal",
988
+ class: "border-surface-outline-neutral-normal",
989
+ },
990
+ // Subtle variant colors
991
+ {
992
+ variant: "subtle",
993
+ class: "border-surface-outline-neutral-subtle",
994
+ },
995
+ // Muted variant colors
996
+ {
997
+ variant: "muted",
998
+ class: "border-surface-outline-neutral-muted",
999
+ },
1000
+ ],
1001
+ defaultVariants: {
1002
+ orientation: "horizontal",
1003
+ thickness: "thin",
1004
+ lineStyle: "solid",
1005
+ variant: "normal",
1006
+ },
1007
+ });
1008
+ const Divider = React__namespace.forwardRef(({ className, orientation = "horizontal", thickness = "thin", lineStyle = "solid", variant = "normal", ...props }, ref) => {
1009
+ return (jsxRuntime.jsx("div", { ref: ref, role: "separator", "aria-orientation": orientation, className: cn(dividerVariants({ orientation, thickness, lineStyle, variant }), className), ...props }));
1010
+ });
1011
+ Divider.displayName = "Divider";
1012
+
672
1013
  const tooltipVariants = classVarianceAuthority.cva("fixed z-50 bg-popup-fill-intense text-action-ink-on-primary-normal rounded-medium border border-popup-outline-subtle flex flex-col p-4 rounded-xlarge min-w-[200px] max-w-[300px] transition-opacity duration-200", {
673
1014
  variants: {
674
1015
  isVisible: {
@@ -923,6 +1264,389 @@ const FormHeader = React__namespace.forwardRef(({ label, size = "medium", isOpti
923
1264
  });
924
1265
  FormHeader.displayName = "FormHeader";
925
1266
 
1267
+ const listItemVariants = classVarianceAuthority.cva("flex items-start gap-3 p-3 rounded-medium transition-colors cursor-pointer", {
1268
+ variants: {
1269
+ variant: {
1270
+ default: `hover:bg-action-fill-neutral-faded
1271
+ focus:bg-action-fill-neutral-faded
1272
+ focus:ring-2
1273
+ ring-action-outline-primary-faded-hover
1274
+ border border-transparent
1275
+ `,
1276
+ bordered: "border border-action-outline-primary-faded hover:bg-surface-fill-primary-subtle",
1277
+ primary: `hover:bg-action-fill-neutral-faded
1278
+ focus:bg-action-fill-neutral-faded
1279
+ focus:ring-2
1280
+ ring-action-outline-primary-faded-hover
1281
+ border border-transparent
1282
+ `,
1283
+ negative: `hover:bg-action-fill-negative-faded
1284
+ focus:bg-action-fill-negative-faded
1285
+ focus:ring-2 ring-action-outline-negative-faded-hover
1286
+ border border-transparent
1287
+ `,
1288
+ },
1289
+ isDisabled: {
1290
+ true: "cursor-not-allowed opacity-60",
1291
+ false: "",
1292
+ },
1293
+ isSelected: {
1294
+ true: "bg-action-fill-primary-faded border-action-outline-primary-faded",
1295
+ false: "",
1296
+ },
1297
+ },
1298
+ defaultVariants: {
1299
+ variant: "default",
1300
+ isDisabled: false,
1301
+ isSelected: false,
1302
+ },
1303
+ });
1304
+ const ChevronRightIcon = ({ className }) => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsxRuntime.jsx("path", { d: "M7.5 15L12.5 10L7.5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
1305
+ const ListItem = React__namespace.forwardRef(({ className, type = "single", leadingIcon, title, description, trailingIcon, showChevron = true, variant = "default", isDisabled = false, isSelected = false, onSelectionChange, checkboxSize = "small", containerClassName, contentClassName, onClick, ...props }, ref) => {
1306
+ const [internalSelected, setInternalSelected] = React__namespace.useState(isSelected);
1307
+ // Sync internal state with prop
1308
+ React__namespace.useEffect(() => {
1309
+ setInternalSelected(isSelected);
1310
+ }, [isSelected]);
1311
+ const handleClick = (e) => {
1312
+ if (isDisabled)
1313
+ return;
1314
+ if (type === "multiple") {
1315
+ const newSelected = !internalSelected;
1316
+ setInternalSelected(newSelected);
1317
+ onSelectionChange?.(newSelected);
1318
+ }
1319
+ onClick?.(e);
1320
+ };
1321
+ const handleCheckboxChange = (e) => {
1322
+ e.stopPropagation();
1323
+ if (isDisabled)
1324
+ return;
1325
+ const newSelected = e.target.checked;
1326
+ setInternalSelected(newSelected);
1327
+ onSelectionChange?.(newSelected);
1328
+ };
1329
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn(listItemVariants({
1330
+ variant,
1331
+ isDisabled,
1332
+ isSelected: type === "multiple" ? internalSelected : false,
1333
+ }), containerClassName), onClick: handleClick, role: type === "multiple" ? "checkbox" : "button", "aria-checked": type === "multiple" ? internalSelected : undefined, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, ...props, children: [type === "multiple" && (jsxRuntime.jsx(Checkbox, { checked: internalSelected, onChange: handleCheckboxChange, isDisabled: isDisabled, size: checkboxSize, className: "shrink-0 mt-0.5" })), leadingIcon && (jsxRuntime.jsx("div", { className: cn(`shrink-0 flex items-center justify-center mt-0.5`, variant === "primary"
1334
+ ? "text-action-ink-primary-normal"
1335
+ : variant === "negative"
1336
+ ? "text-action-ink-negative-normal"
1337
+ : "text-action-ink-neutral-subtle", isDisabled && "text-surface-ink-neutral-disabled"), children: leadingIcon })), jsxRuntime.jsxs("div", { className: cn("flex-1 min-w-0 flex flex-col justify-center", contentClassName), children: [jsxRuntime.jsx("div", { className: cn("text-body-medium-regular truncate", variant === "primary"
1338
+ ? "text-action-ink-primary-normal"
1339
+ : variant === "negative"
1340
+ ? "text-action-ink-negative-normal"
1341
+ : "text-action-ink-neutral-normal", isDisabled && "text-surface-ink-neutral-disabled"), children: title }), description && (jsxRuntime.jsx("div", { className: cn("text-body-small-regular text-surface-ink-neutral-muted mt-0.5 line-clamp-2", isDisabled && "text-surface-ink-neutral-disabled"), children: description }))] }), (trailingIcon || showChevron) && (jsxRuntime.jsx("div", { className: "shrink-0 self-center text-action-ink-neutral-subtle", children: trailingIcon || jsxRuntime.jsx(ChevronRightIcon, {}) }))] }));
1342
+ });
1343
+ ListItem.displayName = "ListItem";
1344
+
1345
+ const radioVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 border transition-all cursor-pointer rounded-full", {
1346
+ variants: {
1347
+ size: {
1348
+ small: "w-[14px] h-[14px] border-[1.5px]",
1349
+ medium: "w-[16px] h-[16px] border-[1.5px]",
1350
+ large: "w-[20px] h-[20px] border-[2px]",
1351
+ },
1352
+ validationState: {
1353
+ none: "",
1354
+ error: "border-action-outline-negative-default hover:border-action-outline-negative-hover",
1355
+ },
1356
+ isChecked: {
1357
+ true: "",
1358
+ false: "",
1359
+ },
1360
+ isDisabled: {
1361
+ true: "cursor-not-allowed opacity-60 border-action-outline-neutral-disabled bg-surface-fill-neutral-subtle",
1362
+ false: "",
1363
+ },
1364
+ isFocused: {
1365
+ true: "",
1366
+ false: "",
1367
+ },
1368
+ },
1369
+ compoundVariants: [
1370
+ // Unchecked state - none validation
1371
+ {
1372
+ isChecked: false,
1373
+ validationState: "none",
1374
+ isDisabled: false,
1375
+ class: `border-action-outline-neutral-faded
1376
+ hover:bg-action-fill-neutral-faded
1377
+ hover:border-action-outline-neutral-faded
1378
+ `,
1379
+ },
1380
+ // Checked state - none validation
1381
+ {
1382
+ isChecked: true,
1383
+ validationState: "none",
1384
+ isDisabled: false,
1385
+ class: "bg-action-fill-primary-default hover:bg-action-fill-primary-hover border-action-fill-primary-default hover:border-action-fill-primary-hover",
1386
+ },
1387
+ // Checked state - error validation
1388
+ {
1389
+ isChecked: true,
1390
+ validationState: "error",
1391
+ isDisabled: false,
1392
+ class: "bg-action-fill-negative-default hover:bg-action-fill-negative-hover border-action-fill-negative-default hover:border-action-fill-negative-hover",
1393
+ },
1394
+ // Focused state - none validation
1395
+ {
1396
+ isFocused: true,
1397
+ validationState: "none",
1398
+ isDisabled: false,
1399
+ class: "ring-2 ring-action-outline-primary-faded",
1400
+ },
1401
+ // Focused state - error validation
1402
+ {
1403
+ isFocused: true,
1404
+ validationState: "error",
1405
+ isDisabled: false,
1406
+ class: "ring-2 ring-action-outline-negative-faded",
1407
+ },
1408
+ ],
1409
+ defaultVariants: {
1410
+ size: "medium",
1411
+ validationState: "none",
1412
+ isChecked: false,
1413
+ isDisabled: false,
1414
+ isFocused: false,
1415
+ },
1416
+ });
1417
+ const Radio = React__namespace.forwardRef(({ label, errorText, size = "medium", validationState = "none", isDisabled = false, showErrorText = true, containerClassName, labelClassName, className, checked, onChange, ...props }, ref) => {
1418
+ const [internalChecked, setInternalChecked] = React__namespace.useState(false);
1419
+ const [showRipple, setShowRipple] = React__namespace.useState(false);
1420
+ const [isFocused, setIsFocused] = React__namespace.useState(false);
1421
+ const inputRef = React__namespace.useRef(null);
1422
+ // Use forwarded ref or internal ref
1423
+ React__namespace.useImperativeHandle(ref, () => inputRef.current);
1424
+ const isChecked = checked !== undefined ? checked : internalChecked;
1425
+ const handleChange = (e) => {
1426
+ if (onChange) {
1427
+ onChange(e);
1428
+ }
1429
+ else {
1430
+ setInternalChecked(e.target.checked);
1431
+ }
1432
+ };
1433
+ const triggerRipple = () => {
1434
+ if (!isDisabled) {
1435
+ setShowRipple(true);
1436
+ setTimeout(() => {
1437
+ setShowRipple(false);
1438
+ }, 360); // Match animation duration (0.36s)
1439
+ }
1440
+ };
1441
+ const handleContainerClick = () => {
1442
+ if (!isDisabled && inputRef.current) {
1443
+ // Only show ripple when checking (not unchecking)
1444
+ const willBeChecked = !isChecked;
1445
+ if (willBeChecked) {
1446
+ triggerRipple();
1447
+ }
1448
+ inputRef.current.click();
1449
+ }
1450
+ };
1451
+ const handleKeyDown = (e) => {
1452
+ if ((e.key === " " || e.key === "Enter") && !isDisabled) {
1453
+ e.preventDefault();
1454
+ // Only show ripple when checking (not unchecking)
1455
+ const willBeChecked = !isChecked;
1456
+ if (willBeChecked) {
1457
+ triggerRipple();
1458
+ }
1459
+ inputRef.current?.click();
1460
+ }
1461
+ };
1462
+ const handleFocus = () => {
1463
+ if (!isDisabled) {
1464
+ setIsFocused(true);
1465
+ }
1466
+ };
1467
+ const handleBlur = () => {
1468
+ setIsFocused(false);
1469
+ };
1470
+ // Size-based configurations
1471
+ const sizeConfig = {
1472
+ small: {
1473
+ gap: "gap-2",
1474
+ labelSize: "text-body-small-regular",
1475
+ innerCircleSize: 6,
1476
+ },
1477
+ medium: {
1478
+ gap: "gap-2.5",
1479
+ labelSize: "text-body-medium-regular",
1480
+ innerCircleSize: 7,
1481
+ },
1482
+ large: {
1483
+ gap: "gap-3",
1484
+ labelSize: "text-body-large-regular",
1485
+ innerCircleSize: 8,
1486
+ },
1487
+ };
1488
+ const config = sizeConfig[size];
1489
+ // Determine if we should show the error text
1490
+ const shouldShowError = errorText && showErrorText;
1491
+ return (jsxRuntime.jsxs("div", { className: cn("inline-flex flex-col", containerClassName), children: [jsxRuntime.jsxs("div", { className: cn("inline-flex items-center", config.gap, isDisabled ? "cursor-not-allowed" : "cursor-pointer"), onClick: handleContainerClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, role: "radio", "aria-checked": isChecked, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "radio", className: "sr-only", checked: isChecked, onChange: handleChange, disabled: isDisabled, ...props }), jsxRuntime.jsxs("div", { className: "relative inline-flex shrink-0", children: [showRipple && (jsxRuntime.jsx("div", { className: cn("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full pointer-events-none w-full h-full", validationState === "error"
1492
+ ? "bg-action-outline-negative-faded"
1493
+ : "bg-action-outline-primary-faded"), style: {
1494
+ animation: "var(--animate-checkbox-ripple)",
1495
+ } })), jsxRuntime.jsx("div", { className: cn(radioVariants({
1496
+ size,
1497
+ validationState,
1498
+ isChecked,
1499
+ isDisabled,
1500
+ isFocused,
1501
+ }), className), children: isChecked && (jsxRuntime.jsx("div", { className: "rounded-full bg-white transition-all", style: {
1502
+ width: `${config.innerCircleSize}px`,
1503
+ height: `${config.innerCircleSize}px`,
1504
+ } })) })] }), label && (jsxRuntime.jsx("label", { className: cn(config.labelSize, "select-none inline-flex items-center", isDisabled
1505
+ ? "text-surface-ink-neutral-disabled"
1506
+ : "text-surface-ink-neutral-normal", labelClassName), children: label }))] }), shouldShowError && (jsxRuntime.jsx(FormFooter, { helperText: errorText, validationState: "negative", size: size, isDisabled: isDisabled }))] }));
1507
+ });
1508
+ Radio.displayName = "Radio";
1509
+
1510
+ const switchVariants = classVarianceAuthority.cva("relative inline-flex items-center shrink-0 cursor-pointer rounded-full transition-all duration-200", {
1511
+ variants: {
1512
+ size: {
1513
+ small: "w-[20px] h-[12px]",
1514
+ medium: "w-[28px] h-[16px]",
1515
+ large: "w-[36px] h-[20px]",
1516
+ },
1517
+ isChecked: {
1518
+ true: "bg-action-fill-primary-default ",
1519
+ false: "bg-surface-fill-neutral-subtle",
1520
+ },
1521
+ isDisabled: {
1522
+ true: "cursor-not-allowed opacity-60",
1523
+ false: "",
1524
+ },
1525
+ },
1526
+ compoundVariants: [
1527
+ {
1528
+ isChecked: true,
1529
+ isDisabled: false,
1530
+ class: "hover:bg-action-fill-primary-hover ",
1531
+ },
1532
+ {
1533
+ isChecked: false,
1534
+ isDisabled: false,
1535
+ class: "hover:bg-action-fill-neutral-faded",
1536
+ },
1537
+ ],
1538
+ defaultVariants: {
1539
+ size: "medium",
1540
+ isChecked: false,
1541
+ isDisabled: false,
1542
+ },
1543
+ });
1544
+ const switchThumbVariants = classVarianceAuthority.cva("inline-block rounded-full bg-neutral-00 shadow-sm transition-transform duration-200", {
1545
+ variants: {
1546
+ size: {
1547
+ small: "h-[8px] w-[8px]",
1548
+ medium: "h-[12px] w-[12px]",
1549
+ large: "h-[16px] w-[16px]",
1550
+ },
1551
+ isChecked: {
1552
+ true: "",
1553
+ false: "",
1554
+ },
1555
+ },
1556
+ compoundVariants: [
1557
+ // Small size translations
1558
+ {
1559
+ size: "small",
1560
+ isChecked: false,
1561
+ class: "translate-x-[2px]",
1562
+ },
1563
+ {
1564
+ size: "small",
1565
+ isChecked: true,
1566
+ class: "translate-x-[10px]",
1567
+ },
1568
+ // Medium size translations
1569
+ {
1570
+ size: "medium",
1571
+ isChecked: false,
1572
+ class: "translate-x-[2px]",
1573
+ },
1574
+ {
1575
+ size: "medium",
1576
+ isChecked: true,
1577
+ class: "translate-x-[14px]",
1578
+ },
1579
+ // Large size translations
1580
+ {
1581
+ size: "large",
1582
+ isChecked: false,
1583
+ class: "translate-x-[2px]",
1584
+ },
1585
+ {
1586
+ size: "large",
1587
+ isChecked: true,
1588
+ class: "translate-x-[18px]",
1589
+ },
1590
+ ],
1591
+ defaultVariants: {
1592
+ size: "medium",
1593
+ isChecked: false,
1594
+ },
1595
+ });
1596
+ const Switch = React__namespace.forwardRef(({ label, size = "medium", isDisabled = false, containerClassName, labelClassName, trackClassName, thumbClassName, className, checked, onChange, ...props }, ref) => {
1597
+ const [internalChecked, setInternalChecked] = React__namespace.useState(false);
1598
+ const inputRef = React__namespace.useRef(null);
1599
+ // Use forwarded ref or internal ref
1600
+ React__namespace.useImperativeHandle(ref, () => inputRef.current);
1601
+ const isChecked = checked !== undefined ? checked : internalChecked;
1602
+ const handleChange = (e) => {
1603
+ if (onChange) {
1604
+ onChange(e);
1605
+ }
1606
+ else {
1607
+ setInternalChecked(e.target.checked);
1608
+ }
1609
+ };
1610
+ const handleContainerClick = () => {
1611
+ if (!isDisabled && inputRef.current) {
1612
+ inputRef.current.click();
1613
+ }
1614
+ };
1615
+ const handleKeyDown = (e) => {
1616
+ if ((e.key === " " || e.key === "Enter") && !isDisabled) {
1617
+ e.preventDefault();
1618
+ inputRef.current?.click();
1619
+ }
1620
+ };
1621
+ // Size-based configurations
1622
+ const sizeConfig = {
1623
+ small: {
1624
+ gap: "gap-2",
1625
+ labelSize: "text-body-small-regular",
1626
+ },
1627
+ medium: {
1628
+ gap: "gap-2.5",
1629
+ labelSize: "text-body-medium-regular",
1630
+ },
1631
+ large: {
1632
+ gap: "gap-3",
1633
+ labelSize: "text-body-large-regular",
1634
+ },
1635
+ };
1636
+ const config = sizeConfig[size];
1637
+ return (jsxRuntime.jsx("div", { className: cn("inline-flex flex-col", containerClassName), children: jsxRuntime.jsxs("div", { className: cn("inline-flex items-center", config.gap, isDisabled ? "cursor-not-allowed" : "cursor-pointer"), onClick: handleContainerClick, onKeyDown: handleKeyDown, role: "switch", "aria-checked": isChecked, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "checkbox", role: "switch", className: "sr-only", checked: isChecked, onChange: handleChange, disabled: isDisabled, ...props }), jsxRuntime.jsx("div", { className: "relative inline-flex shrink-0", children: jsxRuntime.jsx("div", { className: cn(switchVariants({
1638
+ size,
1639
+ isChecked,
1640
+ isDisabled,
1641
+ }), trackClassName, className, "focus-visible:ring-2 focus-visible:ring-action-outline-primary-faded focus-visible:ring-offset-2"), children: jsxRuntime.jsx("span", { className: cn(switchThumbVariants({
1642
+ size,
1643
+ isChecked,
1644
+ }), thumbClassName) }) }) }), label && (jsxRuntime.jsx("label", { className: cn(config.labelSize, "select-none inline-flex items-center", isDisabled
1645
+ ? "text-surface-ink-neutral-disabled"
1646
+ : "text-surface-ink-neutral-normal", labelClassName), children: label }))] }) }));
1647
+ });
1648
+ Switch.displayName = "Switch";
1649
+
926
1650
  const textAreaVariants = classVarianceAuthority.cva("relative flex flex-col border rounded-medium transition-all font-display font-size-100 leading-100", {
927
1651
  variants: {
928
1652
  size: {
@@ -932,19 +1656,17 @@ const textAreaVariants = classVarianceAuthority.cva("relative flex flex-col bord
932
1656
  },
933
1657
  validationState: {
934
1658
  none: `
935
- border-action-outline-neutral-default
1659
+ border-action-outline-neutral-faded
936
1660
  hover:border-action-outline-primary-hover
937
1661
  focus-within:border-action-outline-primary-hover
938
1662
  focus-within:ring-2
939
1663
  ring-action-outline-primary-faded-hover`,
940
1664
  positive: `
941
1665
  border-action-outline-positive-default
942
- hover:border-action-outline-positive-hover
943
1666
  focus-within:border-action-outline-positive-hover
944
1667
  focus-within:ring-2
945
1668
  ring-action-outline-positive-faded-hover`,
946
1669
  negative: `border-action-outline-negative-default
947
- hover:border-action-outline-negative-hover
948
1670
  focus-within:border-action-outline-negative-hover
949
1671
  focus-within:ring-2
950
1672
  ring-action-outline-negative-faded-hover`,
@@ -991,7 +1713,18 @@ const TextArea = React__namespace.forwardRef(({ label, helperText, errorText, su
991
1713
  // Check if we're approaching or at the limit
992
1714
  const isNearLimit = maxChar && currentLength >= maxChar * 0.9;
993
1715
  const isAtLimit = maxChar && currentLength >= maxChar;
994
- return (jsxRuntime.jsxs("div", { className: cn("w-full flex flex-col gap-3", containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { className: cn(textAreaVariants({
1716
+ const sizeConfig = {
1717
+ small: {
1718
+ gap: "gap-2",
1719
+ },
1720
+ medium: {
1721
+ gap: "gap-2",
1722
+ },
1723
+ large: {
1724
+ gap: "gap-3",
1725
+ },
1726
+ };
1727
+ return (jsxRuntime.jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { className: cn(textAreaVariants({
995
1728
  size,
996
1729
  validationState: currentValidationState,
997
1730
  isDisabled,
@@ -1109,21 +1842,32 @@ const TextField = React__namespace.forwardRef(({ label, helperText, errorText, s
1109
1842
  });
1110
1843
  TextField.displayName = "TextField";
1111
1844
 
1845
+ exports.Badge = Badge;
1112
1846
  exports.Button = Button;
1113
1847
  exports.Checkbox = Checkbox;
1848
+ exports.Counter = Counter;
1849
+ exports.Divider = Divider;
1114
1850
  exports.FormFooter = FormFooter;
1115
1851
  exports.FormHeader = FormHeader;
1116
1852
  exports.Icon = Icon;
1853
+ exports.ListItem = ListItem;
1854
+ exports.Radio = Radio;
1855
+ exports.Switch = Switch;
1117
1856
  exports.Text = Text;
1118
1857
  exports.TextArea = TextArea;
1119
1858
  exports.TextField = TextField;
1120
1859
  exports.Tooltip = Tooltip;
1860
+ exports.badgeVariants = badgeVariants;
1121
1861
  exports.buttonVariants = buttonVariants;
1122
1862
  exports.checkboxVariants = checkboxVariants;
1123
1863
  exports.cn = cn;
1864
+ exports.counterVariants = counterVariants;
1124
1865
  exports.getAvailableIcons = getAvailableIcons;
1125
1866
  exports.hasIcon = hasIcon;
1126
1867
  exports.iconRegistry = iconRegistry;
1868
+ exports.listItemVariants = listItemVariants;
1869
+ exports.radioVariants = radioVariants;
1870
+ exports.switchVariants = switchVariants;
1127
1871
  exports.textAreaVariants = textAreaVariants;
1128
1872
  exports.textFieldVariants = textFieldVariants;
1129
1873
  exports.tooltipVariants = tooltipVariants;