@raydenui/ui 0.9.7 → 0.10.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 (309) hide show
  1. package/README.md +124 -49
  2. package/dist/Table-DCNSxua1.d.cts +31 -0
  3. package/dist/Table-DCNSxua1.d.ts +31 -0
  4. package/dist/blocks/ApplicationShellBlock.cjs +157 -0
  5. package/dist/blocks/ApplicationShellBlock.js +154 -0
  6. package/dist/blocks/CheckoutReviewBlock.cjs +16 -0
  7. package/dist/blocks/CheckoutReviewBlock.js +13 -0
  8. package/dist/blocks/CommandPaletteBlock.cjs +334 -0
  9. package/dist/blocks/CommandPaletteBlock.js +331 -0
  10. package/dist/blocks/CreateAccountBlock.cjs +147 -0
  11. package/dist/blocks/CreateAccountBlock.js +143 -0
  12. package/dist/blocks/EmptyStateBlock.cjs +19 -0
  13. package/dist/blocks/EmptyStateBlock.js +16 -0
  14. package/dist/blocks/FeatureOverviewBlock.cjs +54 -0
  15. package/dist/blocks/FeatureOverviewBlock.js +51 -0
  16. package/dist/blocks/HeaderBlock.cjs +230 -0
  17. package/dist/blocks/HeaderBlock.js +227 -0
  18. package/dist/blocks/KpiOverviewBlock.cjs +63 -0
  19. package/dist/blocks/KpiOverviewBlock.js +60 -0
  20. package/dist/blocks/LoginBlock.cjs +66 -0
  21. package/dist/blocks/LoginBlock.js +63 -0
  22. package/dist/blocks/NotificationsBlock.cjs +17 -0
  23. package/dist/blocks/NotificationsBlock.js +14 -0
  24. package/dist/blocks/PageHeaderBlock.cjs +121 -0
  25. package/dist/blocks/PageHeaderBlock.js +118 -0
  26. package/dist/blocks/PricingPlansBlock.cjs +146 -0
  27. package/dist/blocks/PricingPlansBlock.js +143 -0
  28. package/dist/blocks/ProductCollectionBlock.cjs +37 -0
  29. package/dist/blocks/ProductCollectionBlock.js +34 -0
  30. package/dist/blocks/ProductDetailBlock.cjs +30 -0
  31. package/dist/blocks/ProductDetailBlock.js +27 -0
  32. package/dist/blocks/ProductHeroBlock.cjs +83 -0
  33. package/dist/blocks/ProductHeroBlock.js +80 -0
  34. package/dist/blocks/ProfileSettingsBlock.cjs +130 -0
  35. package/dist/blocks/ProfileSettingsBlock.js +126 -0
  36. package/dist/blocks/QuickSendBlock.cjs +11 -0
  37. package/dist/blocks/QuickSendBlock.js +8 -0
  38. package/dist/blocks/RecentTransactionsBlock.cjs +13 -0
  39. package/dist/blocks/RecentTransactionsBlock.js +10 -0
  40. package/dist/blocks/SearchableTableBlock.cjs +91 -0
  41. package/dist/blocks/SearchableTableBlock.js +88 -0
  42. package/dist/blocks/ShoppingCartBlock.cjs +16 -0
  43. package/dist/blocks/ShoppingCartBlock.js +13 -0
  44. package/dist/blocks/SiteFooterBlock.cjs +69 -0
  45. package/dist/blocks/SiteFooterBlock.js +66 -0
  46. package/dist/blocks/TableBlock.cjs +20 -0
  47. package/dist/blocks/TableBlock.js +17 -0
  48. package/dist/blocks/TaskListBlock.cjs +198 -0
  49. package/dist/blocks/TaskListBlock.js +195 -0
  50. package/dist/blocks/WorkspaceSwitcherBlock.cjs +291 -0
  51. package/dist/blocks/WorkspaceSwitcherBlock.js +288 -0
  52. package/dist/blocks/commerce.cjs +44 -0
  53. package/dist/blocks/commerce.js +35 -0
  54. package/dist/blocks/index.cjs +53 -0
  55. package/dist/blocks/index.js +24 -0
  56. package/dist/blocks.d.cts +1820 -0
  57. package/dist/blocks.d.ts +1820 -0
  58. package/dist/chart.cjs +13 -0
  59. package/dist/chart.d.cts +59 -0
  60. package/dist/chart.d.ts +59 -0
  61. package/dist/chart.js +5 -0
  62. package/dist/components/Accordion/Accordion.cjs +94 -0
  63. package/dist/components/Accordion/Accordion.js +91 -0
  64. package/dist/components/Accordion/index.cjs +8 -0
  65. package/dist/components/Accordion/index.js +1 -0
  66. package/dist/components/ActivityFeed/ActivityContent.cjs +40 -0
  67. package/dist/components/ActivityFeed/ActivityContent.js +37 -0
  68. package/dist/components/ActivityFeed/ActivityItem.cjs +19 -0
  69. package/dist/components/ActivityFeed/ActivityItem.js +16 -0
  70. package/dist/components/ActivityFeed/index.cjs +7 -0
  71. package/dist/components/ActivityFeed/index.js +2 -0
  72. package/dist/components/Alert/Alert.cjs +42 -0
  73. package/dist/components/Alert/Alert.js +39 -0
  74. package/dist/components/Alert/index.cjs +5 -0
  75. package/dist/components/Alert/index.js +1 -0
  76. package/dist/components/Avatar/Avatar.cjs +101 -0
  77. package/dist/components/Avatar/Avatar.js +98 -0
  78. package/dist/components/Avatar/index.cjs +6 -0
  79. package/dist/components/Avatar/index.js +1 -0
  80. package/dist/components/Badge/Badge.cjs +53 -0
  81. package/dist/components/Badge/Badge.js +50 -0
  82. package/dist/components/Badge/index.cjs +5 -0
  83. package/dist/components/Badge/index.js +1 -0
  84. package/dist/components/Banner/Banner.cjs +83 -0
  85. package/dist/components/Banner/Banner.js +80 -0
  86. package/dist/components/Banner/index.cjs +5 -0
  87. package/dist/components/Banner/index.js +1 -0
  88. package/dist/components/Breadcrumb/Breadcrumb.cjs +31 -0
  89. package/dist/components/Breadcrumb/Breadcrumb.js +28 -0
  90. package/dist/components/Breadcrumb/index.cjs +5 -0
  91. package/dist/components/Breadcrumb/index.js +1 -0
  92. package/dist/components/Button/Button.cjs +88 -0
  93. package/dist/components/Button/Button.js +85 -0
  94. package/dist/components/Button/index.cjs +5 -0
  95. package/dist/components/Button/index.js +1 -0
  96. package/dist/components/ButtonGroup/ButtonGroup.cjs +8 -0
  97. package/dist/components/ButtonGroup/ButtonGroup.js +5 -0
  98. package/dist/components/ButtonGroup/ButtonGroupItem.cjs +15 -0
  99. package/dist/components/ButtonGroup/ButtonGroupItem.js +12 -0
  100. package/dist/components/ButtonGroup/index.cjs +7 -0
  101. package/dist/components/ButtonGroup/index.js +2 -0
  102. package/dist/components/Card/Card.cjs +94 -0
  103. package/dist/components/Card/Card.js +91 -0
  104. package/dist/components/Card/index.cjs +9 -0
  105. package/dist/components/Card/index.js +1 -0
  106. package/dist/components/Chart/Chart.cjs +160 -0
  107. package/dist/components/Chart/Chart.js +153 -0
  108. package/dist/components/Chart/index.cjs +10 -0
  109. package/dist/components/Chart/index.js +2 -0
  110. package/dist/components/Chart/theme.cjs +67 -0
  111. package/dist/components/Chart/theme.js +62 -0
  112. package/dist/components/Chip/Chip.cjs +18 -0
  113. package/dist/components/Chip/Chip.js +15 -0
  114. package/dist/components/Chip/index.cjs +5 -0
  115. package/dist/components/Chip/index.js +1 -0
  116. package/dist/components/Counter/Counter.cjs +74 -0
  117. package/dist/components/Counter/Counter.js +71 -0
  118. package/dist/components/Counter/index.cjs +6 -0
  119. package/dist/components/Counter/index.js +1 -0
  120. package/dist/components/DatePicker/DatePicker.cjs +343 -0
  121. package/dist/components/DatePicker/DatePicker.js +340 -0
  122. package/dist/components/DatePicker/index.cjs +5 -0
  123. package/dist/components/DatePicker/index.js +1 -0
  124. package/dist/components/Divider/Divider.cjs +31 -0
  125. package/dist/components/Divider/Divider.js +28 -0
  126. package/dist/components/Divider/index.cjs +5 -0
  127. package/dist/components/Divider/index.js +1 -0
  128. package/dist/components/DropdownMenu/DropdownMenu.cjs +108 -0
  129. package/dist/components/DropdownMenu/DropdownMenu.js +105 -0
  130. package/dist/components/DropdownMenu/index.cjs +11 -0
  131. package/dist/components/DropdownMenu/index.js +1 -0
  132. package/dist/components/EmptyStateIllustration/EmptyStateIllustration.cjs +42 -0
  133. package/dist/components/EmptyStateIllustration/EmptyStateIllustration.js +39 -0
  134. package/dist/components/EmptyStateIllustration/illustrations.cjs +3322 -0
  135. package/dist/components/EmptyStateIllustration/illustrations.js +3319 -0
  136. package/dist/components/EmptyStateIllustration/index.cjs +7 -0
  137. package/dist/components/EmptyStateIllustration/index.js +2 -0
  138. package/dist/components/FileUpload/FileUpload.cjs +116 -0
  139. package/dist/components/FileUpload/FileUpload.js +113 -0
  140. package/dist/components/FileUpload/FileUploadDropZone.cjs +58 -0
  141. package/dist/components/FileUpload/FileUploadDropZone.js +55 -0
  142. package/dist/components/FileUpload/FileUploadIcons.cjs +55 -0
  143. package/dist/components/FileUpload/FileUploadIcons.js +50 -0
  144. package/dist/components/FileUpload/FileUploadItem.cjs +34 -0
  145. package/dist/components/FileUpload/FileUploadItem.js +31 -0
  146. package/dist/components/FileUpload/index.cjs +9 -0
  147. package/dist/components/FileUpload/index.js +3 -0
  148. package/dist/components/FormControl/Checkbox.cjs +27 -0
  149. package/dist/components/FormControl/Checkbox.js +24 -0
  150. package/dist/components/FormControl/Radio.cjs +15 -0
  151. package/dist/components/FormControl/Radio.js +12 -0
  152. package/dist/components/FormControl/Toggle.cjs +15 -0
  153. package/dist/components/FormControl/Toggle.js +12 -0
  154. package/dist/components/FormControl/index.cjs +9 -0
  155. package/dist/components/FormControl/index.js +3 -0
  156. package/dist/components/Icon/Icon.cjs +70 -0
  157. package/dist/components/Icon/Icon.js +34 -0
  158. package/dist/components/Icon/catalog.cjs +1672 -0
  159. package/dist/components/Icon/catalog.js +1669 -0
  160. package/dist/components/Icon/icons.cjs +5621 -0
  161. package/dist/components/Icon/icons.js +5610 -0
  162. package/dist/components/Icon/index.cjs +8 -0
  163. package/dist/components/Icon/index.js +2 -0
  164. package/dist/components/Input/Input.cjs +64 -0
  165. package/dist/components/Input/Input.js +61 -0
  166. package/dist/components/Input/index.cjs +5 -0
  167. package/dist/components/Input/index.js +1 -0
  168. package/dist/components/MetricsCard/MetricsCard.cjs +107 -0
  169. package/dist/components/MetricsCard/MetricsCard.js +104 -0
  170. package/dist/components/MetricsCard/index.cjs +5 -0
  171. package/dist/components/MetricsCard/index.js +1 -0
  172. package/dist/components/Modal/Modal.cjs +126 -0
  173. package/dist/components/Modal/Modal.js +123 -0
  174. package/dist/components/Modal/index.cjs +5 -0
  175. package/dist/components/Modal/index.js +1 -0
  176. package/dist/components/Pagination/Pagination.cjs +42 -0
  177. package/dist/components/Pagination/Pagination.js +39 -0
  178. package/dist/components/Pagination/index.cjs +5 -0
  179. package/dist/components/Pagination/index.js +1 -0
  180. package/dist/components/ProgressBar/ProgressBar.cjs +34 -0
  181. package/dist/components/ProgressBar/ProgressBar.js +31 -0
  182. package/dist/components/ProgressBar/index.cjs +5 -0
  183. package/dist/components/ProgressBar/index.js +1 -0
  184. package/dist/components/ProgressCircle/ProgressCircle.cjs +34 -0
  185. package/dist/components/ProgressCircle/ProgressCircle.js +31 -0
  186. package/dist/components/ProgressCircle/index.cjs +5 -0
  187. package/dist/components/ProgressCircle/index.js +1 -0
  188. package/dist/components/Select/Select.cjs +84 -0
  189. package/dist/components/Select/Select.js +80 -0
  190. package/dist/components/Select/SelectOption.cjs +26 -0
  191. package/dist/components/Select/SelectOption.js +23 -0
  192. package/dist/components/Select/index.cjs +7 -0
  193. package/dist/components/Select/index.js +2 -0
  194. package/dist/components/SidebarMenu/SidebarMenu.cjs +85 -0
  195. package/dist/components/SidebarMenu/SidebarMenu.js +81 -0
  196. package/dist/components/SidebarMenu/SidebarMenuItem.cjs +126 -0
  197. package/dist/components/SidebarMenu/SidebarMenuItem.js +122 -0
  198. package/dist/components/SidebarMenu/SidebarMenuSection.cjs +14 -0
  199. package/dist/components/SidebarMenu/SidebarMenuSection.js +11 -0
  200. package/dist/components/SidebarMenu/index.cjs +12 -0
  201. package/dist/components/SidebarMenu/index.js +4 -0
  202. package/dist/components/Slider/Slider.cjs +161 -0
  203. package/dist/components/Slider/Slider.js +158 -0
  204. package/dist/components/Slider/index.cjs +6 -0
  205. package/dist/components/Slider/index.js +1 -0
  206. package/dist/components/Spinner/Spinner.cjs +93 -0
  207. package/dist/components/Spinner/Spinner.js +90 -0
  208. package/dist/components/Spinner/index.cjs +5 -0
  209. package/dist/components/Spinner/index.js +1 -0
  210. package/dist/components/Stepper/Stepper.cjs +82 -0
  211. package/dist/components/Stepper/Stepper.js +79 -0
  212. package/dist/components/Stepper/index.cjs +7 -0
  213. package/dist/components/Stepper/index.js +1 -0
  214. package/dist/components/Table/Table.cjs +25 -0
  215. package/dist/components/Table/Table.js +22 -0
  216. package/dist/components/Table/index.cjs +10 -0
  217. package/dist/components/Table/index.js +1 -0
  218. package/dist/components/Table/useTableSelection.cjs +60 -0
  219. package/dist/components/Table/useTableSelection.js +57 -0
  220. package/dist/components/Tabs/Tab.cjs +70 -0
  221. package/dist/components/Tabs/Tab.js +67 -0
  222. package/dist/components/Tabs/Tabs.cjs +133 -0
  223. package/dist/components/Tabs/Tabs.js +129 -0
  224. package/dist/components/Tabs/index.cjs +7 -0
  225. package/dist/components/Tabs/index.js +2 -0
  226. package/dist/components/Tooltip/Tooltip.cjs +101 -0
  227. package/dist/components/Tooltip/Tooltip.js +98 -0
  228. package/dist/components/Tooltip/index.cjs +5 -0
  229. package/dist/components/Tooltip/index.js +1 -0
  230. package/dist/context/ThemeContext.cjs +97 -0
  231. package/dist/context/ThemeContext.js +92 -0
  232. package/dist/fonts/README.md +13 -0
  233. package/dist/fonts/hanken-grotesk-cyrillic-ext-italic.woff2 +0 -0
  234. package/dist/fonts/hanken-grotesk-cyrillic-ext-normal.woff2 +0 -0
  235. package/dist/fonts/hanken-grotesk-latin-ext-italic.woff2 +0 -0
  236. package/dist/fonts/hanken-grotesk-latin-ext-normal.woff2 +0 -0
  237. package/dist/fonts/hanken-grotesk-latin-italic.woff2 +0 -0
  238. package/dist/fonts/hanken-grotesk-latin-normal.woff2 +0 -0
  239. package/dist/fonts/hanken-grotesk-vietnamese-italic.woff2 +0 -0
  240. package/dist/fonts/hanken-grotesk-vietnamese-normal.woff2 +0 -0
  241. package/dist/fonts/hankengrotesk-LICENSE.txt +94 -0
  242. package/dist/fonts/manrope-LICENSE.txt +93 -0
  243. package/dist/fonts/manrope-cyrillic-ext-normal.woff2 +0 -0
  244. package/dist/fonts/manrope-cyrillic-normal.woff2 +0 -0
  245. package/dist/fonts/manrope-greek-normal.woff2 +0 -0
  246. package/dist/fonts/manrope-latin-ext-normal.woff2 +0 -0
  247. package/dist/fonts/manrope-latin-normal.woff2 +0 -0
  248. package/dist/fonts/manrope-vietnamese-normal.woff2 +0 -0
  249. package/dist/fonts.css +148 -0
  250. package/dist/hooks/form/index.cjs +11 -0
  251. package/dist/hooks/form/index.js +3 -0
  252. package/dist/hooks/form/useRaydenFormControl.cjs +81 -0
  253. package/dist/hooks/form/useRaydenFormControl.js +76 -0
  254. package/dist/hooks/form/useRaydenInput.cjs +38 -0
  255. package/dist/hooks/form/useRaydenInput.js +35 -0
  256. package/dist/hooks/form/useRaydenSelect.cjs +45 -0
  257. package/dist/hooks/form/useRaydenSelect.js +42 -0
  258. package/dist/hooks/index.cjs +17 -0
  259. package/dist/hooks/index.js +1 -0
  260. package/dist/hooks/useBodyScrollLock.cjs +24 -0
  261. package/dist/hooks/useBodyScrollLock.js +21 -0
  262. package/dist/hooks/useCollisionAwareSide.cjs +72 -0
  263. package/dist/hooks/useCollisionAwareSide.js +69 -0
  264. package/dist/hooks/useControllableValue.cjs +16 -0
  265. package/dist/hooks/useControllableValue.js +13 -0
  266. package/dist/hooks/useDismissableLayer.cjs +100 -0
  267. package/dist/hooks/useDismissableLayer.js +97 -0
  268. package/dist/hooks/usePopupList.cjs +101 -0
  269. package/dist/hooks/usePopupList.js +98 -0
  270. package/dist/icons-8yD7I5jO.d.cts +430 -0
  271. package/dist/icons-8yD7I5jO.d.ts +430 -0
  272. package/dist/icons.cjs +2111 -418
  273. package/dist/icons.d.cts +1256 -429
  274. package/dist/icons.d.ts +1256 -429
  275. package/dist/icons.js +2089 -1
  276. package/dist/index.cjs +128 -15046
  277. package/dist/index.d.cts +697 -662
  278. package/dist/index.d.ts +697 -662
  279. package/dist/index.js +43 -14962
  280. package/dist/motion/Collapse.cjs +28 -0
  281. package/dist/motion/Collapse.js +25 -0
  282. package/dist/motion/MotionProvider.cjs +43 -0
  283. package/dist/motion/MotionProvider.js +38 -0
  284. package/dist/motion/Pressable.cjs +46 -0
  285. package/dist/motion/Pressable.js +43 -0
  286. package/dist/motion/Reveal.cjs +19 -0
  287. package/dist/motion/Reveal.js +16 -0
  288. package/dist/motion/SharedLayout.cjs +46 -0
  289. package/dist/motion/SharedLayout.js +43 -0
  290. package/dist/motion/index.cjs +19 -0
  291. package/dist/motion/index.js +6 -0
  292. package/dist/motion/presence.cjs +58 -0
  293. package/dist/motion/presence.js +55 -0
  294. package/dist/motion/presets.cjs +88 -0
  295. package/dist/motion/presets.js +84 -0
  296. package/dist/motion.d.cts +51 -0
  297. package/dist/motion.d.ts +51 -0
  298. package/dist/preset.cjs +356 -195
  299. package/dist/preset.d.cts +111 -32
  300. package/dist/preset.d.ts +111 -32
  301. package/dist/preset.js +353 -187
  302. package/dist/presets-Ba5QndHg.d.cts +144 -0
  303. package/dist/presets-Ba5QndHg.d.ts +144 -0
  304. package/dist/styles.css +1 -1
  305. package/dist/utils/cn.cjs +38 -0
  306. package/dist/utils/cn.js +35 -0
  307. package/dist/utils/resolveIcon.cjs +18 -0
  308. package/dist/utils/resolveIcon.js +15 -0
  309. package/package.json +79 -21
@@ -0,0 +1,123 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useBodyScrollLock } from "../../hooks/useBodyScrollLock.js";
3
+ import { forwardRef, useCallback, useEffect, useId, useLayoutEffect, useRef, useState, } from "react";
4
+ import { createPortal } from "react-dom";
5
+ import { cn } from "../../utils/cn.js";
6
+ import { resolveIcon } from "../../utils/resolveIcon.js";
7
+ import { Button } from "../Button/index.js";
8
+ import { useMotionPresence } from "../../motion/presence.js";
9
+ const useBrowserLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
10
+ /* ─── Icons ────────────────────────────────────────────────────────────── */
11
+ function CloseIcon({ className }) {
12
+ return (_jsx("svg", { className: className, viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M9 3L3 9M3 3l6 6" }) }));
13
+ }
14
+ function BoxIcon({ className }) {
15
+ return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M2.67 4.67L8 7.33l5.33-2.66M8 14V7.33" }), _jsx("path", { d: "M13.33 10.67V5.33a1.33 1.33 0 00-.66-1.15L8.67 2a1.33 1.33 0 00-1.34 0L3.33 4.18A1.33 1.33 0 002.67 5.33v5.34a1.33 1.33 0 00.66 1.15L7.33 14a1.33 1.33 0 001.34 0l4-2.18a1.33 1.33 0 00.66-1.15z" })] }));
16
+ }
17
+ /* ─── Size Config ──────────────────────────────────────────────────────── */
18
+ const sizeClasses = {
19
+ sm: "w-full max-w-[400px]",
20
+ md: "w-full max-w-[500px]",
21
+ lg: "w-full max-w-[640px]",
22
+ };
23
+ /* ─── Modal ────────────────────────────────────────────────────────────── */
24
+ export const Modal = forwardRef(({ open, motion = false, onClose, size = "sm", title, description, icon, showClose = true,
25
+ // Defaulted only when there is something for it to do; an inert "Save"
26
+ // used to render whenever the footer appeared.
27
+ primaryLabel: primaryLabelProp, onPrimaryClick, secondaryLabel, onSecondaryClick, footerOrientation = "horizontal", closeOnOverlay = true, closeOnEscape = true, blur = true, children, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }, ref) => {
28
+ const overlayRef = useRef(null);
29
+ const anchorRef = useRef(null);
30
+ const panelRef = useRef(null);
31
+ const titleId = useId();
32
+ const descriptionId = useId();
33
+ // The portal target only exists in a browser; defer it so an initially
34
+ // open modal can be server-rendered without touching document.
35
+ const [mounted, setMounted] = useState(false);
36
+ useEffect(() => setMounted(true), []);
37
+ const { present, preset } = useMotionPresence(open, panelRef, motion, "overlay.pop", mounted);
38
+ // Native modal dialogs contain focus and make the background inert.
39
+ useBrowserLayoutEffect(() => {
40
+ const dialog = overlayRef.current;
41
+ if (!present || !dialog)
42
+ return;
43
+ const trigger = document.activeElement instanceof HTMLElement ? document.activeElement : null;
44
+ dialog.showModal();
45
+ return () => {
46
+ dialog.close();
47
+ if (trigger?.isConnected)
48
+ trigger.focus({ preventScroll: true });
49
+ };
50
+ }, [present, mounted]);
51
+ // ── #30: the portal escapes the provider, so its theme class is copied in.
52
+ // Copying once on open left an open dialog stuck in the old theme when the
53
+ // app switched; observe the source element and re-sync on every change.
54
+ useBrowserLayoutEffect(() => {
55
+ const dialog = overlayRef.current;
56
+ if (!present || !dialog)
57
+ return;
58
+ const source = anchorRef.current?.closest(".rayden-light, .dark");
59
+ if (!source)
60
+ return;
61
+ const sync = () => {
62
+ const isLight = source.classList.contains("rayden-light");
63
+ dialog.classList.toggle("rayden-light", isLight);
64
+ dialog.classList.toggle("dark", !isLight);
65
+ };
66
+ sync();
67
+ const observer = new MutationObserver(sync);
68
+ observer.observe(source, { attributes: true, attributeFilter: ["class"] });
69
+ // The theme may also move to a different ancestor, e.g. the documentElement.
70
+ if (source !== document.documentElement)
71
+ observer.observe(document.documentElement, {
72
+ attributes: true,
73
+ attributeFilter: ["class"],
74
+ });
75
+ return () => observer.disconnect();
76
+ }, [present, mounted]);
77
+ useBodyScrollLock(present && mounted);
78
+ const handleOverlayClick = useCallback((e) => {
79
+ if (open && closeOnOverlay && e.target === overlayRef.current)
80
+ onClose();
81
+ }, [open, closeOnOverlay, onClose]);
82
+ if (!present || !mounted)
83
+ return null;
84
+ const primaryLabel = primaryLabelProp ?? (onPrimaryClick ? "Save" : undefined);
85
+ const showPrimary = !!primaryLabel;
86
+ const showSecondary = !!secondaryLabel;
87
+ const isVertical = footerOrientation === "vertical";
88
+ const modal = (_jsx("dialog", { ref: overlayRef, "data-rayden-motion": motion ? preset : undefined, "data-state": open ? "open" : "closed", "aria-label": ariaLabel ?? (!title && !ariaLabelledBy ? "Dialog" : undefined), "aria-labelledby": ariaLabelledBy ?? (title ? titleId : undefined), "aria-describedby": ariaDescribedBy ?? (description ? descriptionId : undefined), className: cn("fixed inset-0 m-0 h-dvh w-screen max-h-none max-w-none border-0 bg-transparent p-4 open:flex items-center justify-center backdrop:bg-black/60", blur && "backdrop:backdrop-blur-md"), onCancel: (event) => {
89
+ event.preventDefault();
90
+ if (open && closeOnEscape)
91
+ onClose();
92
+ }, onKeyDown: (event) => {
93
+ if (event.key !== "Tab")
94
+ return;
95
+ const dialog = event.currentTarget;
96
+ const focusable = Array.from(dialog.querySelectorAll('a[href], button, input, select, textarea, [tabindex], [contenteditable="true"]')).filter((element) => element.tabIndex >= 0 &&
97
+ !element.matches(":disabled") &&
98
+ !element.closest("[inert]") &&
99
+ element.getClientRects().length > 0 &&
100
+ getComputedStyle(element).visibility !== "hidden");
101
+ const first = focusable[0];
102
+ const last = focusable[focusable.length - 1];
103
+ if (!first || !last) {
104
+ event.preventDefault();
105
+ dialog.firstElementChild?.focus();
106
+ }
107
+ else if (!focusable.includes(document.activeElement) ||
108
+ (event.shiftKey ? document.activeElement === first : document.activeElement === last)) {
109
+ event.preventDefault();
110
+ (event.shiftKey ? last : first).focus();
111
+ }
112
+ }, onClick: handleOverlayClick, children: _jsxs("div", { ref: (element) => {
113
+ panelRef.current = element;
114
+ if (typeof ref === "function")
115
+ ref(element);
116
+ else if (ref)
117
+ ref.current = element;
118
+ }, tabIndex: -1, className: cn("relative flex max-h-[calc(100dvh-2rem)] flex-col bg-surface rounded-xl shadow-soft-xl overflow-hidden", sizeClasses[size], className), ...rest, children: [(title || showClose) && (_jsxs("div", { className: "flex items-start gap-2 pt-5 pb-2 px-4", children: [_jsxs("div", { className: "flex flex-1 gap-4 items-start min-w-0", children: [icon !== undefined ? (_jsx("span", { className: "shrink-0 flex items-center justify-center p-2.5 bg-primary-50 rounded-[20px]", children: _jsx("span", { className: "size-4", children: resolveIcon(icon, "sm") }) })) : title ? (_jsx("span", { className: "shrink-0 flex items-center justify-center p-2.5 bg-primary-50 rounded-[20px]", children: _jsx(BoxIcon, { className: "size-4 text-primary-400" }) })) : null, _jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [title && (_jsx("h2", { id: titleId, className: "text-xl font-semibold text-on-surface-body leading-[1.2] tracking-[-0.4px]", children: title })), description && !!(title || showClose) && (_jsx("p", { id: descriptionId, className: "text-sm text-on-surface-muted leading-[1.45]", children: description }))] })] }), showClose && (_jsx("button", { type: "button", onClick: onClose, "aria-label": "Close modal", className: "shrink-0 flex items-center justify-center p-2 bg-grey-75 text-grey-700 rounded-xl hover:bg-grey-200 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-text", children: _jsx(CloseIcon, { className: "size-3" }) }))] })), description && !title && !showClose && (_jsx("p", { id: descriptionId, className: "px-4 pt-5 text-sm text-on-surface-muted leading-[1.45]", children: description })), children && _jsx("div", { className: "min-h-0 flex-1 px-4 py-4 overflow-y-auto", children: children }), (showPrimary || showSecondary) && (_jsxs("div", { className: cn("py-5", isVertical
119
+ ? "flex flex-col gap-5 items-center px-4"
120
+ : "flex items-center justify-end gap-3 px-4"), children: [showSecondary && !isVertical && (_jsx(Button, { variant: "secondary", onClick: onSecondaryClick ?? onClose, type: "button", children: secondaryLabel })), showPrimary && (_jsx(Button, { type: "button", onClick: onPrimaryClick, className: isVertical ? "w-full" : undefined, children: primaryLabel })), showSecondary && isVertical && (_jsx(Button, { variant: "secondary", onClick: onSecondaryClick ?? onClose, type: "button", className: "w-full", children: secondaryLabel }))] }))] }) }));
121
+ return (_jsxs(_Fragment, { children: [_jsx("span", { ref: anchorRef, hidden: true }), createPortal(modal, document.body)] }));
122
+ });
123
+ Modal.displayName = "Modal";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Modal = void 0;
4
+ var Modal_1 = require("./Modal.cjs");
5
+ Object.defineProperty(exports, "Modal", { enumerable: true, get: function () { return Modal_1.Modal; } });
@@ -0,0 +1 @@
1
+ export { Modal } from "./Modal.js";
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Pagination = Pagination;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../../utils/cn.cjs");
6
+ const Icon_1 = require("../Icon/index.cjs");
7
+ function range(start, end) {
8
+ const arr = [];
9
+ for (let i = start; i <= end; i++)
10
+ arr.push(i);
11
+ return arr;
12
+ }
13
+ function getPageNumbers(currentPage, totalPages, siblingCount) {
14
+ const totalNumbers = siblingCount * 2 + 5; // siblings + first + last + current + 2 dots
15
+ if (totalPages <= totalNumbers) {
16
+ return range(1, totalPages);
17
+ }
18
+ const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
19
+ const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPages);
20
+ const showLeftDots = leftSiblingIndex > 2;
21
+ const showRightDots = rightSiblingIndex < totalPages - 1;
22
+ if (!showLeftDots && showRightDots) {
23
+ const leftItemCount = 3 + 2 * siblingCount;
24
+ const leftRange = range(1, leftItemCount);
25
+ return [...leftRange, "...", totalPages];
26
+ }
27
+ if (showLeftDots && !showRightDots) {
28
+ const rightItemCount = 3 + 2 * siblingCount;
29
+ const rightRange = range(totalPages - rightItemCount + 1, totalPages);
30
+ return [1, "...", ...rightRange];
31
+ }
32
+ const middleRange = range(leftSiblingIndex, rightSiblingIndex);
33
+ return [1, "...", ...middleRange, "...", totalPages];
34
+ }
35
+ const ChevronLeft = () => (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-left", size: "md" });
36
+ const ChevronRight = () => (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-right", size: "md" });
37
+ function Pagination({ currentPage, totalPages, onPageChange, showPrevNext = true, siblingCount = 1, className, ...rest }) {
38
+ const pages = getPageNumbers(currentPage, totalPages, siblingCount);
39
+ return ((0, jsx_runtime_1.jsx)("nav", { className: (0, cn_1.cn)("rayden-pagination min-w-0", className), "aria-label": "Pagination", ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full items-center justify-center gap-2", children: [showPrevNext && ((0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => onPageChange(currentPage - 1), disabled: currentPage <= 1, className: "inline-flex min-h-11 shrink-0 items-center gap-2 rounded-lg focus-visible:outline-2 focus-visible:outline-action-primary-text border border-control-border bg-surface px-3 py-2 text-sm font-semibold text-on-surface-body cursor-pointer hover:bg-grey-50 disabled:opacity-50 disabled:cursor-not-allowed", "aria-label": "Previous page", children: [(0, jsx_runtime_1.jsx)(ChevronLeft, {}), (0, jsx_runtime_1.jsx)("span", { className: "rayden-pagination-word", children: "Previous" })] })), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("items-center justify-center gap-1 flex-wrap", showPrevNext ? "rayden-pagination-pages" : "flex"), children: pages.map((page, i) => page === "..." ? ((0, jsx_runtime_1.jsx)("span", { className: "flex items-center justify-center size-6 text-sm text-on-surface-muted", children: "..." }, `dots-${i}`)) : ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => onPageChange(page), className: (0, cn_1.cn)("flex items-center justify-center min-w-9 h-11 px-2 rounded-md text-sm cursor-pointer", page === currentPage
40
+ ? "border border-action-primary-text text-action-primary-text font-medium"
41
+ : "text-on-surface-secondary hover:bg-grey-100"), "aria-label": `Page ${page}`, "aria-current": page === currentPage ? "page" : undefined, children: page }, page))) }), showPrevNext && ((0, jsx_runtime_1.jsxs)("span", { className: "rayden-pagination-compact text-sm text-on-surface-body", "aria-live": "polite", children: ["Page ", currentPage, " of ", totalPages] })), showPrevNext && ((0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => onPageChange(currentPage + 1), disabled: currentPage >= totalPages, className: "inline-flex min-h-11 shrink-0 items-center gap-2 rounded-lg focus-visible:outline-2 focus-visible:outline-action-primary-text border border-control-border bg-surface px-3 py-2 text-sm font-semibold text-on-surface-body cursor-pointer hover:bg-grey-50 disabled:opacity-50 disabled:cursor-not-allowed", "aria-label": "Next page", children: [(0, jsx_runtime_1.jsx)("span", { className: "rayden-pagination-word", children: "Next" }), (0, jsx_runtime_1.jsx)(ChevronRight, {})] }))] }) }));
42
+ }
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { Icon } from "../Icon/index.js";
4
+ function range(start, end) {
5
+ const arr = [];
6
+ for (let i = start; i <= end; i++)
7
+ arr.push(i);
8
+ return arr;
9
+ }
10
+ function getPageNumbers(currentPage, totalPages, siblingCount) {
11
+ const totalNumbers = siblingCount * 2 + 5; // siblings + first + last + current + 2 dots
12
+ if (totalPages <= totalNumbers) {
13
+ return range(1, totalPages);
14
+ }
15
+ const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
16
+ const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPages);
17
+ const showLeftDots = leftSiblingIndex > 2;
18
+ const showRightDots = rightSiblingIndex < totalPages - 1;
19
+ if (!showLeftDots && showRightDots) {
20
+ const leftItemCount = 3 + 2 * siblingCount;
21
+ const leftRange = range(1, leftItemCount);
22
+ return [...leftRange, "...", totalPages];
23
+ }
24
+ if (showLeftDots && !showRightDots) {
25
+ const rightItemCount = 3 + 2 * siblingCount;
26
+ const rightRange = range(totalPages - rightItemCount + 1, totalPages);
27
+ return [1, "...", ...rightRange];
28
+ }
29
+ const middleRange = range(leftSiblingIndex, rightSiblingIndex);
30
+ return [1, "...", ...middleRange, "...", totalPages];
31
+ }
32
+ const ChevronLeft = () => _jsx(Icon, { name: "chevron-left", size: "md" });
33
+ const ChevronRight = () => _jsx(Icon, { name: "chevron-right", size: "md" });
34
+ export function Pagination({ currentPage, totalPages, onPageChange, showPrevNext = true, siblingCount = 1, className, ...rest }) {
35
+ const pages = getPageNumbers(currentPage, totalPages, siblingCount);
36
+ return (_jsx("nav", { className: cn("rayden-pagination min-w-0", className), "aria-label": "Pagination", ...rest, children: _jsxs("div", { className: "flex w-full items-center justify-center gap-2", children: [showPrevNext && (_jsxs("button", { type: "button", onClick: () => onPageChange(currentPage - 1), disabled: currentPage <= 1, className: "inline-flex min-h-11 shrink-0 items-center gap-2 rounded-lg focus-visible:outline-2 focus-visible:outline-action-primary-text border border-control-border bg-surface px-3 py-2 text-sm font-semibold text-on-surface-body cursor-pointer hover:bg-grey-50 disabled:opacity-50 disabled:cursor-not-allowed", "aria-label": "Previous page", children: [_jsx(ChevronLeft, {}), _jsx("span", { className: "rayden-pagination-word", children: "Previous" })] })), _jsx("div", { className: cn("items-center justify-center gap-1 flex-wrap", showPrevNext ? "rayden-pagination-pages" : "flex"), children: pages.map((page, i) => page === "..." ? (_jsx("span", { className: "flex items-center justify-center size-6 text-sm text-on-surface-muted", children: "..." }, `dots-${i}`)) : (_jsx("button", { type: "button", onClick: () => onPageChange(page), className: cn("flex items-center justify-center min-w-9 h-11 px-2 rounded-md text-sm cursor-pointer", page === currentPage
37
+ ? "border border-action-primary-text text-action-primary-text font-medium"
38
+ : "text-on-surface-secondary hover:bg-grey-100"), "aria-label": `Page ${page}`, "aria-current": page === currentPage ? "page" : undefined, children: page }, page))) }), showPrevNext && (_jsxs("span", { className: "rayden-pagination-compact text-sm text-on-surface-body", "aria-live": "polite", children: ["Page ", currentPage, " of ", totalPages] })), showPrevNext && (_jsxs("button", { type: "button", onClick: () => onPageChange(currentPage + 1), disabled: currentPage >= totalPages, className: "inline-flex min-h-11 shrink-0 items-center gap-2 rounded-lg focus-visible:outline-2 focus-visible:outline-action-primary-text border border-control-border bg-surface px-3 py-2 text-sm font-semibold text-on-surface-body cursor-pointer hover:bg-grey-50 disabled:opacity-50 disabled:cursor-not-allowed", "aria-label": "Next page", children: [_jsx("span", { className: "rayden-pagination-word", children: "Next" }), _jsx(ChevronRight, {})] }))] }) }));
39
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Pagination = void 0;
4
+ var Pagination_1 = require("./Pagination.cjs");
5
+ Object.defineProperty(exports, "Pagination", { enumerable: true, get: function () { return Pagination_1.Pagination; } });
@@ -0,0 +1 @@
1
+ export { Pagination } from "./Pagination.js";
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressBar = ProgressBar;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const cn_1 = require("../../utils/cn.cjs");
7
+ const SEGMENT_COUNT = 10;
8
+ const trackHeight = {
9
+ sm: "h-1",
10
+ md: "h-2",
11
+ lg: "h-3",
12
+ };
13
+ const clampValue = (value) => Math.min(100, Math.max(0, value));
14
+ function ProgressBar({ value = 0, size = "lg", type = "basic", label, metadata, showPercentage = true, percentagePosition = "bottom", className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }) {
15
+ const clamped = clampValue(value);
16
+ const generatedId = (0, react_1.useId)();
17
+ const labelId = label ? `${generatedId}-label` : undefined;
18
+ // Naming and value semantics belong on the same element as the progressbar
19
+ // role. Spreading them onto the wrapper left every bar unnamed, and the
20
+ // visible label had no id to point at.
21
+ const namedBy = ariaLabelledBy ?? labelId;
22
+ const progressAria = {
23
+ role: "progressbar",
24
+ "aria-valuenow": clamped,
25
+ "aria-valuemin": 0,
26
+ "aria-valuemax": 100,
27
+ "aria-labelledby": namedBy,
28
+ "aria-label": namedBy ? undefined : ariaLabel,
29
+ "aria-describedby": ariaDescribedBy,
30
+ };
31
+ const filledSegments = Math.round((clamped / 100) * SEGMENT_COUNT);
32
+ const metadataItems = Array.isArray(metadata) ? metadata : metadata ? [metadata] : [];
33
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex flex-col gap-2 w-full", className), ...rest, children: [(label || (showPercentage && percentagePosition === "top")) && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [label && ((0, jsx_runtime_1.jsx)("span", { id: labelId, className: "flex-1 text-sm font-medium text-grey-900 leading-[1.45]", children: label })), showPercentage && percentagePosition === "top" && ((0, jsx_runtime_1.jsxs)("span", { className: "text-sm font-semibold text-grey-500 leading-[1.45]", children: [Math.round(clamped), "%"] }))] })), type === "basic" ? ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("w-full rounded-full bg-grey-200", trackHeight[size]), ...progressAria, children: (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("rounded-full bg-primary-400 transition-all duration-300", trackHeight[size]), style: { width: `${clamped}%` } }) })) : ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("flex gap-0.5 w-full", trackHeight[size]), ...progressAria, children: Array.from({ length: SEGMENT_COUNT }, (_, i) => ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("flex-1 rounded-full transition-colors duration-300", i < filledSegments ? "bg-primary-400" : "bg-grey-100") }, i))) })), (metadataItems.length > 0 || (showPercentage && percentagePosition === "bottom")) && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [metadataItems.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-1 items-center gap-1", children: metadataItems.map((item, i) => ((0, jsx_runtime_1.jsxs)("span", { className: "contents", children: [i > 0 && (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-grey-500 leading-[1.45]", children: "\u2022" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-grey-500 leading-[1.45]", children: item })] }, i))) })), showPercentage && percentagePosition === "bottom" && ((0, jsx_runtime_1.jsxs)("span", { className: "flex-1 text-sm font-semibold text-grey-500 text-right leading-[1.45]", children: [Math.round(clamped), "%"] }))] }))] }));
34
+ }
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId } from "react";
3
+ import { cn } from "../../utils/cn.js";
4
+ const SEGMENT_COUNT = 10;
5
+ const trackHeight = {
6
+ sm: "h-1",
7
+ md: "h-2",
8
+ lg: "h-3",
9
+ };
10
+ const clampValue = (value) => Math.min(100, Math.max(0, value));
11
+ export function ProgressBar({ value = 0, size = "lg", type = "basic", label, metadata, showPercentage = true, percentagePosition = "bottom", className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }) {
12
+ const clamped = clampValue(value);
13
+ const generatedId = useId();
14
+ const labelId = label ? `${generatedId}-label` : undefined;
15
+ // Naming and value semantics belong on the same element as the progressbar
16
+ // role. Spreading them onto the wrapper left every bar unnamed, and the
17
+ // visible label had no id to point at.
18
+ const namedBy = ariaLabelledBy ?? labelId;
19
+ const progressAria = {
20
+ role: "progressbar",
21
+ "aria-valuenow": clamped,
22
+ "aria-valuemin": 0,
23
+ "aria-valuemax": 100,
24
+ "aria-labelledby": namedBy,
25
+ "aria-label": namedBy ? undefined : ariaLabel,
26
+ "aria-describedby": ariaDescribedBy,
27
+ };
28
+ const filledSegments = Math.round((clamped / 100) * SEGMENT_COUNT);
29
+ const metadataItems = Array.isArray(metadata) ? metadata : metadata ? [metadata] : [];
30
+ return (_jsxs("div", { className: cn("flex flex-col gap-2 w-full", className), ...rest, children: [(label || (showPercentage && percentagePosition === "top")) && (_jsxs("div", { className: "flex items-center gap-2", children: [label && (_jsx("span", { id: labelId, className: "flex-1 text-sm font-medium text-grey-900 leading-[1.45]", children: label })), showPercentage && percentagePosition === "top" && (_jsxs("span", { className: "text-sm font-semibold text-grey-500 leading-[1.45]", children: [Math.round(clamped), "%"] }))] })), type === "basic" ? (_jsx("div", { className: cn("w-full rounded-full bg-grey-200", trackHeight[size]), ...progressAria, children: _jsx("div", { className: cn("rounded-full bg-primary-400 transition-all duration-300", trackHeight[size]), style: { width: `${clamped}%` } }) })) : (_jsx("div", { className: cn("flex gap-0.5 w-full", trackHeight[size]), ...progressAria, children: Array.from({ length: SEGMENT_COUNT }, (_, i) => (_jsx("div", { className: cn("flex-1 rounded-full transition-colors duration-300", i < filledSegments ? "bg-primary-400" : "bg-grey-100") }, i))) })), (metadataItems.length > 0 || (showPercentage && percentagePosition === "bottom")) && (_jsxs("div", { className: "flex items-center justify-between", children: [metadataItems.length > 0 && (_jsx("div", { className: "flex flex-1 items-center gap-1", children: metadataItems.map((item, i) => (_jsxs("span", { className: "contents", children: [i > 0 && _jsx("span", { className: "text-xs text-grey-500 leading-[1.45]", children: "\u2022" }), _jsx("span", { className: "text-sm font-medium text-grey-500 leading-[1.45]", children: item })] }, i))) })), showPercentage && percentagePosition === "bottom" && (_jsxs("span", { className: "flex-1 text-sm font-semibold text-grey-500 text-right leading-[1.45]", children: [Math.round(clamped), "%"] }))] }))] }));
31
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressBar = void 0;
4
+ var ProgressBar_1 = require("./ProgressBar.cjs");
5
+ Object.defineProperty(exports, "ProgressBar", { enumerable: true, get: function () { return ProgressBar_1.ProgressBar; } });
@@ -0,0 +1 @@
1
+ export { ProgressBar } from "./ProgressBar.js";
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressCircle = ProgressCircle;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../../utils/cn.cjs");
6
+ const sizeConfig = {
7
+ xs: { dimension: 48, strokeWidth: 4, fontSize: 12 },
8
+ sm: { dimension: 56, strokeWidth: 5, fontSize: 12 },
9
+ md: { dimension: 72, strokeWidth: 6, fontSize: 14 },
10
+ lg: { dimension: 90, strokeWidth: 7, fontSize: 16 },
11
+ xl: { dimension: 120, strokeWidth: 8, fontSize: 18 },
12
+ };
13
+ const SEGMENT_COUNT = 10;
14
+ const SEGMENT_GAP_DEGREES = 6;
15
+ const clampValue = (value) => Math.min(100, Math.max(0, value));
16
+ function ProgressCircle({ value = 0, size = "md", variant = "default", showText = true, className, label, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest }) {
17
+ const clamped = clampValue(value);
18
+ const config = sizeConfig[size];
19
+ const radius = (config.dimension - config.strokeWidth) / 2;
20
+ const circumference = 2 * Math.PI * radius;
21
+ if (variant === "segmented") {
22
+ const filledSegments = Math.round((clamped / 100) * SEGMENT_COUNT);
23
+ const totalGapDegrees = SEGMENT_COUNT * SEGMENT_GAP_DEGREES;
24
+ const segmentDegrees = (360 - totalGapDegrees) / SEGMENT_COUNT;
25
+ const segmentLength = (segmentDegrees / 360) * circumference;
26
+ const gapLength = (SEGMENT_GAP_DEGREES / 360) * circumference;
27
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("relative inline-flex items-center justify-center", className), style: { width: config.dimension, height: config.dimension }, role: "progressbar", "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": 100, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabelledBy ? undefined : (label ?? ariaLabel ?? "Progress"), ...rest, children: [(0, jsx_runtime_1.jsx)("svg", { width: config.dimension, height: config.dimension, className: "-rotate-90", children: Array.from({ length: SEGMENT_COUNT }, (_, i) => {
28
+ const segmentOffset = i * ((segmentLength + gapLength) / circumference) * circumference;
29
+ return ((0, jsx_runtime_1.jsx)("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: i < filledSegments ? "#F56630" : "#F0F2F5", strokeWidth: config.strokeWidth, strokeLinecap: "round", strokeDasharray: `${segmentLength} ${circumference - segmentLength}`, strokeDashoffset: -segmentOffset, className: "transition-colors duration-300" }, i));
30
+ }) }), showText && ((0, jsx_runtime_1.jsxs)("span", { className: "absolute font-semibold text-grey-900", style: { fontSize: config.fontSize }, children: [Math.round(clamped), "%"] }))] }));
31
+ }
32
+ const offset = circumference - (clamped / 100) * circumference;
33
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("relative inline-flex items-center justify-center", className), style: { width: config.dimension, height: config.dimension }, role: "progressbar", "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": 100, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabelledBy ? undefined : (label ?? ariaLabel ?? "Progress"), ...rest, children: [(0, jsx_runtime_1.jsxs)("svg", { width: config.dimension, height: config.dimension, className: "-rotate-90", children: [(0, jsx_runtime_1.jsx)("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: "#F0F2F5", strokeWidth: config.strokeWidth }), (0, jsx_runtime_1.jsx)("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: "#F56630", strokeWidth: config.strokeWidth, strokeLinecap: "round", strokeDasharray: circumference, strokeDashoffset: offset, className: "transition-all duration-300" })] }), showText && ((0, jsx_runtime_1.jsxs)("span", { className: "absolute font-semibold text-grey-900", style: { fontSize: config.fontSize }, children: [Math.round(clamped), "%"] }))] }));
34
+ }
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../utils/cn.js";
3
+ const sizeConfig = {
4
+ xs: { dimension: 48, strokeWidth: 4, fontSize: 12 },
5
+ sm: { dimension: 56, strokeWidth: 5, fontSize: 12 },
6
+ md: { dimension: 72, strokeWidth: 6, fontSize: 14 },
7
+ lg: { dimension: 90, strokeWidth: 7, fontSize: 16 },
8
+ xl: { dimension: 120, strokeWidth: 8, fontSize: 18 },
9
+ };
10
+ const SEGMENT_COUNT = 10;
11
+ const SEGMENT_GAP_DEGREES = 6;
12
+ const clampValue = (value) => Math.min(100, Math.max(0, value));
13
+ export function ProgressCircle({ value = 0, size = "md", variant = "default", showText = true, className, label, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest }) {
14
+ const clamped = clampValue(value);
15
+ const config = sizeConfig[size];
16
+ const radius = (config.dimension - config.strokeWidth) / 2;
17
+ const circumference = 2 * Math.PI * radius;
18
+ if (variant === "segmented") {
19
+ const filledSegments = Math.round((clamped / 100) * SEGMENT_COUNT);
20
+ const totalGapDegrees = SEGMENT_COUNT * SEGMENT_GAP_DEGREES;
21
+ const segmentDegrees = (360 - totalGapDegrees) / SEGMENT_COUNT;
22
+ const segmentLength = (segmentDegrees / 360) * circumference;
23
+ const gapLength = (SEGMENT_GAP_DEGREES / 360) * circumference;
24
+ return (_jsxs("div", { className: cn("relative inline-flex items-center justify-center", className), style: { width: config.dimension, height: config.dimension }, role: "progressbar", "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": 100, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabelledBy ? undefined : (label ?? ariaLabel ?? "Progress"), ...rest, children: [_jsx("svg", { width: config.dimension, height: config.dimension, className: "-rotate-90", children: Array.from({ length: SEGMENT_COUNT }, (_, i) => {
25
+ const segmentOffset = i * ((segmentLength + gapLength) / circumference) * circumference;
26
+ return (_jsx("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: i < filledSegments ? "#F56630" : "#F0F2F5", strokeWidth: config.strokeWidth, strokeLinecap: "round", strokeDasharray: `${segmentLength} ${circumference - segmentLength}`, strokeDashoffset: -segmentOffset, className: "transition-colors duration-300" }, i));
27
+ }) }), showText && (_jsxs("span", { className: "absolute font-semibold text-grey-900", style: { fontSize: config.fontSize }, children: [Math.round(clamped), "%"] }))] }));
28
+ }
29
+ const offset = circumference - (clamped / 100) * circumference;
30
+ return (_jsxs("div", { className: cn("relative inline-flex items-center justify-center", className), style: { width: config.dimension, height: config.dimension }, role: "progressbar", "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": 100, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabelledBy ? undefined : (label ?? ariaLabel ?? "Progress"), ...rest, children: [_jsxs("svg", { width: config.dimension, height: config.dimension, className: "-rotate-90", children: [_jsx("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: "#F0F2F5", strokeWidth: config.strokeWidth }), _jsx("circle", { cx: config.dimension / 2, cy: config.dimension / 2, r: radius, fill: "none", stroke: "#F56630", strokeWidth: config.strokeWidth, strokeLinecap: "round", strokeDasharray: circumference, strokeDashoffset: offset, className: "transition-all duration-300" })] }), showText && (_jsxs("span", { className: "absolute font-semibold text-grey-900", style: { fontSize: config.fontSize }, children: [Math.round(clamped), "%"] }))] }));
31
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressCircle = void 0;
4
+ var ProgressCircle_1 = require("./ProgressCircle.cjs");
5
+ Object.defineProperty(exports, "ProgressCircle", { enumerable: true, get: function () { return ProgressCircle_1.ProgressCircle; } });
@@ -0,0 +1 @@
1
+ export { ProgressCircle } from "./ProgressCircle.js";
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Select = void 0;
4
+ exports.useSelectContext = useSelectContext;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const useControllableValue_1 = require("../../hooks/useControllableValue.cjs");
8
+ const usePopupList_1 = require("../../hooks/usePopupList.cjs");
9
+ const cn_1 = require("../../utils/cn.cjs");
10
+ const useCollisionAwareSide_1 = require("../../hooks/useCollisionAwareSide.cjs");
11
+ const resolveIcon_1 = require("../../utils/resolveIcon.cjs");
12
+ const Icon_1 = require("../Icon/index.cjs");
13
+ const SelectContext = (0, react_1.createContext)(null);
14
+ function useSelectContext() {
15
+ const ctx = (0, react_1.useContext)(SelectContext);
16
+ if (!ctx)
17
+ throw new Error("SelectOption must be used within <Select>");
18
+ return ctx;
19
+ }
20
+ function findSelectedOption(children, value) {
21
+ let found = null;
22
+ react_1.Children.forEach(children, (child) => {
23
+ if (found)
24
+ return;
25
+ if ((0, react_1.isValidElement)(child) && child.props.value === value) {
26
+ found = {
27
+ label: child.props.children,
28
+ icon: child.props.icon,
29
+ avatar: child.props.avatar,
30
+ statusColor: child.props.statusColor,
31
+ description: child.props.description,
32
+ };
33
+ }
34
+ else if ((0, react_1.isValidElement)(child) && child.props.children) {
35
+ found = findSelectedOption(child.props.children, value);
36
+ }
37
+ });
38
+ return found;
39
+ }
40
+ exports.Select = (0, react_1.forwardRef)(({ value: controlledValue, defaultValue = "", onValueChange, placeholder = "Select an option", label, helperText, error, disabled = false, children, className, wrapperClassName, ...rest }, ref) => {
41
+ const [value, setValue] = (0, useControllableValue_1.useControllableValue)(controlledValue, defaultValue, onValueChange);
42
+ const [open, setOpen] = (0, react_1.useState)(false);
43
+ const hasError = error !== undefined && error !== false;
44
+ const bottomText = hasError ? (typeof error === "string" ? error : undefined) : helperText;
45
+ const listboxId = (0, react_1.useId)();
46
+ const labelId = (0, react_1.useId)();
47
+ const helperId = (0, react_1.useId)();
48
+ const containerRef = (0, react_1.useRef)(null);
49
+ const triggerRef = (0, react_1.useRef)(null);
50
+ const listRef = (0, react_1.useRef)(null);
51
+ // The listbox always opened downward, so near the bottom edge it ran off-screen.
52
+ const listSide = (0, useCollisionAwareSide_1.useCollisionAwareSide)("bottom", open, triggerRef, listRef);
53
+ const { close, onTriggerKeyDown, onListKeyDown } = (0, usePopupList_1.usePopupList)({
54
+ open,
55
+ setOpen,
56
+ containerRef,
57
+ triggerRef,
58
+ listRef,
59
+ role: "option",
60
+ selected: true,
61
+ });
62
+ const onSelect = (0, react_1.useCallback)((val) => {
63
+ close(true);
64
+ setValue(val);
65
+ }, [close, setValue]);
66
+ // Find selected option info for trigger display
67
+ const selectedOption = value ? findSelectedOption(children, value) : null;
68
+ // Resolve leading element for trigger
69
+ const triggerLeading = selectedOption ? (selectedOption.avatar ? (selectedOption.avatar) : selectedOption.statusColor ? ((0, jsx_runtime_1.jsx)("span", { className: "shrink-0 size-2 rounded-full border-[1.5px] border-white", style: { backgroundColor: selectedOption.statusColor } })) : selectedOption.icon ? ((0, jsx_runtime_1.jsx)("span", { className: "shrink-0 size-5", children: (0, resolveIcon_1.resolveIcon)(selectedOption.icon, "md") })) : null) : null;
70
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: (node) => {
71
+ containerRef.current = node;
72
+ if (typeof ref === "function")
73
+ ref(node);
74
+ else if (ref)
75
+ ref.current = node;
76
+ }, ...rest, className: (0, cn_1.cn)("relative flex flex-col gap-2 w-full", wrapperClassName), children: [label && ((0, jsx_runtime_1.jsx)("label", { id: labelId, className: "text-sm font-medium text-on-surface leading-[1.45]", children: label })), (0, jsx_runtime_1.jsxs)("button", { ref: triggerRef, type: "button", role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, "aria-describedby": bottomText ? helperId : undefined, "aria-invalid": hasError || undefined, disabled: disabled, onKeyDown: onTriggerKeyDown, onClick: () => !disabled && setOpen(!open), className: (0, cn_1.cn)("flex h-14 w-full items-center gap-3 rounded-md border px-4 transition-colors", disabled
77
+ ? "bg-grey-100 border-control-border-disabled cursor-not-allowed"
78
+ : hasError
79
+ ? "bg-surface border-error-400"
80
+ : open
81
+ ? "bg-surface border-[#1671D9]"
82
+ : "bg-surface border-control-border hover:border-[#B6D8FF]", className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-1 items-center gap-2 min-w-0", children: [triggerLeading, (0, jsx_runtime_1.jsx)("span", { className: (0, cn_1.cn)("truncate text-body-sm", selectedOption ? "text-on-surface" : "text-on-surface-muted"), children: selectedOption ? selectedOption.label : placeholder })] }), (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-down", size: "md", "aria-hidden": "true", className: (0, cn_1.cn)("shrink-0 transition-transform", open && "rotate-180", disabled ? "text-grey-300" : "text-on-surface-muted") })] }), bottomText && ((0, jsx_runtime_1.jsx)("p", { id: helperId, className: (0, cn_1.cn)("text-sm leading-[1.45]", hasError ? "text-feedback-error" : "text-on-surface-muted"), children: bottomText })), open && ((0, jsx_runtime_1.jsx)(SelectContext.Provider, { value: { value, onSelect, open }, children: (0, jsx_runtime_1.jsx)("div", { ref: listRef, id: listboxId, role: "listbox", onKeyDown: onListKeyDown, className: (0, cn_1.cn)("absolute left-0 right-0 z-50 max-h-[320px] overflow-y-auto rounded-lg border border-grey-200 bg-surface py-1 shadow-[0px_3px_2px_-2px_rgba(0,0,0,0.06),0px_5px_3px_-2px_rgba(0,0,0,0.02)]", listSide === "top" ? "bottom-full mb-2" : "top-full mt-2"), children: children }) }))] }));
83
+ });
84
+ exports.Select.displayName = "Select";
@@ -0,0 +1,80 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useId, useRef, useState, forwardRef, Children, isValidElement, } from "react";
3
+ import { useControllableValue } from "../../hooks/useControllableValue.js";
4
+ import { usePopupList } from "../../hooks/usePopupList.js";
5
+ import { cn } from "../../utils/cn.js";
6
+ import { useCollisionAwareSide } from "../../hooks/useCollisionAwareSide.js";
7
+ import { resolveIcon } from "../../utils/resolveIcon.js";
8
+ import { Icon } from "../Icon/index.js";
9
+ const SelectContext = createContext(null);
10
+ export function useSelectContext() {
11
+ const ctx = useContext(SelectContext);
12
+ if (!ctx)
13
+ throw new Error("SelectOption must be used within <Select>");
14
+ return ctx;
15
+ }
16
+ function findSelectedOption(children, value) {
17
+ let found = null;
18
+ Children.forEach(children, (child) => {
19
+ if (found)
20
+ return;
21
+ if (isValidElement(child) && child.props.value === value) {
22
+ found = {
23
+ label: child.props.children,
24
+ icon: child.props.icon,
25
+ avatar: child.props.avatar,
26
+ statusColor: child.props.statusColor,
27
+ description: child.props.description,
28
+ };
29
+ }
30
+ else if (isValidElement(child) && child.props.children) {
31
+ found = findSelectedOption(child.props.children, value);
32
+ }
33
+ });
34
+ return found;
35
+ }
36
+ export const Select = forwardRef(({ value: controlledValue, defaultValue = "", onValueChange, placeholder = "Select an option", label, helperText, error, disabled = false, children, className, wrapperClassName, ...rest }, ref) => {
37
+ const [value, setValue] = useControllableValue(controlledValue, defaultValue, onValueChange);
38
+ const [open, setOpen] = useState(false);
39
+ const hasError = error !== undefined && error !== false;
40
+ const bottomText = hasError ? (typeof error === "string" ? error : undefined) : helperText;
41
+ const listboxId = useId();
42
+ const labelId = useId();
43
+ const helperId = useId();
44
+ const containerRef = useRef(null);
45
+ const triggerRef = useRef(null);
46
+ const listRef = useRef(null);
47
+ // The listbox always opened downward, so near the bottom edge it ran off-screen.
48
+ const listSide = useCollisionAwareSide("bottom", open, triggerRef, listRef);
49
+ const { close, onTriggerKeyDown, onListKeyDown } = usePopupList({
50
+ open,
51
+ setOpen,
52
+ containerRef,
53
+ triggerRef,
54
+ listRef,
55
+ role: "option",
56
+ selected: true,
57
+ });
58
+ const onSelect = useCallback((val) => {
59
+ close(true);
60
+ setValue(val);
61
+ }, [close, setValue]);
62
+ // Find selected option info for trigger display
63
+ const selectedOption = value ? findSelectedOption(children, value) : null;
64
+ // Resolve leading element for trigger
65
+ const triggerLeading = selectedOption ? (selectedOption.avatar ? (selectedOption.avatar) : selectedOption.statusColor ? (_jsx("span", { className: "shrink-0 size-2 rounded-full border-[1.5px] border-white", style: { backgroundColor: selectedOption.statusColor } })) : selectedOption.icon ? (_jsx("span", { className: "shrink-0 size-5", children: resolveIcon(selectedOption.icon, "md") })) : null) : null;
66
+ return (_jsxs("div", { ref: (node) => {
67
+ containerRef.current = node;
68
+ if (typeof ref === "function")
69
+ ref(node);
70
+ else if (ref)
71
+ ref.current = node;
72
+ }, ...rest, className: cn("relative flex flex-col gap-2 w-full", wrapperClassName), children: [label && (_jsx("label", { id: labelId, className: "text-sm font-medium text-on-surface leading-[1.45]", children: label })), _jsxs("button", { ref: triggerRef, type: "button", role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, "aria-describedby": bottomText ? helperId : undefined, "aria-invalid": hasError || undefined, disabled: disabled, onKeyDown: onTriggerKeyDown, onClick: () => !disabled && setOpen(!open), className: cn("flex h-14 w-full items-center gap-3 rounded-md border px-4 transition-colors", disabled
73
+ ? "bg-grey-100 border-control-border-disabled cursor-not-allowed"
74
+ : hasError
75
+ ? "bg-surface border-error-400"
76
+ : open
77
+ ? "bg-surface border-[#1671D9]"
78
+ : "bg-surface border-control-border hover:border-[#B6D8FF]", className), children: [_jsxs("div", { className: "flex flex-1 items-center gap-2 min-w-0", children: [triggerLeading, _jsx("span", { className: cn("truncate text-body-sm", selectedOption ? "text-on-surface" : "text-on-surface-muted"), children: selectedOption ? selectedOption.label : placeholder })] }), _jsx(Icon, { name: "chevron-down", size: "md", "aria-hidden": "true", className: cn("shrink-0 transition-transform", open && "rotate-180", disabled ? "text-grey-300" : "text-on-surface-muted") })] }), bottomText && (_jsx("p", { id: helperId, className: cn("text-sm leading-[1.45]", hasError ? "text-feedback-error" : "text-on-surface-muted"), children: bottomText })), open && (_jsx(SelectContext.Provider, { value: { value, onSelect, open }, children: _jsx("div", { ref: listRef, id: listboxId, role: "listbox", onKeyDown: onListKeyDown, className: cn("absolute left-0 right-0 z-50 max-h-[320px] overflow-y-auto rounded-lg border border-grey-200 bg-surface py-1 shadow-[0px_3px_2px_-2px_rgba(0,0,0,0.06),0px_5px_3px_-2px_rgba(0,0,0,0.02)]", listSide === "top" ? "bottom-full mb-2" : "top-full mt-2"), children: children }) }))] }));
79
+ });
80
+ Select.displayName = "Select";
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectOption = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const cn_1 = require("../../utils/cn.cjs");
7
+ const resolveIcon_1 = require("../../utils/resolveIcon.cjs");
8
+ const Select_1 = require("./Select.cjs");
9
+ exports.SelectOption = (0, react_1.forwardRef)(({ value, icon, avatar, statusColor, description, disabled = false, children, className, onClick, ...rest }, ref) => {
10
+ const ctx = (0, Select_1.useSelectContext)();
11
+ const isSelected = ctx.value === value;
12
+ const handleClick = (e) => {
13
+ if (disabled)
14
+ return;
15
+ onClick?.(e);
16
+ if (!e.defaultPrevented)
17
+ ctx.onSelect(value);
18
+ };
19
+ const resolvedIcon = (0, resolveIcon_1.resolveIcon)(icon, "md");
20
+ // Determine leading element
21
+ const leading = avatar ? ((0, jsx_runtime_1.jsx)("span", { className: "shrink-0 size-5", children: avatar })) : statusColor ? ((0, jsx_runtime_1.jsx)("span", { className: "shrink-0 size-2 rounded-full border-[1.5px] border-white", style: { backgroundColor: statusColor } })) : resolvedIcon ? ((0, jsx_runtime_1.jsx)("span", { className: (0, cn_1.cn)("shrink-0 size-5", disabled && "opacity-50"), children: resolvedIcon })) : null;
22
+ return ((0, jsx_runtime_1.jsxs)("button", { ref: ref, type: "button", role: "option", tabIndex: -1, "aria-selected": isSelected, disabled: disabled, onClick: handleClick, className: (0, cn_1.cn)("flex w-full items-center px-4 py-2 text-left text-body-sm outline-none transition-colors", statusColor ? "gap-2" : "gap-3", disabled
23
+ ? "bg-grey-100 text-grey-500 cursor-not-allowed"
24
+ : "text-grey-900 hover:bg-grey-50 focus:bg-grey-100 focus:font-medium", className), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex flex-1 items-center", statusColor ? "gap-2" : "gap-3"), children: [leading, (0, jsx_runtime_1.jsx)("span", { className: "shrink-0", children: children }), description && (0, jsx_runtime_1.jsx)("span", { className: "text-grey-500 truncate", children: description })] }), isSelected && !disabled && ((0, jsx_runtime_1.jsx)("span", { className: "ml-2 shrink-0", children: (0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "text-[#1671D9]", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "8", cy: "8", r: "8", fill: "currentColor" }), (0, jsx_runtime_1.jsx)("path", { d: "M11.5 5.5L6.5 10.5L4.5 8.5", stroke: "white", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" })] }) }))] }));
25
+ });
26
+ exports.SelectOption.displayName = "SelectOption";