@fanvue/ui 0.1.0-alpha.3 → 1.0.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.
Files changed (221) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/Alert/Alert.cjs +72 -0
  3. package/dist/cjs/components/Alert/Alert.cjs.map +1 -0
  4. package/dist/cjs/components/Avatar/Avatar.cjs +162 -0
  5. package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -0
  6. package/dist/cjs/components/Badge/Badge.cjs +99 -0
  7. package/dist/cjs/components/Badge/Badge.cjs.map +1 -0
  8. package/dist/cjs/components/Button/Button.cjs +172 -0
  9. package/dist/cjs/components/Button/Button.cjs.map +1 -0
  10. package/dist/cjs/components/Checkbox/Checkbox.cjs +157 -0
  11. package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -0
  12. package/dist/cjs/components/Chip/Chip.cjs +92 -0
  13. package/dist/cjs/components/Chip/Chip.cjs.map +1 -0
  14. package/dist/cjs/components/Count/Count.cjs +56 -0
  15. package/dist/cjs/components/Count/Count.cjs.map +1 -0
  16. package/dist/cjs/components/DatePicker/DatePicker.cjs +133 -0
  17. package/dist/cjs/components/DatePicker/DatePicker.cjs.map +1 -0
  18. package/dist/cjs/components/Divider/Divider.cjs +69 -0
  19. package/dist/cjs/components/Divider/Divider.cjs.map +1 -0
  20. package/dist/cjs/components/IconButton/IconButton.cjs +92 -0
  21. package/dist/cjs/components/IconButton/IconButton.cjs.map +1 -0
  22. package/dist/cjs/components/Icons/ArrowRightIcon.cjs +47 -0
  23. package/dist/cjs/components/Icons/ArrowRightIcon.cjs.map +1 -0
  24. package/dist/cjs/components/Icons/ArrowUpRightIcon.cjs +47 -0
  25. package/dist/cjs/components/Icons/ArrowUpRightIcon.cjs.map +1 -0
  26. package/dist/cjs/components/Icons/CheckCircleIcon.cjs +47 -0
  27. package/dist/cjs/components/Icons/CheckCircleIcon.cjs.map +1 -0
  28. package/dist/cjs/components/Icons/CheckIcon.cjs +49 -0
  29. package/dist/cjs/components/Icons/CheckIcon.cjs.map +1 -0
  30. package/dist/cjs/components/Icons/ChevronLeftIcon.cjs +49 -0
  31. package/dist/cjs/components/Icons/ChevronLeftIcon.cjs.map +1 -0
  32. package/dist/cjs/components/Icons/ChevronRightIcon.cjs +49 -0
  33. package/dist/cjs/components/Icons/ChevronRightIcon.cjs.map +1 -0
  34. package/dist/cjs/components/Icons/CloseIcon.cjs +46 -0
  35. package/dist/cjs/components/Icons/CloseIcon.cjs.map +1 -0
  36. package/dist/cjs/components/Icons/CrossIcon.cjs +40 -0
  37. package/dist/cjs/components/Icons/CrossIcon.cjs.map +1 -0
  38. package/dist/cjs/components/Icons/CrownIcon.cjs +40 -0
  39. package/dist/cjs/components/Icons/CrownIcon.cjs.map +1 -0
  40. package/dist/cjs/components/Icons/ErrorCircleIcon.cjs +47 -0
  41. package/dist/cjs/components/Icons/ErrorCircleIcon.cjs.map +1 -0
  42. package/dist/cjs/components/Icons/ErrorIcon.cjs +30 -0
  43. package/dist/cjs/components/Icons/ErrorIcon.cjs.map +1 -0
  44. package/dist/cjs/components/Icons/FireIcon.cjs +47 -0
  45. package/dist/cjs/components/Icons/FireIcon.cjs.map +1 -0
  46. package/dist/cjs/components/Icons/HomeIcon.cjs +40 -0
  47. package/dist/cjs/components/Icons/HomeIcon.cjs.map +1 -0
  48. package/dist/cjs/components/Icons/InfoCircleIcon.cjs +47 -0
  49. package/dist/cjs/components/Icons/InfoCircleIcon.cjs.map +1 -0
  50. package/dist/cjs/components/Icons/InfoIcon.cjs +30 -0
  51. package/dist/cjs/components/Icons/InfoIcon.cjs.map +1 -0
  52. package/dist/cjs/components/Icons/MicrophoneIcon.cjs +31 -0
  53. package/dist/cjs/components/Icons/MicrophoneIcon.cjs.map +1 -0
  54. package/dist/cjs/components/Icons/MinusIcon.cjs +40 -0
  55. package/dist/cjs/components/Icons/MinusIcon.cjs.map +1 -0
  56. package/dist/cjs/components/Icons/PlusIcon.cjs +40 -0
  57. package/dist/cjs/components/Icons/PlusIcon.cjs.map +1 -0
  58. package/dist/cjs/components/Icons/SpinnerIcon.cjs +43 -0
  59. package/dist/cjs/components/Icons/SpinnerIcon.cjs.map +1 -0
  60. package/dist/cjs/components/Icons/StopIcon.cjs +22 -0
  61. package/dist/cjs/components/Icons/StopIcon.cjs.map +1 -0
  62. package/dist/cjs/components/Icons/SuccessIcon.cjs +30 -0
  63. package/dist/cjs/components/Icons/SuccessIcon.cjs.map +1 -0
  64. package/dist/cjs/components/Icons/VipBadgeIcon.cjs +97 -0
  65. package/dist/cjs/components/Icons/VipBadgeIcon.cjs.map +1 -0
  66. package/dist/cjs/components/Icons/WarningIcon.cjs +30 -0
  67. package/dist/cjs/components/Icons/WarningIcon.cjs.map +1 -0
  68. package/dist/cjs/components/Icons/WarningTriangleIcon.cjs +47 -0
  69. package/dist/cjs/components/Icons/WarningTriangleIcon.cjs.map +1 -0
  70. package/dist/cjs/components/Logo/Logo.cjs +182 -0
  71. package/dist/cjs/components/Logo/Logo.cjs.map +1 -0
  72. package/dist/cjs/components/Pagination/Pagination.cjs +144 -0
  73. package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -0
  74. package/dist/cjs/components/Pill/Pill.cjs +69 -0
  75. package/dist/cjs/components/Pill/Pill.cjs.map +1 -0
  76. package/dist/cjs/components/ProgressBar/ProgressBar.cjs +112 -0
  77. package/dist/cjs/components/ProgressBar/ProgressBar.cjs.map +1 -0
  78. package/dist/cjs/components/Radio/Radio.cjs +74 -0
  79. package/dist/cjs/components/Radio/Radio.cjs.map +1 -0
  80. package/dist/cjs/components/RadioGroup/RadioGroup.cjs +30 -0
  81. package/dist/cjs/components/RadioGroup/RadioGroup.cjs.map +1 -0
  82. package/dist/cjs/components/Slider/Slider.cjs +96 -0
  83. package/dist/cjs/components/Slider/Slider.cjs.map +1 -0
  84. package/dist/cjs/components/Slider/SliderLayout.cjs +31 -0
  85. package/dist/cjs/components/Slider/SliderLayout.cjs.map +1 -0
  86. package/dist/cjs/components/Slider/SliderThumb.cjs +87 -0
  87. package/dist/cjs/components/Slider/SliderThumb.cjs.map +1 -0
  88. package/dist/cjs/components/Snackbar/Snackbar.cjs +215 -0
  89. package/dist/cjs/components/Snackbar/Snackbar.cjs.map +1 -0
  90. package/dist/cjs/components/Switch/Switch.cjs +57 -0
  91. package/dist/cjs/components/Switch/Switch.cjs.map +1 -0
  92. package/dist/cjs/components/SwitchField/SwitchField.cjs +103 -0
  93. package/dist/cjs/components/SwitchField/SwitchField.cjs.map +1 -0
  94. package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs +110 -0
  95. package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs.map +1 -0
  96. package/dist/cjs/components/Tabs/Tabs.cjs +24 -0
  97. package/dist/cjs/components/Tabs/Tabs.cjs.map +1 -0
  98. package/dist/cjs/components/Tabs/TabsContent.cjs +36 -0
  99. package/dist/cjs/components/Tabs/TabsContent.cjs.map +1 -0
  100. package/dist/cjs/components/Tabs/TabsList.cjs +42 -0
  101. package/dist/cjs/components/Tabs/TabsList.cjs.map +1 -0
  102. package/dist/cjs/components/Tabs/TabsTrigger.cjs +50 -0
  103. package/dist/cjs/components/Tabs/TabsTrigger.cjs.map +1 -0
  104. package/dist/cjs/components/Toast/Toast.cjs +128 -0
  105. package/dist/cjs/components/Toast/Toast.cjs.map +1 -0
  106. package/dist/cjs/index.cjs +111 -0
  107. package/dist/cjs/index.cjs.map +1 -0
  108. package/dist/cjs/utils/cn.cjs +10 -0
  109. package/dist/cjs/utils/cn.cjs.map +1 -0
  110. package/dist/components/Alert/Alert.mjs +55 -0
  111. package/dist/components/Alert/Alert.mjs.map +1 -0
  112. package/dist/components/Avatar/Avatar.mjs +144 -0
  113. package/dist/components/Avatar/Avatar.mjs.map +1 -0
  114. package/dist/components/Badge/Badge.mjs +82 -0
  115. package/dist/components/Badge/Badge.mjs.map +1 -0
  116. package/dist/components/Button/Button.mjs +155 -0
  117. package/dist/components/Button/Button.mjs.map +1 -0
  118. package/dist/components/Checkbox/Checkbox.mjs +139 -0
  119. package/dist/components/Checkbox/Checkbox.mjs.map +1 -0
  120. package/dist/components/Chip/Chip.mjs +75 -0
  121. package/dist/components/Chip/Chip.mjs.map +1 -0
  122. package/dist/components/Count/Count.mjs +39 -0
  123. package/dist/components/Count/Count.mjs.map +1 -0
  124. package/dist/components/DatePicker/DatePicker.mjs +133 -0
  125. package/dist/components/DatePicker/DatePicker.mjs.map +1 -0
  126. package/dist/components/Divider/Divider.mjs +51 -0
  127. package/dist/components/Divider/Divider.mjs.map +1 -0
  128. package/dist/components/IconButton/IconButton.mjs +75 -0
  129. package/dist/components/IconButton/IconButton.mjs.map +1 -0
  130. package/dist/components/Icons/ArrowRightIcon.mjs +30 -0
  131. package/dist/components/Icons/ArrowRightIcon.mjs.map +1 -0
  132. package/dist/components/Icons/ArrowUpRightIcon.mjs +30 -0
  133. package/dist/components/Icons/ArrowUpRightIcon.mjs.map +1 -0
  134. package/dist/components/Icons/CheckCircleIcon.mjs +30 -0
  135. package/dist/components/Icons/CheckCircleIcon.mjs.map +1 -0
  136. package/dist/components/Icons/CheckIcon.mjs +32 -0
  137. package/dist/components/Icons/CheckIcon.mjs.map +1 -0
  138. package/dist/components/Icons/ChevronLeftIcon.mjs +32 -0
  139. package/dist/components/Icons/ChevronLeftIcon.mjs.map +1 -0
  140. package/dist/components/Icons/ChevronRightIcon.mjs +32 -0
  141. package/dist/components/Icons/ChevronRightIcon.mjs.map +1 -0
  142. package/dist/components/Icons/CloseIcon.mjs +29 -0
  143. package/dist/components/Icons/CloseIcon.mjs.map +1 -0
  144. package/dist/components/Icons/CrossIcon.mjs +23 -0
  145. package/dist/components/Icons/CrossIcon.mjs.map +1 -0
  146. package/dist/components/Icons/CrownIcon.mjs +23 -0
  147. package/dist/components/Icons/CrownIcon.mjs.map +1 -0
  148. package/dist/components/Icons/ErrorCircleIcon.mjs +30 -0
  149. package/dist/components/Icons/ErrorCircleIcon.mjs.map +1 -0
  150. package/dist/components/Icons/ErrorIcon.mjs +30 -0
  151. package/dist/components/Icons/ErrorIcon.mjs.map +1 -0
  152. package/dist/components/Icons/FireIcon.mjs +30 -0
  153. package/dist/components/Icons/FireIcon.mjs.map +1 -0
  154. package/dist/components/Icons/HomeIcon.mjs +23 -0
  155. package/dist/components/Icons/HomeIcon.mjs.map +1 -0
  156. package/dist/components/Icons/InfoCircleIcon.mjs +30 -0
  157. package/dist/components/Icons/InfoCircleIcon.mjs.map +1 -0
  158. package/dist/components/Icons/InfoIcon.mjs +30 -0
  159. package/dist/components/Icons/InfoIcon.mjs.map +1 -0
  160. package/dist/components/Icons/MicrophoneIcon.mjs +31 -0
  161. package/dist/components/Icons/MicrophoneIcon.mjs.map +1 -0
  162. package/dist/components/Icons/MinusIcon.mjs +23 -0
  163. package/dist/components/Icons/MinusIcon.mjs.map +1 -0
  164. package/dist/components/Icons/PlusIcon.mjs +23 -0
  165. package/dist/components/Icons/PlusIcon.mjs.map +1 -0
  166. package/dist/components/Icons/SpinnerIcon.mjs +26 -0
  167. package/dist/components/Icons/SpinnerIcon.mjs.map +1 -0
  168. package/dist/components/Icons/StopIcon.mjs +22 -0
  169. package/dist/components/Icons/StopIcon.mjs.map +1 -0
  170. package/dist/components/Icons/SuccessIcon.mjs +30 -0
  171. package/dist/components/Icons/SuccessIcon.mjs.map +1 -0
  172. package/dist/components/Icons/VipBadgeIcon.mjs +80 -0
  173. package/dist/components/Icons/VipBadgeIcon.mjs.map +1 -0
  174. package/dist/components/Icons/WarningIcon.mjs +30 -0
  175. package/dist/components/Icons/WarningIcon.mjs.map +1 -0
  176. package/dist/components/Icons/WarningTriangleIcon.mjs +30 -0
  177. package/dist/components/Icons/WarningTriangleIcon.mjs.map +1 -0
  178. package/dist/components/Logo/Logo.mjs +165 -0
  179. package/dist/components/Logo/Logo.mjs.map +1 -0
  180. package/dist/components/Pagination/Pagination.mjs +127 -0
  181. package/dist/components/Pagination/Pagination.mjs.map +1 -0
  182. package/dist/components/Pill/Pill.mjs +52 -0
  183. package/dist/components/Pill/Pill.mjs.map +1 -0
  184. package/dist/components/ProgressBar/ProgressBar.mjs +95 -0
  185. package/dist/components/ProgressBar/ProgressBar.mjs.map +1 -0
  186. package/dist/components/Radio/Radio.mjs +56 -0
  187. package/dist/components/Radio/Radio.mjs.map +1 -0
  188. package/dist/components/RadioGroup/RadioGroup.mjs +12 -0
  189. package/dist/components/RadioGroup/RadioGroup.mjs.map +1 -0
  190. package/dist/components/Slider/Slider.mjs +78 -0
  191. package/dist/components/Slider/Slider.mjs.map +1 -0
  192. package/dist/components/Slider/SliderLayout.mjs +31 -0
  193. package/dist/components/Slider/SliderLayout.mjs.map +1 -0
  194. package/dist/components/Slider/SliderThumb.mjs +69 -0
  195. package/dist/components/Slider/SliderThumb.mjs.map +1 -0
  196. package/dist/components/Snackbar/Snackbar.mjs +198 -0
  197. package/dist/components/Snackbar/Snackbar.mjs.map +1 -0
  198. package/dist/components/Switch/Switch.mjs +39 -0
  199. package/dist/components/Switch/Switch.mjs.map +1 -0
  200. package/dist/components/SwitchField/SwitchField.mjs +86 -0
  201. package/dist/components/SwitchField/SwitchField.mjs.map +1 -0
  202. package/dist/components/SwitchToggle/SwitchToggle.mjs +93 -0
  203. package/dist/components/SwitchToggle/SwitchToggle.mjs.map +1 -0
  204. package/dist/components/Tabs/Tabs.mjs +7 -0
  205. package/dist/components/Tabs/Tabs.mjs.map +1 -0
  206. package/dist/components/Tabs/TabsContent.mjs +18 -0
  207. package/dist/components/Tabs/TabsContent.mjs.map +1 -0
  208. package/dist/components/Tabs/TabsList.mjs +24 -0
  209. package/dist/components/Tabs/TabsList.mjs.map +1 -0
  210. package/dist/components/Tabs/TabsTrigger.mjs +32 -0
  211. package/dist/components/Tabs/TabsTrigger.mjs.map +1 -0
  212. package/dist/components/Toast/Toast.mjs +110 -0
  213. package/dist/components/Toast/Toast.mjs.map +1 -0
  214. package/dist/index.d.ts +30 -0
  215. package/dist/index.mjs +107 -10507
  216. package/dist/index.mjs.map +1 -1
  217. package/dist/utils/cn.mjs +10 -0
  218. package/dist/utils/cn.mjs.map +1 -0
  219. package/package.json +10 -4
  220. package/dist/index.cjs +0 -2
  221. package/dist/index.cjs.map +0 -1
@@ -0,0 +1,139 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
4
+ import * as React from "react";
5
+ import { cn } from "../../utils/cn.mjs";
6
+ import { CheckIcon } from "../Icons/CheckIcon.mjs";
7
+ import { MinusIcon } from "../Icons/MinusIcon.mjs";
8
+ const Checkbox = React.forwardRef(
9
+ ({ className, size = "default", label, helperText, disabled, name, ...props }, ref) => {
10
+ const id = React.useId();
11
+ const helperTextId = helperText ? `${id}-helper` : void 0;
12
+ const hasLabel = Boolean(label || helperText);
13
+ const inputRef = React.useRef(null);
14
+ React.useImperativeHandle(ref, () => inputRef.current);
15
+ const handleCheckedChange = (value) => {
16
+ const checked = value === true;
17
+ if (inputRef.current) {
18
+ inputRef.current.checked = checked;
19
+ inputRef.current.dispatchEvent(new Event("change", { bubbles: true }));
20
+ }
21
+ props.onCheckedChange?.(value);
22
+ };
23
+ const checkboxElement = /* @__PURE__ */ jsxs(
24
+ "span",
25
+ {
26
+ className: cn(
27
+ "relative inline-flex size-5 shrink-0",
28
+ // Alignment when used with label
29
+ label && (helperText ? "mt-1" : "mt-0.5")
30
+ ),
31
+ children: [
32
+ /* @__PURE__ */ jsx(
33
+ "input",
34
+ {
35
+ ref: inputRef,
36
+ type: "checkbox",
37
+ name,
38
+ disabled,
39
+ "aria-hidden": true,
40
+ tabIndex: -1,
41
+ onChange: () => {
42
+ },
43
+ className: "pointer-events-none absolute size-px overflow-hidden opacity-0",
44
+ style: { clip: "rect(0,0,0,0)" }
45
+ }
46
+ ),
47
+ /* @__PURE__ */ jsx(
48
+ CheckboxPrimitive.Root,
49
+ {
50
+ id,
51
+ disabled,
52
+ "aria-describedby": helperTextId,
53
+ "data-testid": "checkbox",
54
+ ...props,
55
+ onCheckedChange: handleCheckedChange,
56
+ className: cn(
57
+ // Base styles
58
+ "flex size-5 items-center justify-center rounded border-2",
59
+ "transition-[border-color,background-color,color,box-shadow] duration-150",
60
+ // Default state
61
+ "border-body-100 bg-transparent text-transparent",
62
+ // Checked state
63
+ "data-[state=checked]:border-body-100 data-[state=checked]:bg-body-100 data-[state=checked]:text-body-300",
64
+ // Indeterminate state
65
+ "data-[state=indeterminate]:border-body-100 data-[state=indeterminate]:bg-body-100 data-[state=indeterminate]:text-body-300",
66
+ // Hover state
67
+ "hover:ring-2 hover:ring-brand-green-500 group-hover:ring-2 group-hover:ring-brand-green-500",
68
+ // Focus state
69
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 focus-visible:ring-offset-2 focus-visible:ring-offset-background-inverse-solid",
70
+ // Disabled state
71
+ "disabled:cursor-not-allowed disabled:border-disabled-400 disabled:ring-0 disabled:group-hover:ring-0",
72
+ "disabled:data-[state=checked]:border-disabled-400 disabled:data-[state=checked]:bg-disabled-400 disabled:data-[state=checked]:text-disabled-100",
73
+ !hasLabel && className
74
+ ),
75
+ children: /* @__PURE__ */ jsx(
76
+ CheckboxPrimitive.Indicator,
77
+ {
78
+ forceMount: true,
79
+ className: cn(
80
+ "flex size-3 items-center justify-center text-body-300",
81
+ "data-[state=unchecked]:invisible"
82
+ ),
83
+ children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, {}) : /* @__PURE__ */ jsx(CheckIcon, {})
84
+ }
85
+ )
86
+ }
87
+ )
88
+ ]
89
+ }
90
+ );
91
+ if (!hasLabel) {
92
+ return checkboxElement;
93
+ }
94
+ return /* @__PURE__ */ jsxs(
95
+ "div",
96
+ {
97
+ className: cn(
98
+ "inline-flex flex-col gap-0.5",
99
+ disabled && "is-disabled cursor-not-allowed",
100
+ className
101
+ ),
102
+ children: [
103
+ /* @__PURE__ */ jsxs("div", { className: "group inline-flex items-start gap-2", children: [
104
+ checkboxElement,
105
+ label && /* @__PURE__ */ jsx(
106
+ "label",
107
+ {
108
+ htmlFor: id,
109
+ className: cn(
110
+ "cursor-pointer select-none text-body-100",
111
+ "group-has-disabled:cursor-not-allowed group-has-disabled:text-disabled-100",
112
+ size === "small" ? "typography-body-2-semibold" : "typography-body-1-semibold"
113
+ ),
114
+ children: label
115
+ }
116
+ )
117
+ ] }),
118
+ helperText && /* @__PURE__ */ jsx(
119
+ "span",
120
+ {
121
+ id: helperTextId,
122
+ className: cn(
123
+ "ml-7 text-body-200",
124
+ "in-[.is-disabled]:cursor-not-allowed in-[.is-disabled]:text-disabled-100",
125
+ size === "small" ? "typography-caption-regular" : "typography-body-2-regular"
126
+ ),
127
+ children: helperText
128
+ }
129
+ )
130
+ ]
131
+ }
132
+ );
133
+ }
134
+ );
135
+ Checkbox.displayName = "Checkbox";
136
+ export {
137
+ Checkbox
138
+ };
139
+ //# sourceMappingURL=Checkbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.mjs","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { CheckIcon } from \"../Icons/CheckIcon\";\nimport { MinusIcon } from \"../Icons/MinusIcon\";\n\nexport type CheckboxSize = \"default\" | \"small\";\n\nexport interface CheckboxProps\n extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, \"asChild\"> {\n /** Size variant for label and helper text */\n size?: CheckboxSize;\n /** Label text displayed next to the checkbox */\n label?: string;\n /** Helper text displayed below the label */\n helperText?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, size = \"default\", label, helperText, disabled, name, ...props }, ref) => {\n const id = React.useId();\n const helperTextId = helperText ? `${id}-helper` : undefined;\n const hasLabel = Boolean(label || helperText);\n\n // Hidden input for form library compatibility (e.g. react-hook-form register)\n const inputRef = React.useRef<HTMLInputElement>(null);\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n const handleCheckedChange = (value: boolean | \"indeterminate\") => {\n const checked = value === true;\n if (inputRef.current) {\n inputRef.current.checked = checked;\n inputRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n props.onCheckedChange?.(value);\n };\n\n const checkboxElement = (\n <span\n className={cn(\n \"relative inline-flex size-5 shrink-0\",\n // Alignment when used with label\n label && (helperText ? \"mt-1\" : \"mt-0.5\"),\n )}\n >\n <input\n ref={inputRef}\n type=\"checkbox\"\n name={name}\n disabled={disabled}\n aria-hidden\n tabIndex={-1}\n onChange={() => {}}\n className=\"pointer-events-none absolute size-px overflow-hidden opacity-0\"\n style={{ clip: \"rect(0,0,0,0)\" }}\n />\n <CheckboxPrimitive.Root\n id={id}\n disabled={disabled}\n aria-describedby={helperTextId}\n data-testid=\"checkbox\"\n {...props}\n onCheckedChange={handleCheckedChange}\n className={cn(\n // Base styles\n \"flex size-5 items-center justify-center rounded border-2\",\n \"transition-[border-color,background-color,color,box-shadow] duration-150\",\n // Default state\n \"border-body-100 bg-transparent text-transparent\",\n // Checked state\n \"data-[state=checked]:border-body-100 data-[state=checked]:bg-body-100 data-[state=checked]:text-body-300\",\n // Indeterminate state\n \"data-[state=indeterminate]:border-body-100 data-[state=indeterminate]:bg-body-100 data-[state=indeterminate]:text-body-300\",\n // Hover state\n \"hover:ring-2 hover:ring-brand-green-500 group-hover:ring-2 group-hover:ring-brand-green-500\",\n // Focus state\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 focus-visible:ring-offset-2 focus-visible:ring-offset-background-inverse-solid\",\n // Disabled state\n \"disabled:cursor-not-allowed disabled:border-disabled-400 disabled:ring-0 disabled:group-hover:ring-0\",\n \"disabled:data-[state=checked]:border-disabled-400 disabled:data-[state=checked]:bg-disabled-400 disabled:data-[state=checked]:text-disabled-100\",\n !hasLabel && className,\n )}\n >\n <CheckboxPrimitive.Indicator\n forceMount\n className={cn(\n \"flex size-3 items-center justify-center text-body-300\",\n \"data-[state=unchecked]:invisible\",\n )}\n >\n {props.checked === \"indeterminate\" ? <MinusIcon /> : <CheckIcon />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n </span>\n );\n\n if (!hasLabel) {\n return checkboxElement;\n }\n\n return (\n <div\n className={cn(\n \"inline-flex flex-col gap-0.5\",\n disabled && \"is-disabled cursor-not-allowed\",\n className,\n )}\n >\n <div className=\"group inline-flex items-start gap-2\">\n {checkboxElement}\n {label && (\n <label\n htmlFor={id}\n className={cn(\n \"cursor-pointer select-none text-body-100\",\n \"group-has-disabled:cursor-not-allowed group-has-disabled:text-disabled-100\",\n size === \"small\" ? \"typography-body-2-semibold\" : \"typography-body-1-semibold\",\n )}\n >\n {label}\n </label>\n )}\n </div>\n {helperText && (\n <span\n id={helperTextId}\n className={cn(\n \"ml-7 text-body-200\",\n \"in-[.is-disabled]:cursor-not-allowed in-[.is-disabled]:text-disabled-100\",\n size === \"small\" ? \"typography-caption-regular\" : \"typography-body-2-regular\",\n )}\n >\n {helperText}\n </span>\n )}\n </div>\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n"],"names":[],"mappings":";;;;;;;AAkBO,MAAM,WAAW,MAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,OAAO,WAAW,OAAO,YAAY,UAAU,MAAM,GAAG,MAAA,GAAS,QAAQ;AACrF,UAAM,KAAK,MAAM,MAAA;AACjB,UAAM,eAAe,aAAa,GAAG,EAAE,YAAY;AACnD,UAAM,WAAW,QAAQ,SAAS,UAAU;AAG5C,UAAM,WAAW,MAAM,OAAyB,IAAI;AACpD,UAAM,oBAAoB,KAAK,MAAM,SAAS,OAA2B;AAEzE,UAAM,sBAAsB,CAAC,UAAqC;AAChE,YAAM,UAAU,UAAU;AAC1B,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,UAAU;AAC3B,iBAAS,QAAQ,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAA,CAAM,CAAC;AAAA,MACvE;AACA,YAAM,kBAAkB,KAAK;AAAA,IAC/B;AAEA,UAAM,kBACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA;AAAA,UAEA,UAAU,aAAa,SAAS;AAAA,QAAA;AAAA,QAGlC,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAK;AAAA,cACL,MAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA,eAAW;AAAA,cACX,UAAU;AAAA,cACV,UAAU,MAAM;AAAA,cAAC;AAAA,cACjB,WAAU;AAAA,cACV,OAAO,EAAE,MAAM,gBAAA;AAAA,YAAgB;AAAA,UAAA;AAAA,UAEjC;AAAA,YAAC,kBAAkB;AAAA,YAAlB;AAAA,cACC;AAAA,cACA;AAAA,cACA,oBAAkB;AAAA,cAClB,eAAY;AAAA,cACX,GAAG;AAAA,cACJ,iBAAiB;AAAA,cACjB,WAAW;AAAA;AAAA,gBAET;AAAA,gBACA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA,gBACA;AAAA,gBACA,CAAC,YAAY;AAAA,cAAA;AAAA,cAGf,UAAA;AAAA,gBAAC,kBAAkB;AAAA,gBAAlB;AAAA,kBACC,YAAU;AAAA,kBACV,WAAW;AAAA,oBACT;AAAA,oBACA;AAAA,kBAAA;AAAA,kBAGD,gBAAM,YAAY,sCAAmB,WAAA,EAAU,wBAAM,WAAA,CAAA,CAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YAClE;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IAAA;AAIJ,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,uCACZ,UAAA;AAAA,YAAA;AAAA,YACA,SACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS;AAAA,gBACT,WAAW;AAAA,kBACT;AAAA,kBACA;AAAA,kBACA,SAAS,UAAU,+BAA+B;AAAA,gBAAA;AAAA,gBAGnD,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACH,GAEJ;AAAA,UACC,cACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,SAAS,UAAU,+BAA+B;AAAA,cAAA;AAAA,cAGnD,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,SAAS,cAAc;"}
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { Slot, Slottable } from "@radix-ui/react-slot";
4
+ import * as React from "react";
5
+ import { cn } from "../../utils/cn.mjs";
6
+ const Chip = React.forwardRef(
7
+ ({
8
+ className,
9
+ variant = "rounded",
10
+ size = "32",
11
+ selected = false,
12
+ disabled = false,
13
+ leftDot = false,
14
+ leftIcon,
15
+ rightIcon,
16
+ notificationLabel,
17
+ onClick,
18
+ asChild = false,
19
+ children,
20
+ ...props
21
+ }, ref) => {
22
+ const isInteractive = !!onClick && !asChild;
23
+ const Comp = asChild ? Slot : isInteractive ? "button" : "span";
24
+ const isDark = variant === "dark";
25
+ return /* @__PURE__ */ jsxs(
26
+ Comp,
27
+ {
28
+ ref,
29
+ "data-testid": "chip",
30
+ className: cn(
31
+ "typography-caption-semibold relative inline-flex items-center gap-2 px-3 transition-colors",
32
+ // Shape
33
+ variant === "square" ? "rounded-lg" : "rounded-full",
34
+ // Size
35
+ size === "32" && "h-8 py-1",
36
+ size === "40" && "h-10 py-2.5",
37
+ // Variant colors
38
+ isDark && "bg-background-800 text-body-white-solid-constant",
39
+ !isDark && selected && "bg-brand-green-50 text-neutral-400",
40
+ !isDark && !selected && "bg-neutral-100 text-neutral-400",
41
+ // Hover
42
+ isInteractive && !disabled && !isDark && selected && "hover:bg-brand-green-500 hover:text-body-black-solid-constant",
43
+ isInteractive && !disabled && !isDark && !selected && "hover:bg-hover-400",
44
+ // Focus
45
+ "focus-visible:shadow-focus-ring focus-visible:outline-none",
46
+ // Disabled
47
+ disabled && isDark && "pointer-events-none opacity-50",
48
+ disabled && !isDark && "pointer-events-none text-neutral-300",
49
+ className
50
+ ),
51
+ ...isInteractive && {
52
+ type: "button",
53
+ disabled,
54
+ "aria-pressed": selected,
55
+ onClick
56
+ },
57
+ ...!isInteractive && disabled && { "aria-disabled": true },
58
+ ...selected && { "data-selected": "" },
59
+ ...props,
60
+ children: [
61
+ leftDot && /* @__PURE__ */ jsx("span", { className: "size-2 shrink-0 rounded-full bg-current", "aria-hidden": "true" }),
62
+ leftIcon && /* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center", "aria-hidden": "true", children: leftIcon }),
63
+ /* @__PURE__ */ jsx(Slottable, { children }),
64
+ rightIcon && /* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center", "aria-hidden": "true", children: rightIcon }),
65
+ notificationLabel && /* @__PURE__ */ jsx("span", { className: "typography-caption-semibold absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-body-100 px-1 text-body-300", children: notificationLabel })
66
+ ]
67
+ }
68
+ );
69
+ }
70
+ );
71
+ Chip.displayName = "Chip";
72
+ export {
73
+ Chip
74
+ };
75
+ //# sourceMappingURL=Chip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chip.mjs","sources":["../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type ChipVariant = \"rounded\" | \"square\" | \"dark\";\nexport type ChipSize = \"32\" | \"40\";\n\nexport interface ChipProps extends React.HTMLAttributes<HTMLElement> {\n /** Visual shape variant of the chip */\n variant?: ChipVariant;\n /** Size of the chip */\n size?: ChipSize;\n /** Whether the chip is in a selected state */\n selected?: boolean;\n /** Whether the chip is disabled */\n disabled?: boolean;\n /** Show left status dot */\n leftDot?: boolean;\n /** Left icon element */\n leftIcon?: React.ReactNode;\n /** Right icon element */\n rightIcon?: React.ReactNode;\n /** Notification badge content (e.g., \"99+\"). Passed as a string for i18n support. */\n notificationLabel?: string;\n /** Click handler — when provided, the chip renders as a `<button>` for accessibility */\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Render as a different element using Radix Slot */\n asChild?: boolean;\n}\n\nexport const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(\n (\n {\n className,\n variant = \"rounded\",\n size = \"32\",\n selected = false,\n disabled = false,\n leftDot = false,\n leftIcon,\n rightIcon,\n notificationLabel,\n onClick,\n asChild = false,\n children,\n ...props\n },\n ref,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Variant-heavy UI component\n ) => {\n const isInteractive = !!onClick && !asChild;\n const Comp = asChild ? Slot : isInteractive ? \"button\" : \"span\";\n const isDark = variant === \"dark\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"chip\"\n className={cn(\n \"typography-caption-semibold relative inline-flex items-center gap-2 px-3 transition-colors\",\n // Shape\n variant === \"square\" ? \"rounded-lg\" : \"rounded-full\",\n // Size\n size === \"32\" && \"h-8 py-1\",\n size === \"40\" && \"h-10 py-2.5\",\n // Variant colors\n isDark && \"bg-background-800 text-body-white-solid-constant\",\n !isDark && selected && \"bg-brand-green-50 text-neutral-400\",\n !isDark && !selected && \"bg-neutral-100 text-neutral-400\",\n // Hover\n isInteractive &&\n !disabled &&\n !isDark &&\n selected &&\n \"hover:bg-brand-green-500 hover:text-body-black-solid-constant\",\n isInteractive && !disabled && !isDark && !selected && \"hover:bg-hover-400\",\n // Focus\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n // Disabled\n disabled && isDark && \"pointer-events-none opacity-50\",\n disabled && !isDark && \"pointer-events-none text-neutral-300\",\n className,\n )}\n {...(isInteractive && {\n type: \"button\" as const,\n disabled,\n \"aria-pressed\": selected,\n onClick,\n })}\n {...(!isInteractive && disabled && { \"aria-disabled\": true })}\n {...(selected && { \"data-selected\": \"\" })}\n {...props}\n >\n {leftDot && <span className=\"size-2 shrink-0 rounded-full bg-current\" aria-hidden=\"true\" />}\n {leftIcon && (\n <span className=\"flex size-5 shrink-0 items-center justify-center\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n <Slottable>{children}</Slottable>\n {rightIcon && (\n <span className=\"flex size-5 shrink-0 items-center justify-center\" aria-hidden=\"true\">\n {rightIcon}\n </span>\n )}\n {notificationLabel && (\n <span className=\"typography-caption-semibold absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-body-100 px-1 text-body-300\">\n {notificationLabel}\n </span>\n )}\n </Comp>\n );\n },\n);\n\nChip.displayName = \"Chip\";\n"],"names":[],"mappings":";;;;;AA8BO,MAAM,OAAO,MAAM;AAAA,EACxB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QAEG;AACH,UAAM,gBAAgB,CAAC,CAAC,WAAW,CAAC;AACpC,UAAM,OAAO,UAAU,OAAO,gBAAgB,WAAW;AACzD,UAAM,SAAS,YAAY;AAE3B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA;AAAA,UAEA,YAAY,WAAW,eAAe;AAAA;AAAA,UAEtC,SAAS,QAAQ;AAAA,UACjB,SAAS,QAAQ;AAAA;AAAA,UAEjB,UAAU;AAAA,UACV,CAAC,UAAU,YAAY;AAAA,UACvB,CAAC,UAAU,CAAC,YAAY;AAAA;AAAA,UAExB,iBACE,CAAC,YACD,CAAC,UACD,YACA;AAAA,UACF,iBAAiB,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY;AAAA;AAAA,UAEtD;AAAA;AAAA,UAEA,YAAY,UAAU;AAAA,UACtB,YAAY,CAAC,UAAU;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAI,iBAAiB;AAAA,UACpB,MAAM;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB;AAAA,QAAA;AAAA,QAED,GAAI,CAAC,iBAAiB,YAAY,EAAE,iBAAiB,KAAA;AAAA,QACrD,GAAI,YAAY,EAAE,iBAAiB,GAAA;AAAA,QACnC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,WAAW,oBAAC,QAAA,EAAK,WAAU,2CAA0C,eAAY,QAAO;AAAA,UACxF,YACC,oBAAC,QAAA,EAAK,WAAU,oDAAmD,eAAY,QAC5E,UAAA,UACH;AAAA,UAEF,oBAAC,aAAW,UAAS;AAAA,UACpB,aACC,oBAAC,QAAA,EAAK,WAAU,oDAAmD,eAAY,QAC5E,UAAA,WACH;AAAA,UAED,qBACC,oBAAC,QAAA,EAAK,WAAU,iJACb,UAAA,kBAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,KAAK,cAAc;"}
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import * as React from "react";
5
+ import { cn } from "../../utils/cn.mjs";
6
+ function getDisplayValue(value, max) {
7
+ return value > max ? `${max}+` : value.toString();
8
+ }
9
+ const Count = React.forwardRef(
10
+ ({ className, variant = "Default", value = 0, max = 99, asChild = false, children, ...props }, ref) => {
11
+ if (value === 0 && !children) {
12
+ return null;
13
+ }
14
+ const Comp = asChild ? Slot : "span";
15
+ return /* @__PURE__ */ jsx(
16
+ Comp,
17
+ {
18
+ ref,
19
+ className: cn(
20
+ "typography-caption-semibold inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 tabular-nums leading-none",
21
+ variant === "Default" && "bg-error-500 text-body-white-solid-constant",
22
+ variant === "Brand" && "bg-brand-green-500 text-body-black-solid-constant",
23
+ variant === "Pink" && "bg-brand-pink-500 text-body-black-solid-constant",
24
+ variant === "Info" && "bg-info-500 text-body-white-solid-constant",
25
+ variant === "Success" && "bg-success-500 text-body-white-solid-constant",
26
+ variant === "Warning" && "bg-warning-500 text-body-black-solid-constant",
27
+ className
28
+ ),
29
+ ...props,
30
+ children: children ?? getDisplayValue(value, max)
31
+ }
32
+ );
33
+ }
34
+ );
35
+ Count.displayName = "Count";
36
+ export {
37
+ Count
38
+ };
39
+ //# sourceMappingURL=Count.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Count.mjs","sources":["../../../src/components/Count/Count.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type CountVariant = \"Default\" | \"Brand\" | \"Pink\" | \"Info\" | \"Success\" | \"Warning\";\n\nfunction getDisplayValue(value: number, max: number): string {\n return value > max ? `${max}+` : value.toString();\n}\n\nexport interface CountProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Visual style variant of the count */\n variant?: CountVariant;\n /** The count value to display */\n value?: number;\n /** Maximum value to display before showing overflow (e.g., \"99+\") */\n max?: number;\n /** Render as a different element using Radix Slot */\n asChild?: boolean;\n}\n\nexport const Count = React.forwardRef<HTMLSpanElement, CountProps>(\n (\n { className, variant = \"Default\", value = 0, max = 99, asChild = false, children, ...props },\n ref,\n ) => {\n if (value === 0 && !children) {\n return null;\n }\n\n const Comp = asChild ? Slot : \"span\";\n\n return (\n <Comp\n ref={ref}\n className={cn(\n \"typography-caption-semibold inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 tabular-nums leading-none\",\n variant === \"Default\" && \"bg-error-500 text-body-white-solid-constant\",\n variant === \"Brand\" && \"bg-brand-green-500 text-body-black-solid-constant\",\n variant === \"Pink\" && \"bg-brand-pink-500 text-body-black-solid-constant\",\n variant === \"Info\" && \"bg-info-500 text-body-white-solid-constant\",\n variant === \"Success\" && \"bg-success-500 text-body-white-solid-constant\",\n variant === \"Warning\" && \"bg-warning-500 text-body-black-solid-constant\",\n className,\n )}\n {...props}\n >\n {children ?? getDisplayValue(value, max)}\n </Comp>\n );\n },\n);\n\nCount.displayName = \"Count\";\n"],"names":[],"mappings":";;;;;AAMA,SAAS,gBAAgB,OAAe,KAAqB;AAC3D,SAAO,QAAQ,MAAM,GAAG,GAAG,MAAM,MAAM,SAAA;AACzC;AAaO,MAAM,QAAQ,MAAM;AAAA,EACzB,CACE,EAAE,WAAW,UAAU,WAAW,QAAQ,GAAG,MAAM,IAAI,UAAU,OAAO,UAAU,GAAG,MAAA,GACrF,QACG;AACH,QAAI,UAAU,KAAK,CAAC,UAAU;AAC5B,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,UAAU,OAAO;AAE9B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,YAAY,aAAa;AAAA,UACzB,YAAY,WAAW;AAAA,UACvB,YAAY,UAAU;AAAA,UACtB,YAAY,UAAU;AAAA,UACtB,YAAY,aAAa;AAAA,UACzB,YAAY,aAAa;AAAA,UACzB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA,YAAY,gBAAgB,OAAO,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAG7C;AACF;AAEA,MAAM,cAAc;"}
@@ -0,0 +1,133 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { forwardRef, useRef, useEffect } from "react";
4
+ import { DayPicker } from "react-day-picker";
5
+ import { cn } from "../../utils/cn.mjs";
6
+ import { Button } from "../Button/Button.mjs";
7
+ import { ChevronLeftIcon } from "../Icons/ChevronLeftIcon.mjs";
8
+ import { ChevronRightIcon } from "../Icons/ChevronRightIcon.mjs";
9
+ function Day({ day, modifiers, className, ...divProps }) {
10
+ const { range_start, range_end } = modifiers;
11
+ const isSingleDayRange = range_start && range_end;
12
+ return /* @__PURE__ */ jsx(
13
+ "div",
14
+ {
15
+ className: cn(
16
+ className,
17
+ (range_start || range_end) && !isSingleDayRange && "from-50% from-transparent to-50%",
18
+ range_start && !isSingleDayRange && "bg-linear-to-r to-brand-green-50",
19
+ range_end && !isSingleDayRange && "bg-linear-to-l to-brand-green-50"
20
+ ),
21
+ ...divProps
22
+ }
23
+ );
24
+ }
25
+ function DayButton({ day, modifiers, className, ...buttonProps }) {
26
+ const ref = useRef(null);
27
+ useEffect(() => {
28
+ if (modifiers.focused) ref.current?.focus();
29
+ }, [modifiers.focused]);
30
+ return /* @__PURE__ */ jsx(
31
+ "button",
32
+ {
33
+ ref,
34
+ type: "button",
35
+ className: cn(
36
+ "relative z-10 inline-flex size-10 cursor-pointer items-center justify-center rounded-lg",
37
+ "typography-body-2-regular",
38
+ "transition-colors hover:bg-brand-green-50",
39
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500",
40
+ "disabled:cursor-not-allowed disabled:opacity-50",
41
+ modifiers.today && !modifiers.selected && "border border-brand-green-500",
42
+ modifiers.selected && !modifiers.range_middle ? "bg-brand-green-500 text-body-black-solid-constant hover:bg-brand-green-500" : "text-body-100",
43
+ modifiers.range_middle && "rounded-none bg-transparent",
44
+ modifiers.outside && "pointer-events-none opacity-50"
45
+ ),
46
+ ...buttonProps
47
+ }
48
+ );
49
+ }
50
+ const DatePicker = forwardRef(
51
+ ({
52
+ type = "single",
53
+ onApply,
54
+ onCancel,
55
+ cancelLabel = "Cancel",
56
+ applyLabel = "Apply",
57
+ showFooter = true,
58
+ className,
59
+ formatters,
60
+ ...dayPickerProps
61
+ }, ref) => {
62
+ const numberOfMonths = type === "double" ? 2 : 1;
63
+ const isMulti = numberOfMonths > 1;
64
+ return /* @__PURE__ */ jsxs(
65
+ "div",
66
+ {
67
+ ref,
68
+ className: cn(
69
+ "inline-flex flex-col rounded-2xl border border-neutral-200 bg-background-inverse-solid shadow-[0px_6px_12px_0px_rgba(0,0,0,0.1)] backdrop-blur-sm",
70
+ className
71
+ ),
72
+ children: [
73
+ /* @__PURE__ */ jsx(
74
+ DayPicker,
75
+ {
76
+ showOutsideDays: true,
77
+ numberOfMonths,
78
+ formatters: {
79
+ formatCaption: (date) => date.toLocaleDateString("en-US", { month: "short", year: "numeric" }),
80
+ ...formatters
81
+ },
82
+ classNames: {
83
+ root: "w-full",
84
+ months: "relative flex",
85
+ month: "flex flex-1 flex-col",
86
+ month_caption: cn("flex items-center py-4", isMulti ? "justify-center px-2" : "px-5"),
87
+ caption_label: "typography-body-1-semibold text-body-100",
88
+ nav: cn(
89
+ "absolute top-4 z-20 flex",
90
+ isMulti ? "pointer-events-none inset-x-3 justify-between" : "right-3 gap-1"
91
+ ),
92
+ button_previous: "pointer-events-auto inline-flex size-8 cursor-pointer items-center justify-center rounded-full text-body-100 transition-colors hover:bg-brand-green-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 disabled:cursor-not-allowed disabled:opacity-50",
93
+ // !TODO https://linear.app/fanvue/issue/ENG-7301/swap-out-typography-tailwind-utility-classes
94
+ button_next: "pointer-events-auto inline-flex size-8 cursor-pointer items-center justify-center rounded-full text-body-100 transition-colors hover:bg-brand-green-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 disabled:cursor-not-allowed disabled:opacity-50",
95
+ // !TODO https://linear.app/fanvue/issue/ENG-7301/swap-out-typography-tailwind-utility-classes
96
+ month_grid: cn("mb-4", isMulti ? "mx-2" : "mx-4"),
97
+ weekdays: "flex",
98
+ weekday: "flex h-[30px] w-10 flex-1 items-center justify-center typography-body-2-regular text-body-200",
99
+ week: "flex overflow-hidden rounded-lg",
100
+ day: "relative flex w-10 flex-1 items-center justify-center",
101
+ range_middle: "bg-brand-green-50",
102
+ hidden: "hidden"
103
+ },
104
+ components: {
105
+ /**
106
+ * !NOTE: We're unable to use semantic elements for the grid due to rdp, as such we've disabled the a11y lint rules for these elements in biome.json.
107
+ */
108
+ Chevron: ({ orientation }) => orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeftIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {}),
109
+ MonthGrid: (props) => /* @__PURE__ */ jsx("div", { role: "grid", ...props }),
110
+ Weekdays: (props) => /* @__PURE__ */ jsx("div", { role: "row", ...props }),
111
+ Weekday: (props) => /* @__PURE__ */ jsx("div", { role: "columnheader", ...props }),
112
+ Weeks: (props) => /* @__PURE__ */ jsx("div", { role: "rowgroup", ...props }),
113
+ Week: ({ week, ...props }) => /* @__PURE__ */ jsx("div", { role: "row", ...props }),
114
+ Day,
115
+ DayButton
116
+ },
117
+ ...dayPickerProps
118
+ }
119
+ ),
120
+ showFooter && /* @__PURE__ */ jsxs("div", { className: "flex gap-4 px-5 pb-4", children: [
121
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "40", className: "flex-1", onClick: onCancel, children: cancelLabel }),
122
+ /* @__PURE__ */ jsx(Button, { variant: "primary", size: "40", className: "flex-1", onClick: onApply, children: applyLabel })
123
+ ] })
124
+ ]
125
+ }
126
+ );
127
+ }
128
+ );
129
+ DatePicker.displayName = "DatePicker";
130
+ export {
131
+ DatePicker
132
+ };
133
+ //# sourceMappingURL=DatePicker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePicker.mjs","sources":["../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["import { forwardRef, useEffect, useRef } from \"react\";\nimport {\n type ChevronProps,\n type DateRange,\n type DayButtonProps,\n DayPicker,\n type DayPickerProps,\n type DayProps,\n type MonthGridProps,\n type WeekdayProps,\n type WeekdaysProps,\n type WeekProps,\n type WeeksProps,\n} from \"react-day-picker\";\nimport { cn } from \"../../utils/cn\";\nimport type { OmitDistributed } from \"../../utils/types\";\nimport { Button } from \"../Button/Button\";\nimport { ChevronLeftIcon } from \"../Icons/ChevronLeftIcon\";\nimport { ChevronRightIcon } from \"../Icons/ChevronRightIcon\";\n\nexport type { DateRange }; // Needed by consumers when passing props\n\nexport type DatePickerType = \"single\" | \"double\";\n\nexport interface DatePickerOwnProps {\n /** Display one month or two side-by-side. @default \"single\" */\n type?: DatePickerType;\n /** Called when the Apply button is clicked. */\n onApply?: () => void;\n /** Called when the Cancel button is clicked. */\n onCancel?: () => void;\n /** Label for the cancel button. @default \"Cancel\" */\n cancelLabel?: string;\n /** Label for the apply button. @default \"Apply\" */\n applyLabel?: string;\n /** Whether to render cancel / apply footer buttons. @default true */\n showFooter?: boolean;\n /** Additional className for the outer container. */\n className?: string;\n}\n\nfunction Day({ day, modifiers, className, ...divProps }: DayProps) {\n const { range_start, range_end } = modifiers;\n const isSingleDayRange = range_start && range_end;\n\n return (\n <div\n className={cn(\n className,\n (range_start || range_end) && !isSingleDayRange && \"from-50% from-transparent to-50%\",\n range_start && !isSingleDayRange && \"bg-linear-to-r to-brand-green-50\",\n range_end && !isSingleDayRange && \"bg-linear-to-l to-brand-green-50\",\n )}\n {...divProps}\n />\n );\n}\n\nfunction DayButton({ day, modifiers, className, ...buttonProps }: DayButtonProps) {\n const ref = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n \"relative z-10 inline-flex size-10 cursor-pointer items-center justify-center rounded-lg\",\n \"typography-body-2-regular\",\n \"transition-colors hover:bg-brand-green-50\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n modifiers.today && !modifiers.selected && \"border border-brand-green-500\",\n modifiers.selected && !modifiers.range_middle\n ? \"bg-brand-green-500 text-body-black-solid-constant hover:bg-brand-green-500\"\n : \"text-body-100\",\n modifiers.range_middle && \"rounded-none bg-transparent\",\n modifiers.outside && \"pointer-events-none opacity-50\",\n )}\n {...buttonProps}\n />\n );\n}\n\nexport type DatePickerProps = DatePickerOwnProps &\n OmitDistributed<DayPickerProps, \"numberOfMonths\">;\n\nexport const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(\n (\n {\n type = \"single\",\n onApply,\n onCancel,\n cancelLabel = \"Cancel\",\n applyLabel = \"Apply\",\n showFooter = true,\n className,\n formatters,\n ...dayPickerProps\n },\n ref,\n ) => {\n const numberOfMonths = type === \"double\" ? 2 : 1;\n const isMulti = numberOfMonths > 1;\n\n return (\n <div\n ref={ref}\n className={cn(\n \"inline-flex flex-col rounded-2xl border border-neutral-200 bg-background-inverse-solid shadow-[0px_6px_12px_0px_rgba(0,0,0,0.1)] backdrop-blur-sm\",\n className,\n )}\n >\n <DayPicker\n showOutsideDays\n numberOfMonths={numberOfMonths}\n formatters={{\n formatCaption: (date: Date) =>\n date.toLocaleDateString(\"en-US\", { month: \"short\", year: \"numeric\" }),\n ...formatters,\n }}\n classNames={{\n root: \"w-full\",\n months: \"relative flex\",\n month: \"flex flex-1 flex-col\",\n month_caption: cn(\"flex items-center py-4\", isMulti ? \"justify-center px-2\" : \"px-5\"),\n caption_label: \"typography-body-1-semibold text-body-100\",\n nav: cn(\n \"absolute top-4 z-20 flex\",\n isMulti ? \"pointer-events-none inset-x-3 justify-between\" : \"right-3 gap-1\",\n ),\n button_previous:\n \"pointer-events-auto inline-flex size-8 cursor-pointer items-center justify-center rounded-full text-body-100 transition-colors hover:bg-brand-green-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 disabled:cursor-not-allowed disabled:opacity-50\", // !TODO https://linear.app/fanvue/issue/ENG-7301/swap-out-typography-tailwind-utility-classes\n button_next:\n \"pointer-events-auto inline-flex size-8 cursor-pointer items-center justify-center rounded-full text-body-100 transition-colors hover:bg-brand-green-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple-500 disabled:cursor-not-allowed disabled:opacity-50\", // !TODO https://linear.app/fanvue/issue/ENG-7301/swap-out-typography-tailwind-utility-classes\n month_grid: cn(\"mb-4\", isMulti ? \"mx-2\" : \"mx-4\"),\n weekdays: \"flex\",\n weekday:\n \"flex h-[30px] w-10 flex-1 items-center justify-center typography-body-2-regular text-body-200\",\n week: \"flex overflow-hidden rounded-lg\",\n day: \"relative flex w-10 flex-1 items-center justify-center\",\n range_middle: \"bg-brand-green-50\",\n hidden: \"hidden\",\n }}\n components={{\n /**\n * !NOTE: We're unable to use semantic elements for the grid due to rdp, as such we've disabled the a11y lint rules for these elements in biome.json.\n */\n Chevron: ({ orientation }: ChevronProps) =>\n orientation === \"left\" ? <ChevronLeftIcon /> : <ChevronRightIcon />,\n MonthGrid: (props: MonthGridProps) => <div role=\"grid\" {...props} />,\n Weekdays: (props: WeekdaysProps) => <div role=\"row\" {...props} />,\n Weekday: (props: WeekdayProps) => <div role=\"columnheader\" {...props} />,\n Weeks: (props: WeeksProps) => <div role=\"rowgroup\" {...props} />,\n Week: ({ week, ...props }: WeekProps) => <div role=\"row\" {...props} />,\n Day,\n DayButton,\n }}\n {...dayPickerProps}\n />\n\n {showFooter && (\n <div className=\"flex gap-4 px-5 pb-4\">\n <Button variant=\"secondary\" size=\"40\" className=\"flex-1\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n <Button variant=\"primary\" size=\"40\" className=\"flex-1\" onClick={onApply}>\n {applyLabel}\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":[],"mappings":";;;;;;;;AAyCA,SAAS,IAAI,EAAE,KAAK,WAAW,WAAW,GAAG,YAAsB;AACjE,QAAM,EAAE,aAAa,UAAA,IAAc;AACnC,QAAM,mBAAmB,eAAe;AAExC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,SACC,eAAe,cAAc,CAAC,oBAAoB;AAAA,QACnD,eAAe,CAAC,oBAAoB;AAAA,QACpC,aAAa,CAAC,oBAAoB;AAAA,MAAA;AAAA,MAEnC,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAAS,UAAU,EAAE,KAAK,WAAW,WAAW,GAAG,eAA+B;AAChF,QAAM,MAAM,OAA0B,IAAI;AAE1C,YAAU,MAAM;AACd,QAAI,UAAU,QAAS,KAAI,SAAS,MAAA;AAAA,EACtC,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,SAAS,CAAC,UAAU,YAAY;AAAA,QAC1C,UAAU,YAAY,CAAC,UAAU,eAC7B,+EACA;AAAA,QACJ,UAAU,gBAAgB;AAAA,QAC1B,UAAU,WAAW;AAAA,MAAA;AAAA,MAEtB,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAKO,MAAM,aAAa;AAAA,EACxB,CACE;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,aAAa;AAAA,IACb,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,iBAAiB,SAAS,WAAW,IAAI;AAC/C,UAAM,UAAU,iBAAiB;AAEjC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,iBAAe;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,eAAe,CAAC,SACd,KAAK,mBAAmB,SAAS,EAAE,OAAO,SAAS,MAAM,WAAW;AAAA,gBACtE,GAAG;AAAA,cAAA;AAAA,cAEL,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,QAAQ;AAAA,gBACR,OAAO;AAAA,gBACP,eAAe,GAAG,0BAA0B,UAAU,wBAAwB,MAAM;AAAA,gBACpF,eAAe;AAAA,gBACf,KAAK;AAAA,kBACH;AAAA,kBACA,UAAU,kDAAkD;AAAA,gBAAA;AAAA,gBAE9D,iBACE;AAAA;AAAA,gBACF,aACE;AAAA;AAAA,gBACF,YAAY,GAAG,QAAQ,UAAU,SAAS,MAAM;AAAA,gBAChD,UAAU;AAAA,gBACV,SACE;AAAA,gBACF,MAAM;AAAA,gBACN,KAAK;AAAA,gBACL,cAAc;AAAA,gBACd,QAAQ;AAAA,cAAA;AAAA,cAEV,YAAY;AAAA;AAAA;AAAA;AAAA,gBAIV,SAAS,CAAC,EAAE,YAAA,MACV,gBAAgB,SAAS,oBAAC,iBAAA,CAAA,CAAgB,IAAK,oBAAC,kBAAA,CAAA,CAAiB;AAAA,gBACnE,WAAW,CAAC,UAA0B,oBAAC,SAAI,MAAK,QAAQ,GAAG,OAAO;AAAA,gBAClE,UAAU,CAAC,UAAyB,oBAAC,SAAI,MAAK,OAAO,GAAG,OAAO;AAAA,gBAC/D,SAAS,CAAC,UAAwB,oBAAC,SAAI,MAAK,gBAAgB,GAAG,OAAO;AAAA,gBACtE,OAAO,CAAC,UAAsB,oBAAC,SAAI,MAAK,YAAY,GAAG,OAAO;AAAA,gBAC9D,MAAM,CAAC,EAAE,MAAM,GAAG,MAAA,MAAuB,oBAAC,OAAA,EAAI,MAAK,OAAO,GAAG,MAAA,CAAO;AAAA,gBACpE;AAAA,gBACA;AAAA,cAAA;AAAA,cAED,GAAG;AAAA,YAAA;AAAA,UAAA;AAAA,UAGL,cACC,qBAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAO,SAAQ,aAAY,MAAK,MAAK,WAAU,UAAS,SAAS,UAC/D,UAAA,YAAA,CACH;AAAA,YACA,oBAAC,QAAA,EAAO,SAAQ,WAAU,MAAK,MAAK,WAAU,UAAS,SAAS,SAC7D,UAAA,WAAA,CACH;AAAA,UAAA,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,WAAW,cAAc;"}
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import * as SeparatorPrimitive from "@radix-ui/react-separator";
4
+ import * as React from "react";
5
+ import { cn } from "../../utils/cn.mjs";
6
+ const Divider = React.forwardRef(({ label, className, ...props }, ref) => {
7
+ if (label !== void 0) {
8
+ return /* @__PURE__ */ jsxs(
9
+ "div",
10
+ {
11
+ ref,
12
+ className: cn(`my-2 flex w-full items-center justify-center gap-2`, className),
13
+ children: [
14
+ /* @__PURE__ */ jsx(
15
+ SeparatorPrimitive.Root,
16
+ {
17
+ decorative: true,
18
+ orientation: "horizontal",
19
+ className: "h-px flex-1 bg-neutral-200",
20
+ ...props
21
+ }
22
+ ),
23
+ /* @__PURE__ */ jsx("span", { className: "typography-body-2-regular shrink-0 text-body-100", children: label }),
24
+ /* @__PURE__ */ jsx(
25
+ SeparatorPrimitive.Root,
26
+ {
27
+ decorative: true,
28
+ orientation: "horizontal",
29
+ className: "h-px flex-1 bg-neutral-200"
30
+ }
31
+ )
32
+ ]
33
+ }
34
+ );
35
+ }
36
+ return /* @__PURE__ */ jsx(
37
+ SeparatorPrimitive.Root,
38
+ {
39
+ ref,
40
+ decorative: true,
41
+ orientation: "horizontal",
42
+ className: cn(`mx-auto my-2 h-px w-full bg-neutral-200`, className),
43
+ ...props
44
+ }
45
+ );
46
+ });
47
+ Divider.displayName = "Divider";
48
+ export {
49
+ Divider
50
+ };
51
+ //# sourceMappingURL=Divider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Divider.mjs","sources":["../../../src/components/Divider/Divider.tsx"],"sourcesContent":["import * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\n\nexport type DividerOrientation = \"horizontal\" | \"vertical\";\nexport type DividerType = \"default\" | \"text\";\n\nexport interface DividerProps\n extends React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> {\n /** Custom label to display*/\n label?: string;\n}\n\nexport const Divider = React.forwardRef<\n React.ElementRef<typeof SeparatorPrimitive.Root>,\n DividerProps\n>(({ label, className, ...props }, ref) => {\n if (label !== undefined) {\n return (\n <div\n ref={ref}\n className={cn(`my-2 flex w-full items-center justify-center gap-2`, className)}\n >\n <SeparatorPrimitive.Root\n decorative\n orientation=\"horizontal\"\n className=\"h-px flex-1 bg-neutral-200\"\n {...props}\n />\n <span className=\"typography-body-2-regular shrink-0 text-body-100\">{label}</span>\n <SeparatorPrimitive.Root\n decorative\n orientation=\"horizontal\"\n className=\"h-px flex-1 bg-neutral-200\"\n />\n </div>\n );\n }\n\n return (\n <SeparatorPrimitive.Root\n ref={ref}\n decorative\n orientation=\"horizontal\"\n className={cn(`mx-auto my-2 h-px w-full bg-neutral-200`, className)}\n {...props}\n />\n );\n});\n\nDivider.displayName = \"Divider\";\n"],"names":[],"mappings":";;;;;AAaO,MAAM,UAAU,MAAM,WAG3B,CAAC,EAAE,OAAO,WAAW,GAAG,MAAA,GAAS,QAAQ;AACzC,MAAI,UAAU,QAAW;AACvB,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,sDAAsD,SAAS;AAAA,QAE7E,UAAA;AAAA,UAAA;AAAA,YAAC,mBAAmB;AAAA,YAAnB;AAAA,cACC,YAAU;AAAA,cACV,aAAY;AAAA,cACZ,WAAU;AAAA,cACT,GAAG;AAAA,YAAA;AAAA,UAAA;AAAA,UAEN,oBAAC,QAAA,EAAK,WAAU,oDAAoD,UAAA,OAAM;AAAA,UAC1E;AAAA,YAAC,mBAAmB;AAAA,YAAnB;AAAA,cACC,YAAU;AAAA,cACV,aAAY;AAAA,cACZ,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAEA,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC;AAAA,MACA,YAAU;AAAA,MACV,aAAY;AAAA,MACZ,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AAED,QAAQ,cAAc;"}
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../utils/cn.mjs";
5
+ import { Count } from "../Count/Count.mjs";
6
+ const iconButtonVariants = {
7
+ primary: "bg-neutral-400 text-body-300 hover:bg-hover-100 disabled:opacity-50 focus:shadow-focus-ring",
8
+ secondary: `bg-neutral-100 text-neutral-400 hover:bg-neutral-200 disabled:opacity-50 focus:focus:shadow-focus-ring`,
9
+ tertiary: `bg-transparent text-neutral-400 hover:bg-hover-300 disabled:opacity-50 focus:shadow-focus-ring active:bg-brand-green-50`,
10
+ brand: `bg-body-black-solid-constant text-brand-green-500 hover:bg-brand-green-500 hover:text-body-black-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,
11
+ contrast: `bg-transparent text-body-white-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,
12
+ messaging: `bg-body-black-solid-constant text-brand-green-500 hover:bg-brand-green-500 hover:text-body-black-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,
13
+ navTray: `bg-transparent text-neutral-400 disabled:opacity-50 focus:shadow-focus-ring active:bg-brand-green-50`,
14
+ tertiaryDestructive: `bg-transparent text-error-500 hover:bg-hover-300 disabled:opacity-50 focus:shadow-focus-ring`,
15
+ stop: `bg-neutral-400 text-body-300 hover:bg-brand-green-500 hover:text-body-black-solid-constant`,
16
+ microphone: `bg-neutral-400 text-body-300 hover:bg-brand-green-500 hover:text-body-black-solid-constant`
17
+ };
18
+ const iconSizeVariants = {
19
+ 24: "size-4",
20
+ 32: "size-5",
21
+ 40: "size-6",
22
+ 52: "size-7",
23
+ 72: "size-8"
24
+ };
25
+ const sizeVariants = {
26
+ 24: "p-1",
27
+ 32: "p-1.5",
28
+ 40: "p-[10px]",
29
+ 52: "p-2",
30
+ 72: "p-4"
31
+ };
32
+ const IconButton = React.forwardRef(
33
+ ({ className, variant = "primary", size = "40", icon, counterValue, disabled = false, ...props }, ref) => {
34
+ return /* @__PURE__ */ jsxs(
35
+ "button",
36
+ {
37
+ ref,
38
+ type: "button",
39
+ "data-testid": "icon-button",
40
+ disabled,
41
+ className: cn(
42
+ // Base styles
43
+ "relative inline-flex shrink-0 items-center justify-center focus-visible:outline-none",
44
+ "cursor-pointer rounded-full transition-all duration-150 ease-in-out disabled:cursor-default",
45
+ // Size variants
46
+ sizeVariants[size],
47
+ // Variant styles
48
+ iconButtonVariants[variant],
49
+ // Manual CSS overrides
50
+ className
51
+ ),
52
+ ...props,
53
+ children: [
54
+ /* @__PURE__ */ jsx(
55
+ "span",
56
+ {
57
+ className: cn(
58
+ "flex shrink-0 items-center justify-center overflow-clip",
59
+ iconSizeVariants[size]
60
+ ),
61
+ "aria-hidden": "true",
62
+ children: icon
63
+ }
64
+ ),
65
+ counterValue !== void 0 && (variant === "tertiary" || variant === "navTray") && /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0", children: /* @__PURE__ */ jsx(Count, { value: counterValue }) })
66
+ ]
67
+ }
68
+ );
69
+ }
70
+ );
71
+ IconButton.displayName = "IconButton";
72
+ export {
73
+ IconButton
74
+ };
75
+ //# sourceMappingURL=IconButton.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconButton.mjs","sources":["../../../src/components/IconButton/IconButton.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Count } from \"../Count/Count\";\n\nconst iconButtonVariants = {\n primary:\n \"bg-neutral-400 text-body-300 hover:bg-hover-100 disabled:opacity-50 focus:shadow-focus-ring\",\n secondary: `bg-neutral-100 text-neutral-400 hover:bg-neutral-200 disabled:opacity-50 focus:focus:shadow-focus-ring`,\n tertiary: `bg-transparent text-neutral-400 hover:bg-hover-300 disabled:opacity-50 focus:shadow-focus-ring active:bg-brand-green-50`,\n brand: `bg-body-black-solid-constant text-brand-green-500 hover:bg-brand-green-500 hover:text-body-black-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,\n contrast: `bg-transparent text-body-white-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,\n messaging: `bg-body-black-solid-constant text-brand-green-500 hover:bg-brand-green-500 hover:text-body-black-solid-constant disabled:opacity-50 focus:shadow-focus-ring`,\n navTray: `bg-transparent text-neutral-400 disabled:opacity-50 focus:shadow-focus-ring active:bg-brand-green-50`,\n tertiaryDestructive: `bg-transparent text-error-500 hover:bg-hover-300 disabled:opacity-50 focus:shadow-focus-ring`,\n stop: `bg-neutral-400 text-body-300 hover:bg-brand-green-500 hover:text-body-black-solid-constant`,\n microphone: `bg-neutral-400 text-body-300 hover:bg-brand-green-500 hover:text-body-black-solid-constant`,\n};\n\nconst iconSizeVariants = {\n 24: \"size-4\",\n 32: \"size-5\",\n 40: \"size-6\",\n 52: \"size-7\",\n 72: \"size-8\",\n} as const;\n\nconst sizeVariants = {\n 24: \"p-1\",\n 32: \"p-1.5\",\n 40: \"p-[10px]\",\n 52: \"p-2\",\n 72: \"p-4\",\n} as const;\n\nexport type IconButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"brand\"\n | \"contrast\"\n | \"messaging\"\n | \"navTray\"\n | \"tertiaryDestructive\"\n | \"stop\"\n | \"microphone\";\n\nexport type IconButtonSize = \"24\" | \"32\" | \"40\" | \"52\" | \"72\";\n\nexport interface IconButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"style\"> {\n /** Visual style variant of the icon button */\n variant?: IconButtonVariant;\n /** Size of the button */\n size?: IconButtonSize;\n /** Icon element to display */\n icon: React.ReactNode;\n /** Counter value to display */\n counterValue?: number;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n (\n { className, variant = \"primary\", size = \"40\", icon, counterValue, disabled = false, ...props },\n ref,\n ) => {\n return (\n <button\n ref={ref}\n type=\"button\"\n data-testid=\"icon-button\"\n disabled={disabled}\n className={cn(\n // Base styles\n \"relative inline-flex shrink-0 items-center justify-center focus-visible:outline-none\",\n \"cursor-pointer rounded-full transition-all duration-150 ease-in-out disabled:cursor-default\",\n // Size variants\n sizeVariants[size],\n // Variant styles\n iconButtonVariants[variant],\n // Manual CSS overrides\n className,\n )}\n {...props}\n >\n <span\n className={cn(\n \"flex shrink-0 items-center justify-center overflow-clip\",\n iconSizeVariants[size],\n )}\n aria-hidden=\"true\"\n >\n {icon}\n </span>\n\n {counterValue !== undefined && (variant === \"tertiary\" || variant === \"navTray\") && (\n <div className=\"absolute top-0 right-0\">\n <Count value={counterValue} />\n </div>\n )}\n </button>\n );\n },\n);\n\nIconButton.displayName = \"IconButton\";\n"],"names":[],"mappings":";;;;;AAIA,MAAM,qBAAqB;AAAA,EACzB,SACE;AAAA,EACF,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,MAAM;AAAA,EACN,YAAY;AACd;AAEA,MAAM,mBAAmB;AAAA,EACvB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,MAAM,eAAe;AAAA,EACnB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AA4BO,MAAM,aAAa,MAAM;AAAA,EAC9B,CACE,EAAE,WAAW,UAAU,WAAW,OAAO,MAAM,MAAM,cAAc,WAAW,OAAO,GAAG,MAAA,GACxF,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,eAAY;AAAA,QACZ;AAAA,QACA,WAAW;AAAA;AAAA,UAET;AAAA,UACA;AAAA;AAAA,UAEA,aAAa,IAAI;AAAA;AAAA,UAEjB,mBAAmB,OAAO;AAAA;AAAA,UAE1B;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,iBAAiB,IAAI;AAAA,cAAA;AAAA,cAEvB,eAAY;AAAA,cAEX,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGF,iBAAiB,WAAc,YAAY,cAAc,YAAY,cACpE,oBAAC,OAAA,EAAI,WAAU,0BACb,UAAA,oBAAC,OAAA,EAAM,OAAO,cAAc,EAAA,CAC9B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,WAAW,cAAc;"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../utils/cn.mjs";
5
+ const ArrowRightIcon = React.forwardRef(
6
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7
+ "svg",
8
+ {
9
+ ref,
10
+ viewBox: "0 0 20 20",
11
+ fill: "currentColor",
12
+ "aria-hidden": "true",
13
+ className: cn("size-5", className),
14
+ ...props,
15
+ children: /* @__PURE__ */ jsx(
16
+ "path",
17
+ {
18
+ fillRule: "evenodd",
19
+ d: "M3 10a.75.75 0 0 1 .75-.75h10.638L10.23 5.29a.75.75 0 1 1 1.04-1.08l5.5 5.25a.75.75 0 0 1 0 1.08l-5.5 5.25a.75.75 0 1 1-1.04-1.08l4.158-3.96H3.75A.75.75 0 0 1 3 10Z",
20
+ clipRule: "evenodd"
21
+ }
22
+ )
23
+ }
24
+ )
25
+ );
26
+ ArrowRightIcon.displayName = "ArrowRightIcon";
27
+ export {
28
+ ArrowRightIcon
29
+ };
30
+ //# sourceMappingURL=ArrowRightIcon.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArrowRightIcon.mjs","sources":["../../../src/components/Icons/ArrowRightIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const ArrowRightIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n className={cn(\"size-5\", className)}\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M3 10a.75.75 0 0 1 .75-.75h10.638L10.23 5.29a.75.75 0 1 1 1.04-1.08l5.5 5.25a.75.75 0 0 1 0 1.08l-5.5 5.25a.75.75 0 1 1-1.04-1.08l4.158-3.96H3.75A.75.75 0 0 1 3 10Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n ),\n);\n\nArrowRightIcon.displayName = \"ArrowRightIcon\";\n"],"names":[],"mappings":";;;;AAIO,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACxB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,UAAU,SAAS;AAAA,MAChC,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,UAAS;AAAA,UACT,GAAE;AAAA,UACF,UAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IACX;AAAA,EAAA;AAGN;AAEA,eAAe,cAAc;"}