@pk-design/react-tailwind 1.6.0 → 1.7.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 (430) hide show
  1. package/dist/cjs/components/Accordion/Accordion.js +61 -0
  2. package/dist/cjs/components/Accordion/Accordion.js.map +1 -0
  3. package/dist/cjs/components/ActionSheet/ActionSheet.js +38 -0
  4. package/dist/cjs/components/ActionSheet/ActionSheet.js.map +1 -0
  5. package/dist/cjs/components/Alert/Alert.js +34 -0
  6. package/dist/cjs/components/Alert/Alert.js.map +1 -0
  7. package/dist/cjs/components/Badge/Badge.js +33 -0
  8. package/dist/cjs/components/Badge/Badge.js.map +1 -0
  9. package/dist/cjs/components/Banner/Banner.js +41 -0
  10. package/dist/cjs/components/Banner/Banner.js.map +1 -0
  11. package/dist/cjs/components/BodyText/BodyText.js +59 -0
  12. package/dist/cjs/components/BodyText/BodyText.js.map +1 -0
  13. package/dist/cjs/components/BottomNavigation/BottomNavigation.js +52 -0
  14. package/dist/cjs/components/BottomNavigation/BottomNavigation.js.map +1 -0
  15. package/dist/cjs/components/Breadcrumb/Breadcrumb.js +63 -0
  16. package/dist/cjs/components/Breadcrumb/Breadcrumb.js.map +1 -0
  17. package/dist/cjs/components/Button/Button.js +118 -0
  18. package/dist/cjs/components/Button/Button.js.map +1 -0
  19. package/dist/cjs/components/ButtonGroup/ButtonGroup.js +100 -0
  20. package/dist/cjs/components/ButtonGroup/ButtonGroup.js.map +1 -0
  21. package/dist/cjs/components/Card/Card.js +65 -0
  22. package/dist/cjs/components/Card/Card.js.map +1 -0
  23. package/dist/cjs/components/Checkbox/Checkbox.js +64 -0
  24. package/dist/cjs/components/Checkbox/Checkbox.js.map +1 -0
  25. package/dist/cjs/components/CheckboxGroup/CheckboxGroup.js +82 -0
  26. package/dist/cjs/components/CheckboxGroup/CheckboxGroup.js.map +1 -0
  27. package/dist/cjs/components/DataList/DataList.js +287 -0
  28. package/dist/cjs/components/DataList/DataList.js.map +1 -0
  29. package/dist/cjs/components/DataTable/DataTable.icons.js +20 -0
  30. package/dist/cjs/components/DataTable/DataTable.icons.js.map +1 -0
  31. package/dist/cjs/components/DataTable/DataTable.js +110 -0
  32. package/dist/cjs/components/DataTable/DataTable.js.map +1 -0
  33. package/dist/cjs/components/DataTable/DataTable.utils.js +87 -0
  34. package/dist/cjs/components/DataTable/DataTable.utils.js.map +1 -0
  35. package/dist/cjs/components/DetailedInformation/DetailedInformation.js +67 -0
  36. package/dist/cjs/components/DetailedInformation/DetailedInformation.js.map +1 -0
  37. package/dist/cjs/components/Dot/index.js +12 -0
  38. package/dist/cjs/components/Dot/index.js.map +1 -0
  39. package/dist/cjs/components/Drawer/Drawer.js +67 -0
  40. package/dist/cjs/components/Drawer/Drawer.js.map +1 -0
  41. package/dist/cjs/components/Dropdown/Dropdown.js +50 -0
  42. package/dist/cjs/components/Dropdown/Dropdown.js.map +1 -0
  43. package/dist/cjs/components/EmptyState/index.js +14 -0
  44. package/dist/cjs/components/EmptyState/index.js.map +1 -0
  45. package/dist/cjs/components/Flex/Flex.js +25 -0
  46. package/dist/cjs/components/Flex/Flex.js.map +1 -0
  47. package/dist/cjs/components/FloatingActionButton/FloatingActionButton.js +71 -0
  48. package/dist/cjs/components/FloatingActionButton/FloatingActionButton.js.map +1 -0
  49. package/dist/cjs/components/Grid/Grid.js +33 -0
  50. package/dist/cjs/components/Grid/Grid.js.map +1 -0
  51. package/dist/cjs/components/HeadingText/HeadingText.js +89 -0
  52. package/dist/cjs/components/HeadingText/HeadingText.js.map +1 -0
  53. package/dist/cjs/components/Icons/ArrowDownAZ.svg.js +46 -0
  54. package/dist/cjs/components/Icons/ArrowDownAZ.svg.js.map +1 -0
  55. package/dist/cjs/components/Icons/ArrowDownNarrowWide.svg.js +46 -0
  56. package/dist/cjs/components/Icons/ArrowDownNarrowWide.svg.js.map +1 -0
  57. package/dist/cjs/components/Icons/ArrowDownWideNarrow.svg.js +46 -0
  58. package/dist/cjs/components/Icons/ArrowDownWideNarrow.svg.js.map +1 -0
  59. package/dist/cjs/components/Icons/ArrowDownZA.svg.js +46 -0
  60. package/dist/cjs/components/Icons/ArrowDownZA.svg.js.map +1 -0
  61. package/dist/cjs/components/Icons/ArrowUpDown.svg.js +46 -0
  62. package/dist/cjs/components/Icons/ArrowUpDown.svg.js.map +1 -0
  63. package/dist/cjs/components/Icons/BadgeCheck.svg.js +48 -0
  64. package/dist/cjs/components/Icons/BadgeCheck.svg.js.map +1 -0
  65. package/dist/cjs/components/Icons/Check.svg.js +46 -0
  66. package/dist/cjs/components/Icons/Check.svg.js.map +1 -0
  67. package/dist/cjs/components/Icons/ChevronDown.svg.js +46 -0
  68. package/dist/cjs/components/Icons/ChevronDown.svg.js.map +1 -0
  69. package/dist/cjs/components/Icons/ChevronLeft.svg.js +46 -0
  70. package/dist/cjs/components/Icons/ChevronLeft.svg.js.map +1 -0
  71. package/dist/cjs/components/Icons/ChevronRight.svg.js +46 -0
  72. package/dist/cjs/components/Icons/ChevronRight.svg.js.map +1 -0
  73. package/dist/cjs/components/Icons/CircleAlert.svg.js +50 -0
  74. package/dist/cjs/components/Icons/CircleAlert.svg.js.map +1 -0
  75. package/dist/cjs/components/Icons/CircleCheck.svg.js +50 -0
  76. package/dist/cjs/components/Icons/CircleCheck.svg.js.map +1 -0
  77. package/dist/cjs/components/Icons/CirclePlus.svg.js +50 -0
  78. package/dist/cjs/components/Icons/CirclePlus.svg.js.map +1 -0
  79. package/dist/cjs/components/Icons/CircleX.svg.js +50 -0
  80. package/dist/cjs/components/Icons/CircleX.svg.js.map +1 -0
  81. package/dist/cjs/components/Icons/FolderPlus.svg.js +46 -0
  82. package/dist/cjs/components/Icons/FolderPlus.svg.js.map +1 -0
  83. package/dist/cjs/components/Icons/Info.svg.js +50 -0
  84. package/dist/cjs/components/Icons/Info.svg.js.map +1 -0
  85. package/dist/cjs/components/Icons/Search.svg.js +50 -0
  86. package/dist/cjs/components/Icons/Search.svg.js.map +1 -0
  87. package/dist/cjs/components/Icons/Slash.svg.js +46 -0
  88. package/dist/cjs/components/Icons/Slash.svg.js.map +1 -0
  89. package/dist/cjs/components/Icons/TriangleAlert.svg.js +46 -0
  90. package/dist/cjs/components/Icons/TriangleAlert.svg.js.map +1 -0
  91. package/dist/cjs/components/Icons/X.svg.js +46 -0
  92. package/dist/cjs/components/Icons/X.svg.js.map +1 -0
  93. package/dist/cjs/components/Input/Input.js +85 -0
  94. package/dist/cjs/components/Input/Input.js.map +1 -0
  95. package/dist/cjs/components/Label/Label.js +14 -0
  96. package/dist/cjs/components/Label/Label.js.map +1 -0
  97. package/dist/cjs/components/Loader/index.js +18 -0
  98. package/dist/cjs/components/Loader/index.js.map +1 -0
  99. package/dist/cjs/components/MobileHeader/MobileHeader.js +45 -0
  100. package/dist/cjs/components/MobileHeader/MobileHeader.js.map +1 -0
  101. package/dist/cjs/components/MobilePicker/MobilePicker.js +368 -0
  102. package/dist/cjs/components/MobilePicker/MobilePicker.js.map +1 -0
  103. package/dist/cjs/components/MobileStepper/MobileStepper.js +33 -0
  104. package/dist/cjs/components/MobileStepper/MobileStepper.js.map +1 -0
  105. package/dist/cjs/components/Pagination/Pagination.js +33 -0
  106. package/dist/cjs/components/Pagination/Pagination.js.map +1 -0
  107. package/dist/cjs/components/Pagination/usePagination.js +33 -0
  108. package/dist/cjs/components/Pagination/usePagination.js.map +1 -0
  109. package/dist/cjs/components/PasswordInput/PasswordInput.js +56 -0
  110. package/dist/cjs/components/PasswordInput/PasswordInput.js.map +1 -0
  111. package/dist/cjs/components/PinInput/PinInput.js +98 -0
  112. package/dist/cjs/components/PinInput/PinInput.js.map +1 -0
  113. package/dist/cjs/components/PullToRefresh/PullToRefresh.js +83 -0
  114. package/dist/cjs/components/PullToRefresh/PullToRefresh.js.map +1 -0
  115. package/dist/cjs/components/QuantityStepper/QuantityStepper.js +77 -0
  116. package/dist/cjs/components/QuantityStepper/QuantityStepper.js.map +1 -0
  117. package/dist/cjs/components/Radio/Radio.js +34 -0
  118. package/dist/cjs/components/Radio/Radio.js.map +1 -0
  119. package/dist/cjs/components/RadioGroup/RadioGroup.js +50 -0
  120. package/dist/cjs/components/RadioGroup/RadioGroup.js.map +1 -0
  121. package/dist/cjs/components/RadioSwitch/RadioSwitch.js +116 -0
  122. package/dist/cjs/components/RadioSwitch/RadioSwitch.js.map +1 -0
  123. package/dist/cjs/components/RangeInput/RangeInput.js +66 -0
  124. package/dist/cjs/components/RangeInput/RangeInput.js.map +1 -0
  125. package/dist/cjs/components/RangeSlider/RangeSlider.js +167 -0
  126. package/dist/cjs/components/RangeSlider/RangeSlider.js.map +1 -0
  127. package/dist/cjs/components/SegmentedControl/SegmentedControl.js +64 -0
  128. package/dist/cjs/components/SegmentedControl/SegmentedControl.js.map +1 -0
  129. package/dist/cjs/components/SelectBox/SelectBox.js +305 -0
  130. package/dist/cjs/components/SelectBox/SelectBox.js.map +1 -0
  131. package/dist/cjs/components/Skeleton/Skeleton.js +36 -0
  132. package/dist/cjs/components/Skeleton/Skeleton.js.map +1 -0
  133. package/dist/cjs/components/StatusPill/StatusPill.js +46 -0
  134. package/dist/cjs/components/StatusPill/StatusPill.js.map +1 -0
  135. package/dist/cjs/components/StickyActionBar/StickyActionBar.js +22 -0
  136. package/dist/cjs/components/StickyActionBar/StickyActionBar.js.map +1 -0
  137. package/dist/cjs/components/SwipeableRow/SwipeableRow.js +187 -0
  138. package/dist/cjs/components/SwipeableRow/SwipeableRow.js.map +1 -0
  139. package/dist/cjs/components/SwipeableTabs/SwipeableTabs.js +91 -0
  140. package/dist/cjs/components/SwipeableTabs/SwipeableTabs.js.map +1 -0
  141. package/dist/cjs/components/Table/Table.js +57 -0
  142. package/dist/cjs/components/Table/Table.js.map +1 -0
  143. package/dist/cjs/components/Tabs/Tabs.js +53 -0
  144. package/dist/cjs/components/Tabs/Tabs.js.map +1 -0
  145. package/dist/cjs/components/TextContent/TextContent.js +47 -0
  146. package/dist/cjs/components/TextContent/TextContent.js.map +1 -0
  147. package/dist/cjs/components/Textarea/Textarea.js +64 -0
  148. package/dist/cjs/components/Textarea/Textarea.js.map +1 -0
  149. package/dist/cjs/components/Toast/Toast.js +96 -0
  150. package/dist/cjs/components/Toast/Toast.js.map +1 -0
  151. package/dist/cjs/components/Toast/ToastProvider.js +151 -0
  152. package/dist/cjs/components/Toast/ToastProvider.js.map +1 -0
  153. package/dist/cjs/components/VirtualizedDataTable/VirtualizedDataTable.js +122 -0
  154. package/dist/cjs/components/VirtualizedDataTable/VirtualizedDataTable.js.map +1 -0
  155. package/dist/cjs/components/VirtualizedDataTable/VirtualizedRow.js +48 -0
  156. package/dist/cjs/components/VirtualizedDataTable/VirtualizedRow.js.map +1 -0
  157. package/dist/cjs/components/WheelPicker/WheelPicker.js +82 -0
  158. package/dist/cjs/components/WheelPicker/WheelPicker.js.map +1 -0
  159. package/dist/cjs/components/common-responsive.js +310 -0
  160. package/dist/cjs/components/common-responsive.js.map +1 -0
  161. package/dist/cjs/hooks/use-debounce.js +31 -0
  162. package/dist/cjs/hooks/use-debounce.js.map +1 -0
  163. package/dist/cjs/hooks/use-is-mobile.js +24 -0
  164. package/dist/cjs/hooks/use-is-mobile.js.map +1 -0
  165. package/dist/cjs/hooks/use-is-tablet-or-mobile.js +13 -0
  166. package/dist/cjs/hooks/use-is-tablet-or-mobile.js.map +1 -0
  167. package/dist/cjs/hooks/use-is-tablet.js +21 -0
  168. package/dist/cjs/hooks/use-is-tablet.js.map +1 -0
  169. package/dist/cjs/index.js +163 -0
  170. package/dist/cjs/index.js.map +1 -0
  171. package/dist/cjs/react-tailwind.css +2 -0
  172. package/dist/cjs/react-tailwind.css.map +1 -0
  173. package/dist/cjs/utils/build-classname.js +8 -0
  174. package/dist/cjs/utils/build-classname.js.map +1 -0
  175. package/dist/cjs/utils/get.js +20 -0
  176. package/dist/cjs/utils/get.js.map +1 -0
  177. package/dist/cjs/utils/is-array.js +12 -0
  178. package/dist/cjs/utils/is-array.js.map +1 -0
  179. package/dist/cjs/utils/is-empty.js +26 -0
  180. package/dist/cjs/utils/is-empty.js.map +1 -0
  181. package/dist/es/components/Accordion/Accordion.js +59 -0
  182. package/dist/es/components/Accordion/Accordion.js.map +1 -0
  183. package/dist/es/components/ActionSheet/ActionSheet.js +36 -0
  184. package/dist/es/components/ActionSheet/ActionSheet.js.map +1 -0
  185. package/dist/es/components/Alert/Alert.js +32 -0
  186. package/dist/es/components/Alert/Alert.js.map +1 -0
  187. package/dist/es/components/Badge/Badge.js +31 -0
  188. package/dist/es/components/Badge/Badge.js.map +1 -0
  189. package/dist/es/components/Banner/Banner.js +39 -0
  190. package/dist/es/components/Banner/Banner.js.map +1 -0
  191. package/dist/es/components/BodyText/BodyText.js +57 -0
  192. package/dist/es/components/BodyText/BodyText.js.map +1 -0
  193. package/dist/es/components/BottomNavigation/BottomNavigation.js +50 -0
  194. package/dist/es/components/BottomNavigation/BottomNavigation.js.map +1 -0
  195. package/dist/es/components/Breadcrumb/Breadcrumb.js +61 -0
  196. package/dist/es/components/Breadcrumb/Breadcrumb.js.map +1 -0
  197. package/dist/es/components/Button/Button.js +116 -0
  198. package/dist/es/components/Button/Button.js.map +1 -0
  199. package/dist/es/components/ButtonGroup/ButtonGroup.js +98 -0
  200. package/dist/es/components/ButtonGroup/ButtonGroup.js.map +1 -0
  201. package/dist/es/components/Card/Card.js +57 -0
  202. package/dist/es/components/Card/Card.js.map +1 -0
  203. package/dist/es/components/Checkbox/Checkbox.js +62 -0
  204. package/dist/es/components/Checkbox/Checkbox.js.map +1 -0
  205. package/dist/es/components/CheckboxGroup/CheckboxGroup.js +80 -0
  206. package/dist/es/components/CheckboxGroup/CheckboxGroup.js.map +1 -0
  207. package/dist/es/components/DataList/DataList.js +285 -0
  208. package/dist/es/components/DataList/DataList.js.map +1 -0
  209. package/dist/es/components/DataTable/DataTable.icons.js +17 -0
  210. package/dist/es/components/DataTable/DataTable.icons.js.map +1 -0
  211. package/dist/es/components/DataTable/DataTable.js +108 -0
  212. package/dist/es/components/DataTable/DataTable.js.map +1 -0
  213. package/dist/es/components/DataTable/DataTable.utils.js +83 -0
  214. package/dist/es/components/DataTable/DataTable.utils.js.map +1 -0
  215. package/dist/es/components/DetailedInformation/DetailedInformation.js +65 -0
  216. package/dist/es/components/DetailedInformation/DetailedInformation.js.map +1 -0
  217. package/dist/es/components/Dot/index.js +10 -0
  218. package/dist/es/components/Dot/index.js.map +1 -0
  219. package/dist/es/components/Drawer/Drawer.js +65 -0
  220. package/dist/es/components/Drawer/Drawer.js.map +1 -0
  221. package/dist/es/components/Dropdown/Dropdown.js +48 -0
  222. package/dist/es/components/Dropdown/Dropdown.js.map +1 -0
  223. package/dist/es/components/EmptyState/index.js +12 -0
  224. package/dist/es/components/EmptyState/index.js.map +1 -0
  225. package/dist/es/components/Flex/Flex.js +22 -0
  226. package/dist/es/components/Flex/Flex.js.map +1 -0
  227. package/dist/es/components/FloatingActionButton/FloatingActionButton.js +69 -0
  228. package/dist/es/components/FloatingActionButton/FloatingActionButton.js.map +1 -0
  229. package/dist/es/components/Grid/Grid.js +30 -0
  230. package/dist/es/components/Grid/Grid.js.map +1 -0
  231. package/dist/es/components/HeadingText/HeadingText.js +87 -0
  232. package/dist/es/components/HeadingText/HeadingText.js.map +1 -0
  233. package/dist/es/components/Icons/ArrowDownAZ.svg.js +23 -0
  234. package/dist/es/components/Icons/ArrowDownAZ.svg.js.map +1 -0
  235. package/dist/es/components/Icons/ArrowDownNarrowWide.svg.js +23 -0
  236. package/dist/es/components/Icons/ArrowDownNarrowWide.svg.js.map +1 -0
  237. package/dist/es/components/Icons/ArrowDownWideNarrow.svg.js +23 -0
  238. package/dist/es/components/Icons/ArrowDownWideNarrow.svg.js.map +1 -0
  239. package/dist/es/components/Icons/ArrowDownZA.svg.js +23 -0
  240. package/dist/es/components/Icons/ArrowDownZA.svg.js.map +1 -0
  241. package/dist/es/components/Icons/ArrowUpDown.svg.js +23 -0
  242. package/dist/es/components/Icons/ArrowUpDown.svg.js.map +1 -0
  243. package/dist/es/components/Icons/BadgeCheck.svg.js +25 -0
  244. package/dist/es/components/Icons/BadgeCheck.svg.js.map +1 -0
  245. package/dist/es/components/Icons/Check.svg.js +23 -0
  246. package/dist/es/components/Icons/Check.svg.js.map +1 -0
  247. package/dist/es/components/Icons/ChevronDown.svg.js +23 -0
  248. package/dist/es/components/Icons/ChevronDown.svg.js.map +1 -0
  249. package/dist/es/components/Icons/ChevronLeft.svg.js +23 -0
  250. package/dist/es/components/Icons/ChevronLeft.svg.js.map +1 -0
  251. package/dist/es/components/Icons/ChevronRight.svg.js +23 -0
  252. package/dist/es/components/Icons/ChevronRight.svg.js.map +1 -0
  253. package/dist/es/components/Icons/CircleAlert.svg.js +27 -0
  254. package/dist/es/components/Icons/CircleAlert.svg.js.map +1 -0
  255. package/dist/es/components/Icons/CircleCheck.svg.js +27 -0
  256. package/dist/es/components/Icons/CircleCheck.svg.js.map +1 -0
  257. package/dist/es/components/Icons/CirclePlus.svg.js +27 -0
  258. package/dist/es/components/Icons/CirclePlus.svg.js.map +1 -0
  259. package/dist/es/components/Icons/CircleX.svg.js +27 -0
  260. package/dist/es/components/Icons/CircleX.svg.js.map +1 -0
  261. package/dist/es/components/Icons/FolderPlus.svg.js +23 -0
  262. package/dist/es/components/Icons/FolderPlus.svg.js.map +1 -0
  263. package/dist/es/components/Icons/Info.svg.js +27 -0
  264. package/dist/es/components/Icons/Info.svg.js.map +1 -0
  265. package/dist/es/components/Icons/Search.svg.js +27 -0
  266. package/dist/es/components/Icons/Search.svg.js.map +1 -0
  267. package/dist/es/components/Icons/Slash.svg.js +23 -0
  268. package/dist/es/components/Icons/Slash.svg.js.map +1 -0
  269. package/dist/es/components/Icons/TriangleAlert.svg.js +23 -0
  270. package/dist/es/components/Icons/TriangleAlert.svg.js.map +1 -0
  271. package/dist/es/components/Icons/X.svg.js +23 -0
  272. package/dist/es/components/Icons/X.svg.js.map +1 -0
  273. package/dist/es/components/Input/Input.js +82 -0
  274. package/dist/es/components/Input/Input.js.map +1 -0
  275. package/dist/es/components/Label/Label.js +12 -0
  276. package/dist/es/components/Label/Label.js.map +1 -0
  277. package/dist/es/components/Loader/index.js +16 -0
  278. package/dist/es/components/Loader/index.js.map +1 -0
  279. package/dist/es/components/MobileHeader/MobileHeader.js +43 -0
  280. package/dist/es/components/MobileHeader/MobileHeader.js.map +1 -0
  281. package/dist/es/components/MobilePicker/MobilePicker.js +366 -0
  282. package/dist/es/components/MobilePicker/MobilePicker.js.map +1 -0
  283. package/dist/es/components/MobileStepper/MobileStepper.js +31 -0
  284. package/dist/es/components/MobileStepper/MobileStepper.js.map +1 -0
  285. package/dist/es/components/Pagination/Pagination.js +31 -0
  286. package/dist/es/components/Pagination/Pagination.js.map +1 -0
  287. package/dist/es/components/Pagination/usePagination.js +30 -0
  288. package/dist/es/components/Pagination/usePagination.js.map +1 -0
  289. package/dist/es/components/PasswordInput/PasswordInput.js +51 -0
  290. package/dist/es/components/PasswordInput/PasswordInput.js.map +1 -0
  291. package/dist/es/components/PinInput/PinInput.js +96 -0
  292. package/dist/es/components/PinInput/PinInput.js.map +1 -0
  293. package/dist/es/components/PullToRefresh/PullToRefresh.js +81 -0
  294. package/dist/es/components/PullToRefresh/PullToRefresh.js.map +1 -0
  295. package/dist/es/components/QuantityStepper/QuantityStepper.js +75 -0
  296. package/dist/es/components/QuantityStepper/QuantityStepper.js.map +1 -0
  297. package/dist/es/components/Radio/Radio.js +32 -0
  298. package/dist/es/components/Radio/Radio.js.map +1 -0
  299. package/dist/es/components/RadioGroup/RadioGroup.js +48 -0
  300. package/dist/es/components/RadioGroup/RadioGroup.js.map +1 -0
  301. package/dist/es/components/RadioSwitch/RadioSwitch.js +114 -0
  302. package/dist/es/components/RadioSwitch/RadioSwitch.js.map +1 -0
  303. package/dist/es/components/RangeInput/RangeInput.js +64 -0
  304. package/dist/es/components/RangeInput/RangeInput.js.map +1 -0
  305. package/dist/es/components/RangeSlider/RangeSlider.js +165 -0
  306. package/dist/es/components/RangeSlider/RangeSlider.js.map +1 -0
  307. package/dist/es/components/SegmentedControl/SegmentedControl.js +62 -0
  308. package/dist/es/components/SegmentedControl/SegmentedControl.js.map +1 -0
  309. package/dist/es/components/SelectBox/SelectBox.js +303 -0
  310. package/dist/es/components/SelectBox/SelectBox.js.map +1 -0
  311. package/dist/es/components/Skeleton/Skeleton.js +34 -0
  312. package/dist/es/components/Skeleton/Skeleton.js.map +1 -0
  313. package/dist/es/components/StatusPill/StatusPill.js +44 -0
  314. package/dist/es/components/StatusPill/StatusPill.js.map +1 -0
  315. package/dist/es/components/StickyActionBar/StickyActionBar.js +20 -0
  316. package/dist/es/components/StickyActionBar/StickyActionBar.js.map +1 -0
  317. package/dist/es/components/SwipeableRow/SwipeableRow.js +185 -0
  318. package/dist/es/components/SwipeableRow/SwipeableRow.js.map +1 -0
  319. package/dist/es/components/SwipeableTabs/SwipeableTabs.js +89 -0
  320. package/dist/es/components/SwipeableTabs/SwipeableTabs.js.map +1 -0
  321. package/dist/es/components/Table/Table.js +48 -0
  322. package/dist/es/components/Table/Table.js.map +1 -0
  323. package/dist/es/components/Tabs/Tabs.js +51 -0
  324. package/dist/es/components/Tabs/Tabs.js.map +1 -0
  325. package/dist/es/components/TextContent/TextContent.js +45 -0
  326. package/dist/es/components/TextContent/TextContent.js.map +1 -0
  327. package/dist/es/components/Textarea/Textarea.js +62 -0
  328. package/dist/es/components/Textarea/Textarea.js.map +1 -0
  329. package/dist/es/components/Toast/Toast.js +94 -0
  330. package/dist/es/components/Toast/Toast.js.map +1 -0
  331. package/dist/es/components/Toast/ToastProvider.js +148 -0
  332. package/dist/es/components/Toast/ToastProvider.js.map +1 -0
  333. package/dist/es/components/VirtualizedDataTable/VirtualizedDataTable.js +120 -0
  334. package/dist/es/components/VirtualizedDataTable/VirtualizedDataTable.js.map +1 -0
  335. package/dist/es/components/VirtualizedDataTable/VirtualizedRow.js +46 -0
  336. package/dist/es/components/VirtualizedDataTable/VirtualizedRow.js.map +1 -0
  337. package/dist/es/components/WheelPicker/WheelPicker.js +80 -0
  338. package/dist/es/components/WheelPicker/WheelPicker.js.map +1 -0
  339. package/dist/es/components/common-responsive.js +287 -0
  340. package/dist/es/components/common-responsive.js.map +1 -0
  341. package/dist/es/hooks/use-debounce.js +28 -0
  342. package/dist/es/hooks/use-debounce.js.map +1 -0
  343. package/dist/es/hooks/use-is-mobile.js +22 -0
  344. package/dist/es/hooks/use-is-mobile.js.map +1 -0
  345. package/dist/es/hooks/use-is-tablet-or-mobile.js +11 -0
  346. package/dist/es/hooks/use-is-tablet-or-mobile.js.map +1 -0
  347. package/dist/es/hooks/use-is-tablet.js +19 -0
  348. package/dist/es/hooks/use-is-tablet.js.map +1 -0
  349. package/dist/es/index.js +67 -0
  350. package/dist/es/index.js.map +1 -0
  351. package/dist/es/react-tailwind.css +2 -0
  352. package/dist/es/react-tailwind.css.map +1 -0
  353. package/dist/es/utils/build-classname.js +6 -0
  354. package/dist/es/utils/build-classname.js.map +1 -0
  355. package/dist/es/utils/get.js +18 -0
  356. package/dist/es/utils/get.js.map +1 -0
  357. package/dist/es/utils/is-array.js +10 -0
  358. package/dist/es/utils/is-array.js.map +1 -0
  359. package/dist/es/utils/is-empty.js +24 -0
  360. package/dist/es/utils/is-empty.js.map +1 -0
  361. package/dist/react-tailwind.cjs.js +2298 -472
  362. package/dist/react-tailwind.cjs.js.map +1 -1
  363. package/dist/react-tailwind.es.js +2284 -474
  364. package/dist/react-tailwind.es.js.map +1 -1
  365. package/dist/types/components/ActionSheet/ActionSheet.d.ts +5 -0
  366. package/dist/types/components/ActionSheet/ActionSheet.test.d.ts +1 -0
  367. package/dist/types/components/ActionSheet/ActionSheet.types.d.ts +44 -0
  368. package/dist/types/components/ActionSheet/index.d.ts +2 -0
  369. package/dist/types/components/Badge/Badge.types.d.ts +1 -1
  370. package/dist/types/components/BottomNavigation/BottomNavigation.d.ts +5 -0
  371. package/dist/types/components/BottomNavigation/BottomNavigation.test.d.ts +1 -0
  372. package/dist/types/components/BottomNavigation/BottomNavigation.types.d.ts +41 -0
  373. package/dist/types/components/BottomNavigation/index.d.ts +2 -0
  374. package/dist/types/components/Card/Card.types.d.ts +25 -0
  375. package/dist/types/components/DataList/DataList.d.ts +5 -0
  376. package/dist/types/components/DataList/DataList.test.d.ts +1 -0
  377. package/dist/types/components/DataList/DataList.types.d.ts +81 -0
  378. package/dist/types/components/DataList/index.d.ts +2 -0
  379. package/dist/types/components/DataTable/DataTable.d.ts +1 -1
  380. package/dist/types/components/DataTable/DataTable.types.d.ts +10 -0
  381. package/dist/types/components/Flex/Flex.d.ts +3 -0
  382. package/dist/types/components/Flex/Flex.test.d.ts +1 -0
  383. package/dist/types/components/Flex/Flex.types.d.ts +92 -0
  384. package/dist/types/components/Flex/index.d.ts +2 -0
  385. package/dist/types/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  386. package/dist/types/components/FloatingActionButton/FloatingActionButton.test.d.ts +1 -0
  387. package/dist/types/components/FloatingActionButton/FloatingActionButton.types.d.ts +48 -0
  388. package/dist/types/components/FloatingActionButton/index.d.ts +2 -0
  389. package/dist/types/components/Grid/Grid.d.ts +3 -0
  390. package/dist/types/components/Grid/Grid.test.d.ts +1 -0
  391. package/dist/types/components/Grid/Grid.types.d.ts +136 -0
  392. package/dist/types/components/Grid/index.d.ts +2 -0
  393. package/dist/types/components/Input/Input.types.d.ts +3 -3
  394. package/dist/types/components/MobileHeader/MobileHeader.d.ts +5 -0
  395. package/dist/types/components/MobileHeader/MobileHeader.test.d.ts +1 -0
  396. package/dist/types/components/MobileHeader/MobileHeader.types.d.ts +49 -0
  397. package/dist/types/components/MobileHeader/index.d.ts +2 -0
  398. package/dist/types/components/MobilePicker/MobilePicker.d.ts +6 -0
  399. package/dist/types/components/MobilePicker/MobilePicker.test.d.ts +1 -0
  400. package/dist/types/components/MobilePicker/MobilePicker.types.d.ts +90 -0
  401. package/dist/types/components/MobilePicker/index.d.ts +2 -0
  402. package/dist/types/components/MobileStepper/MobileStepper.d.ts +5 -0
  403. package/dist/types/components/MobileStepper/MobileStepper.test.d.ts +1 -0
  404. package/dist/types/components/MobileStepper/MobileStepper.types.d.ts +28 -0
  405. package/dist/types/components/MobileStepper/index.d.ts +2 -0
  406. package/dist/types/components/PinInput/PinInput.d.ts +5 -0
  407. package/dist/types/components/PinInput/PinInput.test.d.ts +1 -0
  408. package/dist/types/components/PinInput/PinInput.types.d.ts +29 -0
  409. package/dist/types/components/PinInput/index.d.ts +2 -0
  410. package/dist/types/components/PullToRefresh/PullToRefresh.d.ts +5 -0
  411. package/dist/types/components/PullToRefresh/PullToRefresh.test.d.ts +1 -0
  412. package/dist/types/components/PullToRefresh/PullToRefresh.types.d.ts +23 -0
  413. package/dist/types/components/PullToRefresh/index.d.ts +2 -0
  414. package/dist/types/components/QuantityStepper/QuantityStepper.types.d.ts +18 -1
  415. package/dist/types/components/SelectBox/SelectBox.types.d.ts +9 -0
  416. package/dist/types/components/SwipeableRow/SwipeableRow.d.ts +3 -0
  417. package/dist/types/components/SwipeableRow/SwipeableRow.test.d.ts +1 -0
  418. package/dist/types/components/SwipeableRow/SwipeableRow.types.d.ts +42 -0
  419. package/dist/types/components/SwipeableRow/index.d.ts +2 -0
  420. package/dist/types/components/SwipeableTabs/SwipeableTabs.d.ts +5 -0
  421. package/dist/types/components/SwipeableTabs/SwipeableTabs.test.d.ts +1 -0
  422. package/dist/types/components/SwipeableTabs/SwipeableTabs.types.d.ts +38 -0
  423. package/dist/types/components/SwipeableTabs/index.d.ts +2 -0
  424. package/dist/types/components/WheelPicker/WheelPicker.d.ts +5 -0
  425. package/dist/types/components/WheelPicker/WheelPicker.test.d.ts +1 -0
  426. package/dist/types/components/WheelPicker/WheelPicker.types.d.ts +35 -0
  427. package/dist/types/components/WheelPicker/index.d.ts +2 -0
  428. package/dist/types/components/common-responsive.d.ts +57 -0
  429. package/dist/types/index.d.ts +14 -0
  430. package/package.json +11 -3
@@ -1,16 +1,16 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useRef, useImperativeHandle, useEffect, useCallback, Fragment as Fragment$1, useLayoutEffect, createContext, useContext } from 'react';
3
+ import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useRef, useImperativeHandle, useEffect, useCallback, Fragment as Fragment$1, createContext, useContext, useLayoutEffect } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { Dialog, DialogBackdrop, DialogPanel, DialogTitle, Menu, MenuButton, MenuItems, MenuItem, Combobox, ComboboxInput, ComboboxButton, ComboboxOptions, ComboboxOption, TabGroup, TabList, Tab, TabPanels, TabPanel, Transition } from '@headlessui/react';
6
6
  import { FixedSizeList } from 'react-window';
7
7
 
8
8
  const buildClassName = (...classes) => twMerge(classes.filter(Boolean));
9
9
 
10
- var _path$i;
11
- function _extends$i() { return _extends$i = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$i.apply(null, arguments); }
10
+ var _path$j;
11
+ function _extends$j() { return _extends$j = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$j.apply(null, arguments); }
12
12
  var SvgChevronDown = function SvgChevronDown(props) {
13
- return /*#__PURE__*/React.createElement("svg", _extends$i({
13
+ return /*#__PURE__*/React.createElement("svg", _extends$j({
14
14
  xmlns: "http://www.w3.org/2000/svg",
15
15
  width: 24,
16
16
  height: 24,
@@ -21,19 +21,19 @@ var SvgChevronDown = function SvgChevronDown(props) {
21
21
  strokeWidth: 2,
22
22
  className: "lucide lucide-chevron-down-icon lucide-chevron-down",
23
23
  viewBox: "0 0 24 24"
24
- }, props), _path$i || (_path$i = /*#__PURE__*/React.createElement("path", {
24
+ }, props), _path$j || (_path$j = /*#__PURE__*/React.createElement("path", {
25
25
  d: "m6 9 6 6 6-6"
26
26
  })));
27
27
  };
28
28
 
29
29
  const CONTAINER_CLASS = {
30
- bordered: 'rounded-lg border border-gray-200 dark:border-white/10 divide-y divide-gray-200 dark:divide-white/10 bg-white dark:bg-gray-800 overflow-hidden',
30
+ bordered: 'rounded-lg border border-[var(--ui-border)] divide-y divide-[var(--ui-border)] bg-white dark:bg-gray-800 overflow-hidden',
31
31
  separated: 'space-y-2',
32
- plain: 'divide-y divide-gray-200 dark:divide-white/10',
32
+ plain: 'divide-y divide-[var(--ui-border)]',
33
33
  };
34
34
  const ITEM_CLASS = {
35
35
  bordered: '',
36
- separated: 'rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-gray-800 overflow-hidden',
36
+ separated: 'rounded-lg border border-[var(--ui-border)] bg-white dark:bg-gray-800 overflow-hidden',
37
37
  plain: '',
38
38
  };
39
39
  const HEADER_CLASS = 'flex w-full items-center justify-between gap-2 py-3 px-4 text-left text-sm font-medium ' +
@@ -78,115 +78,6 @@ const Accordion = ({ items, type = 'single', variant = 'bordered', collapsible =
78
78
  };
79
79
  Accordion.displayName = 'Accordion';
80
80
 
81
- var _path$h, _path2;
82
- function _extends$h() { return _extends$h = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$h.apply(null, arguments); }
83
- var SvgBadgeCheck = function SvgBadgeCheck(props) {
84
- return /*#__PURE__*/React.createElement("svg", _extends$h({
85
- xmlns: "http://www.w3.org/2000/svg",
86
- width: 24,
87
- height: 24,
88
- fill: "none",
89
- stroke: "currentColor",
90
- strokeLinecap: "round",
91
- strokeLinejoin: "round",
92
- strokeWidth: 2,
93
- className: "lucide lucide-badge-check-icon lucide-badge-check",
94
- viewBox: "0 0 24 24"
95
- }, props), _path$h || (_path$h = /*#__PURE__*/React.createElement("path", {
96
- d: "M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76"
97
- })), _path2 || (_path2 = /*#__PURE__*/React.createElement("path", {
98
- d: "m9 12 2 2 4-4"
99
- })));
100
- };
101
-
102
- var _circle$4, _path$g;
103
- function _extends$g() { return _extends$g = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$g.apply(null, arguments); }
104
- var SvgCircleX = function SvgCircleX(props) {
105
- return /*#__PURE__*/React.createElement("svg", _extends$g({
106
- xmlns: "http://www.w3.org/2000/svg",
107
- width: 24,
108
- height: 24,
109
- fill: "none",
110
- stroke: "currentColor",
111
- strokeLinecap: "round",
112
- strokeLinejoin: "round",
113
- strokeWidth: 2,
114
- className: "lucide lucide-circle-x-icon lucide-circle-x",
115
- viewBox: "0 0 24 24"
116
- }, props), _circle$4 || (_circle$4 = /*#__PURE__*/React.createElement("circle", {
117
- cx: 12,
118
- cy: 12,
119
- r: 10
120
- })), _path$g || (_path$g = /*#__PURE__*/React.createElement("path", {
121
- d: "m15 9-6 6M9 9l6 6"
122
- })));
123
- };
124
-
125
- var _circle$3, _path$f;
126
- function _extends$f() { return _extends$f = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$f.apply(null, arguments); }
127
- var SvgCircleAlert = function SvgCircleAlert(props) {
128
- return /*#__PURE__*/React.createElement("svg", _extends$f({
129
- xmlns: "http://www.w3.org/2000/svg",
130
- width: 24,
131
- height: 24,
132
- fill: "none",
133
- stroke: "currentColor",
134
- strokeLinecap: "round",
135
- strokeLinejoin: "round",
136
- strokeWidth: 2,
137
- className: "lucide lucide-circle-alert-icon lucide-circle-alert",
138
- viewBox: "0 0 24 24"
139
- }, props), _circle$3 || (_circle$3 = /*#__PURE__*/React.createElement("circle", {
140
- cx: 12,
141
- cy: 12,
142
- r: 10
143
- })), _path$f || (_path$f = /*#__PURE__*/React.createElement("path", {
144
- d: "M12 8v4M12 16h.01"
145
- })));
146
- };
147
-
148
- var _circle$2, _path$e;
149
- function _extends$e() { return _extends$e = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$e.apply(null, arguments); }
150
- var SvgInfo = function SvgInfo(props) {
151
- return /*#__PURE__*/React.createElement("svg", _extends$e({
152
- xmlns: "http://www.w3.org/2000/svg",
153
- width: 24,
154
- height: 24,
155
- fill: "none",
156
- stroke: "currentColor",
157
- strokeLinecap: "round",
158
- strokeLinejoin: "round",
159
- strokeWidth: 2,
160
- className: "lucide lucide-info-icon lucide-info",
161
- viewBox: "0 0 24 24"
162
- }, props), _circle$2 || (_circle$2 = /*#__PURE__*/React.createElement("circle", {
163
- cx: 12,
164
- cy: 12,
165
- r: 10
166
- })), _path$e || (_path$e = /*#__PURE__*/React.createElement("path", {
167
- d: "M12 16v-4M12 8h.01"
168
- })));
169
- };
170
-
171
- var _path$d;
172
- function _extends$d() { return _extends$d = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$d.apply(null, arguments); }
173
- var SvgX = function SvgX(props) {
174
- return /*#__PURE__*/React.createElement("svg", _extends$d({
175
- xmlns: "http://www.w3.org/2000/svg",
176
- width: 24,
177
- height: 24,
178
- fill: "none",
179
- stroke: "currentColor",
180
- strokeLinecap: "round",
181
- strokeLinejoin: "round",
182
- strokeWidth: 2,
183
- className: "lucide lucide-x-icon lucide-x",
184
- viewBox: "0 0 24 24"
185
- }, props), _path$d || (_path$d = /*#__PURE__*/React.createElement("path", {
186
- d: "M18 6 6 18M6 6l12 12"
187
- })));
188
- };
189
-
190
81
  const loaderSizeMap = {
191
82
  xs: 'size-4',
192
83
  sm: 'size-6',
@@ -253,8 +144,8 @@ const THEMED_BTN_CLASS = {
253
144
  plain: 'text-[var(--ui-danger-text)] hover:bg-black/5 dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:text-[var(--ui-danger-disabled)]',
254
145
  },
255
146
  secondary: {
256
- default: 'text-gray-700 bg-white border border-gray-300 hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:bg-gray-200 dark:disabled:bg-gray-700',
257
- outlined: 'text-gray-700 hover:text-white border border-gray-500 hover:bg-gray-700 dark:border-gray-500 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400 disabled:border-gray-400',
147
+ default: 'text-gray-700 bg-white border border-[var(--ui-border)] hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:bg-gray-200 dark:disabled:bg-gray-700',
148
+ outlined: 'text-gray-700 hover:text-white border border-[var(--ui-border)] hover:bg-gray-700 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400 disabled:border-[var(--ui-border-muted)]',
258
149
  plain: 'text-gray-700 hover:bg-black/5 dark:text-gray-200 dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400',
259
150
  },
260
151
  success: {
@@ -346,52 +237,132 @@ const Button = forwardRef(({ as, type, ...props }, ref) => {
346
237
  });
347
238
  Button.displayName = 'Button';
348
239
 
349
- const AlertTypeIconMap = {
350
- success: SvgBadgeCheck,
351
- danger: SvgCircleX,
352
- warning: SvgCircleAlert,
353
- info: SvgInfo,
240
+ var _path$i;
241
+ function _extends$i() { return _extends$i = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$i.apply(null, arguments); }
242
+ var SvgChevronLeft = function SvgChevronLeft(props) {
243
+ return /*#__PURE__*/React.createElement("svg", _extends$i({
244
+ xmlns: "http://www.w3.org/2000/svg",
245
+ width: 24,
246
+ height: 24,
247
+ fill: "none",
248
+ stroke: "currentColor",
249
+ strokeLinecap: "round",
250
+ strokeLinejoin: "round",
251
+ strokeWidth: 2,
252
+ className: "lucide lucide-chevron-left-icon lucide-chevron-left",
253
+ viewBox: "0 0 24 24"
254
+ }, props), _path$i || (_path$i = /*#__PURE__*/React.createElement("path", {
255
+ d: "m15 18-6-6 6-6"
256
+ })));
354
257
  };
355
- const TypeClassMap$1 = {
356
- success: 'bg-[var(--ui-success-light)] ring-[var(--ui-success-ring-subtle)] text-[var(--ui-success-text)]',
357
- danger: 'bg-[var(--ui-danger-light)] ring-[var(--ui-danger-ring-subtle)] text-[var(--ui-danger-text)]',
358
- warning: 'bg-[var(--ui-warning-light)] ring-[var(--ui-warning-ring-subtle)] text-[var(--ui-warning-text)]',
359
- info: 'bg-[var(--ui-info-light)] ring-[var(--ui-info-ring-subtle)] text-[var(--ui-info-text)]',
258
+
259
+ var _path$h;
260
+ function _extends$h() { return _extends$h = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$h.apply(null, arguments); }
261
+ var SvgX = function SvgX(props) {
262
+ return /*#__PURE__*/React.createElement("svg", _extends$h({
263
+ xmlns: "http://www.w3.org/2000/svg",
264
+ width: 24,
265
+ height: 24,
266
+ fill: "none",
267
+ stroke: "currentColor",
268
+ strokeLinecap: "round",
269
+ strokeLinejoin: "round",
270
+ strokeWidth: 2,
271
+ className: "lucide lucide-x-icon lucide-x",
272
+ viewBox: "0 0 24 24"
273
+ }, props), _path$h || (_path$h = /*#__PURE__*/React.createElement("path", {
274
+ d: "M18 6 6 18M6 6l12 12"
275
+ })));
360
276
  };
361
- const Alert = forwardRef((props, ref) => {
362
- const { type = 'info', className, message, children, removable = false, onRemove, icon, title, ...restProps } = props;
363
- const DefaultIcon = AlertTypeIconMap[type] || SvgInfo;
364
- const iconNode = icon !== undefined ? (icon) : (jsx(DefaultIcon, { className: "size-5 shrink-0", "data-testid": `alert-${type}-icon` }));
365
- return (jsxs("div", { ref: ref, className: buildClassName('flex items-center justify-between rounded-md p-3 text-sm ring-1 ring-inset gap-2', TypeClassMap$1[type], className), ...restProps, children: [jsxs("span", { className: "inline-flex items-start gap-2 min-w-0", children: [iconNode && jsx("span", { className: "shrink-0 inline-flex mt-0.5", children: iconNode }), jsxs("span", { className: "inline-flex flex-col gap-0.5 min-w-0", children: [title && jsx("span", { className: "font-semibold", children: title }), jsx("span", { className: "inline-flex items-center", children: message !== null && message !== void 0 ? message : children })] })] }), removable && (jsx(Button, { iconOnly: true, "aria-label": "Dismiss alert", size: "xs", variant: "plain", theme: "secondary", className: "hover:bg-black/10 dark:hover:bg-white/10 shrink-0", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(), "data-testid": "alert-remove-btn", children: jsx(SvgX, { className: "size-4.5", "data-testid": "alert-remove-icon" }) }))] }));
366
- });
367
- Alert.displayName = 'Alert';
368
277
 
369
- const ThemeClassMap = {
370
- success: 'bg-[var(--ui-success-light)] text-[var(--ui-success-text)] ring-[var(--ui-success-ring-subtle)]',
371
- danger: 'bg-[var(--ui-danger-light)] text-[var(--ui-danger-text)] ring-[var(--ui-danger-ring-subtle)]',
372
- warning: 'bg-[var(--ui-warning-light)] text-[var(--ui-warning-text)] ring-[var(--ui-warning-ring-subtle)]',
373
- info: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
374
- secondary: 'bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 ring-[var(--ui-secondary-ring-subtle)]',
278
+ const alignmentMap = {
279
+ center: 'items-center justify-center h-full',
280
+ start: 'justify-start h-full',
281
+ end: 'justify-end h-full',
282
+ top: 'items-start justify-center w-full',
283
+ bottom: 'items-end justify-center h-full',
375
284
  };
376
- const SIZE_CLASS$1 = {
377
- sm: 'text-xs py-0.5 px-2',
378
- md: 'text-xs py-1 px-3',
285
+ const panelAlignmentMap = {
286
+ center: 'data-[closed]:scale-95 rounded-2xl',
287
+ start: 'data-[closed]:-translate-x-1/2 rounded-r-2xl',
288
+ end: 'data-[closed]:translate-x-1/2 rounded-l-2xl',
289
+ top: 'data-[closed]:-translate-y-1/2 rounded-b-2xl',
290
+ bottom: 'data-[closed]:translate-y-full rounded-t-2xl md:rounded-t-3xl max-h-[88vh] max-h-[88dvh]',
379
291
  };
380
- const Badge = forwardRef((props, ref) => {
381
- const { theme = 'info', className, children, removable = false, rounded = false, onRemove, size = 'md', icon, ...restProps } = props;
382
- return (jsxs(TextContent, { ref: ref, className: buildClassName('inline-flex items-center gap-1 font-medium ring-1 ring-inset', SIZE_CLASS$1[size], ThemeClassMap[theme], rounded ? 'rounded-full' : 'rounded-md', icon ? 'pl-2' : '', removable ? 'pr-1' : '', className), "data-testid": `badge-${theme}`, ...restProps, children: [icon && jsx("span", { className: "shrink-0 inline-flex", children: icon }), children, removable && (jsx(SvgX, { className: "size-4 shrink-0 hover:bg-black/10 dark:hover:bg-white/10 rounded-sm cursor-pointer", role: "button", tabIndex: 0, "aria-label": "Remove", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(), onKeyDown: (e) => {
383
- if (e.key === 'Enter' || e.key === ' ') {
384
- e.preventDefault();
385
- onRemove === null || onRemove === void 0 ? void 0 : onRemove();
386
- }
387
- } }))] }));
388
- });
389
- Badge.displayName = 'Badge';
292
+ const panelSizeMap = {
293
+ xs: 'max-w-xs',
294
+ sm: 'max-w-sm',
295
+ md: 'max-w-md',
296
+ lg: 'max-w-lg',
297
+ xl: 'max-w-xl',
298
+ '2xl': 'max-w-2xl',
299
+ full: 'w-full',
300
+ };
301
+ const Drawer = ({ isOpen, onClose = () => { }, closeOnOutsideClick = true, align = 'end', size = 'md', backdrop = true, title, description, children, footer, footerSticky = false, panelClass = '', contentClass = '', titleClass = '', descriptionClass = '', titleSticky = false, showBackButton = false, showCloseButton = true, dragHandle, }) => {
302
+ const showTitleSection = Boolean(title || description || showBackButton || showCloseButton);
303
+ const shouldShowDragHandle = dragHandle !== null && dragHandle !== void 0 ? dragHandle : align === 'bottom';
304
+ const [viewportHeight, setViewportHeight] = React__default.useState(null);
305
+ React__default.useEffect(() => {
306
+ if (!isOpen) {
307
+ setViewportHeight(null);
308
+ return;
309
+ }
310
+ const updateHeight = () => {
311
+ if (typeof window !== 'undefined' && window.visualViewport) {
312
+ setViewportHeight(window.visualViewport.height);
313
+ }
314
+ };
315
+ updateHeight();
316
+ const vv = typeof window !== 'undefined' ? window.visualViewport : null;
317
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('resize', updateHeight);
318
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('scroll', updateHeight);
319
+ return () => {
320
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('resize', updateHeight);
321
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('scroll', updateHeight);
322
+ };
323
+ }, [isOpen]);
324
+ const handleDialogClose = () => {
325
+ if (closeOnOutsideClick) {
326
+ onClose === null || onClose === void 0 ? void 0 : onClose();
327
+ }
328
+ };
329
+ return (jsxs(Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: handleDialogClose, transition: true, children: [backdrop && (jsx(DialogBackdrop, { className: "fixed inset-0 bg-black/40 backdrop-blur-xs transition-opacity duration-200" })), jsx("div", { className: "fixed left-0 top-0 w-full", style: { height: viewportHeight ? `${viewportHeight}px` : '100dvh' }, children: jsx("div", { className: buildClassName('flex', alignmentMap[align]), children: jsxs(DialogPanel, { transition: true, className: buildClassName('w-full max-w-full bg-white dark:bg-gray-800 shadow-xl flex flex-col min-w-0', 'overflow-y-auto overflow-x-hidden overscroll-contain touch-pan-y [-webkit-overflow-scrolling:touch] duration-200 ease-out data-[closed]:opacity-0', panelAlignmentMap[align], panelSizeMap[size], panelClass), children: [shouldShowDragHandle && (jsx("div", { className: "w-12 h-1.5 rounded-full bg-gray-300 dark:bg-gray-600 mx-auto my-2.5 shrink-0 cursor-grab", "data-testid": "drawer-drag-handle" })), showTitleSection && (jsxs("div", { className: buildClassName('space-y-1 py-3 px-4 md:px-6 flex flex-col border-b border-[var(--ui-border)] shrink-0', titleSticky && 'sticky top-0 bg-white dark:bg-gray-800 z-10'), children: [jsxs("div", { className: "flex items-center justify-between gap-3 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [showBackButton && (jsx(Button, { iconOnly: true, "aria-label": "Back", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, children: jsx(SvgChevronLeft, { className: "size-4" }) })), title && (jsx(DialogTitle, { as: "h3", className: buildClassName('text-lg font-semibold text-gray-900 dark:text-white truncate tracking-tight min-w-0', titleClass), children: title }))] }), showCloseButton && (jsx(Button, { iconOnly: true, "aria-label": "Close drawer", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, className: "rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 shrink-0", children: jsx(SvgX, { className: "size-4" }) }))] }), description && (jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal truncate', descriptionClass), children: description }))] })), jsx("div", { className: buildClassName('flex-1 p-4 md:p-6 space-y-4 min-w-0', contentClass), children: children }), footer && (jsx("div", { className: buildClassName('p-4 border-t border-[var(--ui-border-muted)] bg-white dark:bg-gray-800 shrink-0 min-w-0', footerSticky && 'sticky bottom-0 z-10'), children: footer }))] }) }) })] }));
330
+ };
331
+ Drawer.displayName = 'Drawer';
390
332
 
391
- var _path$c;
392
- function _extends$c() { return _extends$c = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$c.apply(null, arguments); }
393
- var SvgTriangleAlert = function SvgTriangleAlert(props) {
394
- return /*#__PURE__*/React.createElement("svg", _extends$c({
333
+ function ActionSheet({ isOpen, onClose, title, description, actions, showCancelButton = true, cancelLabel = 'Cancel', onCancel, closeOnBackdropClick = true, dragHandle = true, panelClass = '', containerClass = '', }) {
334
+ const handleItemClick = (action) => {
335
+ var _a;
336
+ if (action.disabled)
337
+ return;
338
+ (_a = action.onClick) === null || _a === void 0 ? void 0 : _a.call(action);
339
+ onClose();
340
+ };
341
+ const handleCancelClick = () => {
342
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
343
+ onClose();
344
+ };
345
+ return (jsx(Drawer, { isOpen: isOpen, onClose: onClose, align: "bottom", closeOnOutsideClick: closeOnBackdropClick, showCloseButton: false, dragHandle: dragHandle, panelClass: buildClassName('rounded-t-2xl max-h-[85vh] overflow-hidden', panelClass), "data-testid": "action-sheet-drawer", children: jsxs("div", { className: buildClassName('space-y-4 py-1', containerClass), "data-testid": "action-sheet", children: [(title || description) && (jsxs("div", { className: "text-center px-4 pb-2 border-b border-[var(--ui-border-muted)]", children: [title && (jsx("h3", { className: "text-sm font-bold text-gray-900 dark:text-white truncate", children: title })), description && (jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate", children: description }))] })), jsx("div", { className: "space-y-1 bg-gray-50 dark:bg-gray-800/60 p-1.5 rounded-2xl border border-[var(--ui-border-muted)]", children: actions.map((action) => {
346
+ const isDanger = action.theme === 'danger';
347
+ const isPrimary = action.theme === 'primary';
348
+ return (jsxs("button", { type: "button", disabled: action.disabled, onClick: () => handleItemClick(action), className: buildClassName('w-full flex items-center gap-3.5 p-3 rounded-xl text-left transition-all duration-150 group cursor-pointer', action.disabled && 'opacity-50 cursor-not-allowed pointer-events-none', !action.disabled &&
349
+ (isDanger
350
+ ? 'hover:bg-red-50 dark:hover:bg-red-950/40 text-red-600 dark:text-red-400 font-semibold'
351
+ : isPrimary
352
+ ? 'hover:bg-blue-50 dark:hover:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
353
+ : 'hover:bg-white dark:hover:bg-gray-800 text-gray-800 dark:text-gray-200 font-medium')), "data-testid": `action-sheet-item-${action.id}`, children: [action.icon && (jsx("span", { className: buildClassName('shrink-0 text-base transition-colors', isDanger
354
+ ? 'text-red-500 dark:text-red-400'
355
+ : isPrimary
356
+ ? 'text-blue-500 dark:text-blue-400'
357
+ : 'text-gray-500 dark:text-gray-400 group-hover:text-gray-700 dark:group-hover:text-gray-200'), children: action.icon })), jsxs("div", { className: "min-w-0 flex-1", children: [jsx("div", { className: "text-sm truncate", children: action.label }), action.description && (jsx("div", { className: "text-xs text-gray-400 dark:text-gray-500 truncate font-normal mt-0.5", children: action.description }))] })] }, action.id));
358
+ }) }), showCancelButton && (jsx("div", { className: "pt-1", children: jsx(Button, { theme: "secondary", size: "lg", fullWidth: true, onClick: handleCancelClick, className: "font-semibold text-sm rounded-xl py-3", "data-testid": "action-sheet-cancel-btn", children: cancelLabel }) }))] }) }));
359
+ }
360
+ ActionSheet.displayName = 'ActionSheet';
361
+
362
+ var _path$g, _path2;
363
+ function _extends$g() { return _extends$g = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$g.apply(null, arguments); }
364
+ var SvgBadgeCheck = function SvgBadgeCheck(props) {
365
+ return /*#__PURE__*/React.createElement("svg", _extends$g({
395
366
  xmlns: "http://www.w3.org/2000/svg",
396
367
  width: 24,
397
368
  height: 24,
@@ -400,17 +371,19 @@ var SvgTriangleAlert = function SvgTriangleAlert(props) {
400
371
  strokeLinecap: "round",
401
372
  strokeLinejoin: "round",
402
373
  strokeWidth: 2,
403
- className: "lucide lucide-triangle-alert-icon lucide-triangle-alert",
374
+ className: "lucide lucide-badge-check-icon lucide-badge-check",
404
375
  viewBox: "0 0 24 24"
405
- }, props), _path$c || (_path$c = /*#__PURE__*/React.createElement("path", {
406
- d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4M12 17h.01"
376
+ }, props), _path$g || (_path$g = /*#__PURE__*/React.createElement("path", {
377
+ d: "M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76"
378
+ })), _path2 || (_path2 = /*#__PURE__*/React.createElement("path", {
379
+ d: "m9 12 2 2 4-4"
407
380
  })));
408
381
  };
409
382
 
410
- var _circle$1, _path$b;
411
- function _extends$b() { return _extends$b = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$b.apply(null, arguments); }
412
- var SvgCircleCheck = function SvgCircleCheck(props) {
413
- return /*#__PURE__*/React.createElement("svg", _extends$b({
383
+ var _circle$5, _path$f;
384
+ function _extends$f() { return _extends$f = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$f.apply(null, arguments); }
385
+ var SvgCircleX = function SvgCircleX(props) {
386
+ return /*#__PURE__*/React.createElement("svg", _extends$f({
414
387
  xmlns: "http://www.w3.org/2000/svg",
415
388
  width: 24,
416
389
  height: 24,
@@ -419,29 +392,160 @@ var SvgCircleCheck = function SvgCircleCheck(props) {
419
392
  strokeLinecap: "round",
420
393
  strokeLinejoin: "round",
421
394
  strokeWidth: 2,
422
- className: "lucide lucide-circle-check-icon lucide-circle-check",
395
+ className: "lucide lucide-circle-x-icon lucide-circle-x",
423
396
  viewBox: "0 0 24 24"
424
- }, props), _circle$1 || (_circle$1 = /*#__PURE__*/React.createElement("circle", {
397
+ }, props), _circle$5 || (_circle$5 = /*#__PURE__*/React.createElement("circle", {
425
398
  cx: 12,
426
399
  cy: 12,
427
400
  r: 10
428
- })), _path$b || (_path$b = /*#__PURE__*/React.createElement("path", {
429
- d: "m9 12 2 2 4-4"
401
+ })), _path$f || (_path$f = /*#__PURE__*/React.createElement("path", {
402
+ d: "m15 9-6 6M9 9l6 6"
430
403
  })));
431
404
  };
432
405
 
433
- const sizeMap = {
434
- xs: 'size-4',
435
- sm: 'size-5',
436
- md: 'size-6',
437
- lg: 'size-8',
438
- xl: 'size-10',
439
- };
440
- const IconMap = {
441
- info: SvgInfo,
442
- error: SvgCircleX,
443
- success: SvgCircleCheck,
444
- warning: SvgTriangleAlert,
406
+ var _circle$4, _path$e;
407
+ function _extends$e() { return _extends$e = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$e.apply(null, arguments); }
408
+ var SvgCircleAlert = function SvgCircleAlert(props) {
409
+ return /*#__PURE__*/React.createElement("svg", _extends$e({
410
+ xmlns: "http://www.w3.org/2000/svg",
411
+ width: 24,
412
+ height: 24,
413
+ fill: "none",
414
+ stroke: "currentColor",
415
+ strokeLinecap: "round",
416
+ strokeLinejoin: "round",
417
+ strokeWidth: 2,
418
+ className: "lucide lucide-circle-alert-icon lucide-circle-alert",
419
+ viewBox: "0 0 24 24"
420
+ }, props), _circle$4 || (_circle$4 = /*#__PURE__*/React.createElement("circle", {
421
+ cx: 12,
422
+ cy: 12,
423
+ r: 10
424
+ })), _path$e || (_path$e = /*#__PURE__*/React.createElement("path", {
425
+ d: "M12 8v4M12 16h.01"
426
+ })));
427
+ };
428
+
429
+ var _circle$3, _path$d;
430
+ function _extends$d() { return _extends$d = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$d.apply(null, arguments); }
431
+ var SvgInfo = function SvgInfo(props) {
432
+ return /*#__PURE__*/React.createElement("svg", _extends$d({
433
+ xmlns: "http://www.w3.org/2000/svg",
434
+ width: 24,
435
+ height: 24,
436
+ fill: "none",
437
+ stroke: "currentColor",
438
+ strokeLinecap: "round",
439
+ strokeLinejoin: "round",
440
+ strokeWidth: 2,
441
+ className: "lucide lucide-info-icon lucide-info",
442
+ viewBox: "0 0 24 24"
443
+ }, props), _circle$3 || (_circle$3 = /*#__PURE__*/React.createElement("circle", {
444
+ cx: 12,
445
+ cy: 12,
446
+ r: 10
447
+ })), _path$d || (_path$d = /*#__PURE__*/React.createElement("path", {
448
+ d: "M12 16v-4M12 8h.01"
449
+ })));
450
+ };
451
+
452
+ const AlertTypeIconMap = {
453
+ success: SvgBadgeCheck,
454
+ danger: SvgCircleX,
455
+ warning: SvgCircleAlert,
456
+ info: SvgInfo,
457
+ };
458
+ const TypeClassMap$1 = {
459
+ success: 'bg-[var(--ui-success-light)] ring-[var(--ui-success-ring-subtle)] text-[var(--ui-success-text)]',
460
+ danger: 'bg-[var(--ui-danger-light)] ring-[var(--ui-danger-ring-subtle)] text-[var(--ui-danger-text)]',
461
+ warning: 'bg-[var(--ui-warning-light)] ring-[var(--ui-warning-ring-subtle)] text-[var(--ui-warning-text)]',
462
+ info: 'bg-[var(--ui-info-light)] ring-[var(--ui-info-ring-subtle)] text-[var(--ui-info-text)]',
463
+ };
464
+ const Alert = forwardRef((props, ref) => {
465
+ const { type = 'info', className, message, children, removable = false, onRemove, icon, title, ...restProps } = props;
466
+ const DefaultIcon = AlertTypeIconMap[type] || SvgInfo;
467
+ const iconNode = icon !== undefined ? (icon) : (jsx(DefaultIcon, { className: "size-5 shrink-0", "data-testid": `alert-${type}-icon` }));
468
+ return (jsxs("div", { ref: ref, className: buildClassName('flex items-center justify-between rounded-md p-3 text-sm ring-1 ring-inset gap-2', TypeClassMap$1[type], className), ...restProps, children: [jsxs("span", { className: "inline-flex items-start gap-2 min-w-0", children: [iconNode && jsx("span", { className: "shrink-0 inline-flex mt-0.5", children: iconNode }), jsxs("span", { className: "inline-flex flex-col gap-0.5 min-w-0", children: [title && jsx("span", { className: "font-semibold", children: title }), jsx("span", { className: "inline-flex items-center", children: message !== null && message !== void 0 ? message : children })] })] }), removable && (jsx(Button, { iconOnly: true, "aria-label": "Dismiss alert", size: "xs", variant: "plain", theme: "secondary", className: "hover:bg-black/10 dark:hover:bg-white/10 shrink-0", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(), "data-testid": "alert-remove-btn", children: jsx(SvgX, { className: "size-4.5", "data-testid": "alert-remove-icon" }) }))] }));
469
+ });
470
+ Alert.displayName = 'Alert';
471
+
472
+ const ThemeClassMap = {
473
+ success: 'bg-[var(--ui-success-light)] text-[var(--ui-success-text)] ring-[var(--ui-success-ring-subtle)]',
474
+ danger: 'bg-[var(--ui-danger-light)] text-[var(--ui-danger-text)] ring-[var(--ui-danger-ring-subtle)]',
475
+ warning: 'bg-[var(--ui-warning-light)] text-[var(--ui-warning-text)] ring-[var(--ui-warning-ring-subtle)]',
476
+ info: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
477
+ primary: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
478
+ secondary: 'bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 ring-[var(--ui-secondary-ring-subtle)]',
479
+ };
480
+ const SIZE_CLASS$1 = {
481
+ sm: 'text-xs py-0.5 px-2',
482
+ md: 'text-xs py-1 px-3',
483
+ };
484
+ const Badge = forwardRef((props, ref) => {
485
+ const { theme = 'info', className, children, removable = false, rounded = false, onRemove, size = 'md', icon, ...restProps } = props;
486
+ return (jsxs(TextContent, { ref: ref, className: buildClassName('inline-flex items-center gap-1 font-medium ring-1 ring-inset', SIZE_CLASS$1[size], ThemeClassMap[theme] || ThemeClassMap.info, rounded ? 'rounded-full' : 'rounded-md', icon ? 'pl-2' : '', removable ? 'pr-1' : '', className), "data-testid": `badge-${theme}`, ...restProps, children: [icon && jsx("span", { className: "shrink-0 inline-flex", children: icon }), children, removable && (jsx(SvgX, { className: "size-4 shrink-0 hover:bg-black/10 dark:hover:bg-white/10 rounded-sm cursor-pointer", role: "button", tabIndex: 0, "aria-label": "Remove", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(), onKeyDown: (e) => {
487
+ if (e.key === 'Enter' || e.key === ' ') {
488
+ e.preventDefault();
489
+ onRemove === null || onRemove === void 0 ? void 0 : onRemove();
490
+ }
491
+ } }))] }));
492
+ });
493
+ Badge.displayName = 'Badge';
494
+
495
+ var _path$c;
496
+ function _extends$c() { return _extends$c = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$c.apply(null, arguments); }
497
+ var SvgTriangleAlert = function SvgTriangleAlert(props) {
498
+ return /*#__PURE__*/React.createElement("svg", _extends$c({
499
+ xmlns: "http://www.w3.org/2000/svg",
500
+ width: 24,
501
+ height: 24,
502
+ fill: "none",
503
+ stroke: "currentColor",
504
+ strokeLinecap: "round",
505
+ strokeLinejoin: "round",
506
+ strokeWidth: 2,
507
+ className: "lucide lucide-triangle-alert-icon lucide-triangle-alert",
508
+ viewBox: "0 0 24 24"
509
+ }, props), _path$c || (_path$c = /*#__PURE__*/React.createElement("path", {
510
+ d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4M12 17h.01"
511
+ })));
512
+ };
513
+
514
+ var _circle$2, _path$b;
515
+ function _extends$b() { return _extends$b = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$b.apply(null, arguments); }
516
+ var SvgCircleCheck = function SvgCircleCheck(props) {
517
+ return /*#__PURE__*/React.createElement("svg", _extends$b({
518
+ xmlns: "http://www.w3.org/2000/svg",
519
+ width: 24,
520
+ height: 24,
521
+ fill: "none",
522
+ stroke: "currentColor",
523
+ strokeLinecap: "round",
524
+ strokeLinejoin: "round",
525
+ strokeWidth: 2,
526
+ className: "lucide lucide-circle-check-icon lucide-circle-check",
527
+ viewBox: "0 0 24 24"
528
+ }, props), _circle$2 || (_circle$2 = /*#__PURE__*/React.createElement("circle", {
529
+ cx: 12,
530
+ cy: 12,
531
+ r: 10
532
+ })), _path$b || (_path$b = /*#__PURE__*/React.createElement("path", {
533
+ d: "m9 12 2 2 4-4"
534
+ })));
535
+ };
536
+
537
+ const sizeMap = {
538
+ xs: 'size-4',
539
+ sm: 'size-5',
540
+ md: 'size-6',
541
+ lg: 'size-8',
542
+ xl: 'size-10',
543
+ };
544
+ const IconMap = {
545
+ info: SvgInfo,
546
+ error: SvgCircleX,
547
+ success: SvgCircleCheck,
548
+ warning: SvgTriangleAlert,
445
549
  };
446
550
  const TypeClassMap = {
447
551
  info: 'bg-[var(--ui-info-light)] ring-[var(--ui-info-ring-subtle)] text-[var(--ui-info-text)]',
@@ -509,6 +613,51 @@ const BodyText = forwardRef((props, ref) => {
509
613
  });
510
614
  BodyText.displayName = 'BodyText';
511
615
 
616
+ function BottomNavigation({ items, activeId, onChange, fixed = true, showLabels = 'always', theme = 'light', activeIndicatorStyle = 'line', containerClass = '', itemClass = '', }) {
617
+ const handleTabClick = (item) => {
618
+ var _a;
619
+ if (item.disabled)
620
+ return;
621
+ (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item);
622
+ onChange(item.id);
623
+ };
624
+ const themeStyles = {
625
+ light: 'bg-white dark:bg-gray-900 border-t border-[var(--ui-border)] text-gray-600 dark:text-gray-400',
626
+ dark: 'bg-gray-900 text-gray-400 border-t border-gray-800',
627
+ primary: 'bg-blue-600 text-blue-100 border-t border-blue-700',
628
+ }[theme];
629
+ return (jsx("nav", { "aria-label": "Bottom Navigation", className: buildClassName('w-full flex items-center justify-around select-none shadow-lg transition-colors relative', fixed && 'fixed bottom-0 left-0 right-0 z-40', 'pb-[env(safe-area-inset-bottom,6px)] px-2', themeStyles, containerClass), "data-testid": "bottom-navigation", children: items.map((item) => {
630
+ const isActive = item.id === activeId;
631
+ const showLabelText = showLabels === 'always' || (showLabels === 'active' && isActive);
632
+ const activeItemColor = {
633
+ light: 'text-blue-600 dark:text-blue-400 font-bold',
634
+ dark: 'text-white font-bold',
635
+ primary: 'text-white font-bold',
636
+ }[theme];
637
+ const inactiveItemColor = {
638
+ light: 'text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 font-medium',
639
+ dark: 'text-gray-400 hover:text-gray-200 font-medium',
640
+ primary: 'text-blue-200 hover:text-white font-medium',
641
+ }[theme];
642
+ const pillActiveStyles = {
643
+ light: 'bg-blue-100 dark:bg-blue-950/80 text-blue-600 dark:text-blue-400 shadow-xs scale-105',
644
+ dark: 'bg-gray-800 text-white ring-1 ring-gray-700 shadow-xs scale-105',
645
+ primary: 'bg-white/25 text-white shadow-xs scale-105',
646
+ }[theme];
647
+ const badgeColor = {
648
+ danger: 'bg-red-500 text-white',
649
+ info: 'bg-blue-500 text-white',
650
+ success: 'bg-emerald-500 text-white',
651
+ }[item.badgeVariant || 'danger'];
652
+ return (jsxs("button", { type: "button", disabled: item.disabled, onClick: () => handleTabClick(item), className: buildClassName('flex-1 flex flex-col items-center justify-center pt-2 pb-1.5 px-1 transition-all duration-200 relative cursor-pointer group', item.disabled && 'opacity-40 cursor-not-allowed pointer-events-none', isActive ? activeItemColor : inactiveItemColor, itemClass), "data-testid": `bottom-nav-item-${item.id}`, "aria-selected": isActive, children: [activeIndicatorStyle === 'line' && isActive && (jsx("span", { className: buildClassName('absolute -top-[1px] h-0.75 w-9 rounded-full transition-all duration-200 z-10', theme === 'primary' ? 'bg-white' : 'bg-blue-600 dark:bg-blue-400') })), jsxs("div", { className: buildClassName('relative inline-flex items-center justify-center transition-all duration-200', activeIndicatorStyle === 'pill'
653
+ ? buildClassName('px-4 py-1 rounded-full', isActive
654
+ ? pillActiveStyles
655
+ : 'group-hover:bg-gray-100/50 dark:group-hover:bg-gray-800/40')
656
+ : 'px-1 py-0.5'), children: [jsx("span", { className: "text-xl transition-transform duration-150 group-active:scale-95", children: isActive && item.activeIcon ? item.activeIcon : item.icon }), item.badge !== undefined && item.badge !== null && (jsx("span", { className: buildClassName('absolute -top-1 -right-1 min-w-[16px] h-4 px-1 rounded-full text-[10px] font-bold flex items-center justify-center shadow-xs z-10', badgeColor), "data-testid": `bottom-nav-badge-${item.id}`, children: item.badge }))] }), showLabelText && (jsx("span", { className: buildClassName('text-[11px] leading-tight mt-1 truncate max-w-full transition-colors duration-150', isActive ? 'font-bold' : 'font-medium opacity-90'), children: item.label })), activeIndicatorStyle === 'dot' && isActive && (jsx("span", { className: buildClassName('size-1.5 rounded-full mt-1 transition-all duration-200', theme === 'primary' ? 'bg-white' : 'bg-blue-600 dark:bg-blue-400') }))] }, item.id));
657
+ }) }));
658
+ }
659
+ BottomNavigation.displayName = 'BottomNavigation';
660
+
512
661
  var _path$a;
513
662
  function _extends$a() { return _extends$a = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$a.apply(null, arguments); }
514
663
  var SvgSlash = function SvgSlash(props) {
@@ -664,10 +813,10 @@ const ButtonGroup = ({ children, orientation = 'horizontal', theme = 'secondary'
664
813
  (isVertical
665
814
  ? resolvedTheme === 'primary' || resolvedTheme === 'danger'
666
815
  ? 'border-t border-white/25 dark:border-white/20'
667
- : 'border-t border-gray-300/70 dark:border-gray-700/70'
816
+ : 'border-t border-[var(--ui-border)]'
668
817
  : resolvedTheme === 'primary' || resolvedTheme === 'danger'
669
818
  ? 'border-l border-white/25 dark:border-white/20'
670
- : 'border-l border-gray-300/70 dark:border-gray-700/70'),
819
+ : 'border-l border-[var(--ui-border)]'),
671
820
  ], fullWidth && 'flex-1'),
672
821
  });
673
822
  }) }));
@@ -688,27 +837,33 @@ const ASPECT_RATIO_CLASS = {
688
837
  video: 'aspect-video',
689
838
  wide: 'aspect-[21/9]',
690
839
  };
840
+ function ChevronRightIcon$1({ className = 'size-4' }) {
841
+ return (jsx("svg", { className: className, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) }));
842
+ }
691
843
  const Card = forwardRef(({ as, ...props }, ref) => {
692
- const { variant = 'outlined', radius = 'xl', hoverable = false, clickable = false, selected = false, bordered = true, compact = false, zeroPadding = false, ...rest } = props;
844
+ const { variant = 'outlined', radius = 'xl', hoverable = false, clickable = false, selected = false, bordered = true, compact = false, zeroPadding = false, title, subtitle, leading, trailing, badge, showChevron = false, children, onClick, ...rest } = props;
693
845
  const Component = as || 'div';
694
846
  const { className, ...cleanRest } = rest;
847
+ const isClickable = clickable || Boolean(onClick);
695
848
  const isOutlined = variant === 'outlined' && bordered;
696
849
  const isElevated = variant === 'elevated';
697
850
  const isFilled = variant === 'filled';
698
851
  const isGhost = variant === 'ghost';
699
- const classes = buildClassName('block transition-all duration-200', RADIUS_CLASS[radius] || RADIUS_CLASS.xl, zeroPadding ? '' : compact ? 'p-3 sm:p-4' : 'p-5 sm:p-6',
852
+ const classes = buildClassName('block transition-all duration-150 select-none', RADIUS_CLASS[radius] || RADIUS_CLASS.xl, zeroPadding ? '' : compact ? 'p-3 sm:p-4' : 'p-5 sm:p-6',
700
853
  // Surface variants
701
854
  isOutlined && 'bg-white dark:bg-gray-900 border border-[var(--ui-border)]', isElevated &&
702
- 'bg-white dark:bg-gray-900 border border-gray-100 dark:border-gray-800 shadow-md shadow-gray-200/50 dark:shadow-none', isFilled && 'bg-gray-50/80 dark:bg-gray-800/60 border border-transparent', isGhost && 'bg-transparent border border-transparent',
703
- // Hoverable & Clickable states
704
- hoverable && 'hover:bg-gray-100/80 dark:hover:bg-gray-800/80', clickable && 'cursor-pointer hover:-translate-y-0.5 hover:shadow-lg', selected && 'ring-2 ring-[var(--ui-primary)] border-[var(--ui-primary)]', className);
705
- return jsx(Component, { ref: ref, className: classes, ...cleanRest });
855
+ 'bg-white dark:bg-gray-900 border border-[var(--ui-border)] shadow-md shadow-gray-200/50 dark:shadow-none', isFilled && 'bg-gray-50/80 dark:bg-gray-800/60 border border-transparent', isGhost && 'bg-transparent border border-transparent',
856
+ // Hoverable & Clickable mobile/web touch states
857
+ hoverable && 'hover:bg-gray-100/80 dark:hover:bg-gray-800/80', isClickable &&
858
+ 'cursor-pointer hover:-translate-y-0.5 hover:shadow-lg active:scale-[0.99] active:bg-gray-100 dark:active:bg-gray-800/90', selected && 'ring-2 ring-[var(--ui-primary)] border-[var(--ui-primary)]', className);
859
+ const hasHeaderRow = title || subtitle || leading || trailing || badge || showChevron;
860
+ return (jsxs(Component, { ref: ref, className: classes, onClick: onClick, ...cleanRest, children: [hasHeaderRow && (jsxs("div", { className: buildClassName('flex items-center gap-3 w-full min-w-0', children && 'mb-3'), children: [leading && jsx("div", { className: "shrink-0 flex items-center justify-center", children: leading }), jsxs("div", { className: "flex-1 min-w-0 text-left", children: [jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [title && (jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: title })), badge] }), subtitle && (jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate", children: subtitle }))] }), (trailing || showChevron) && (jsxs("div", { className: "shrink-0 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400", children: [trailing, showChevron && jsx(ChevronRightIcon$1, { className: "size-4 text-gray-400" })] }))] })), children] }));
706
861
  });
707
- const CardHeader = ({ className, bordered = false, children, ...props }) => (jsx("div", { className: buildClassName('flex items-center justify-between gap-4 mb-4', bordered && 'pb-4 border-b border-gray-200 dark:border-gray-800', className), ...props, children: children }));
862
+ const CardHeader = ({ className, bordered = false, children, ...props }) => (jsx("div", { className: buildClassName('flex items-center justify-between gap-4 mb-4', bordered && 'pb-4 border-b border-[var(--ui-border)]', className), ...props, children: children }));
708
863
  const CardTitle = ({ className, as: Component = 'h3', children, ...props }) => (jsx(Component, { className: buildClassName('text-lg font-semibold text-gray-900 dark:text-white tracking-tight', className), ...props, children: children }));
709
864
  const CardDescription = ({ className, children, ...props }) => (jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal mt-1', className), ...props, children: children }));
710
865
  const CardContent = ({ className, children, ...props }) => (jsx("div", { className: buildClassName('space-y-3', className), ...props, children: children }));
711
- const CardFooter = ({ className, bordered = false, children, ...props }) => (jsx("div", { className: buildClassName('flex items-center justify-end gap-3 mt-4', bordered && 'pt-4 border-t border-gray-200 dark:border-gray-800', className), ...props, children: children }));
866
+ const CardFooter = ({ className, bordered = false, children, ...props }) => (jsx("div", { className: buildClassName('flex items-center justify-end gap-3 mt-4', bordered && 'pt-4 border-t border-[var(--ui-border)]', className), ...props, children: children }));
712
867
  const CardMedia = ({ className, aspectRatio = 'video', alt = '', ...props }) => (jsx("div", { className: buildClassName('overflow-hidden -mx-5 -mt-5 mb-4 sm:-mx-6 sm:-mt-6', className), children: jsx("img", { alt: alt, className: buildClassName('w-full object-cover', ASPECT_RATIO_CLASS[aspectRatio] || ASPECT_RATIO_CLASS.video), ...props }) }));
713
868
  Card.Header = CardHeader;
714
869
  Card.Title = CardTitle;
@@ -728,19 +883,19 @@ Label.displayName = 'Label';
728
883
  const sizeStyles = {
729
884
  sm: {
730
885
  box: 'size-3.5',
731
- svg: 'h-2.5 w-2.5',
886
+ svg: 'size-2.75',
732
887
  text: 'text-xs',
733
888
  subtext: 'text-[11px]',
734
889
  },
735
890
  md: {
736
891
  box: 'size-4.5',
737
- svg: 'h-3.25 w-3.25',
892
+ svg: 'size-3.5',
738
893
  text: 'text-sm',
739
894
  subtext: 'text-xs',
740
895
  },
741
896
  lg: {
742
897
  box: 'size-5.5',
743
- svg: 'h-4 w-4',
898
+ svg: 'size-4.25',
744
899
  text: 'text-base',
745
900
  subtext: 'text-sm',
746
901
  },
@@ -761,19 +916,19 @@ const Checkbox = forwardRef((props, ref) => {
761
916
  const isCard = variant === 'card';
762
917
  return (jsxs("div", { className: buildClassName(wrapperClass), children: [jsx("div", { className: buildClassName(isCard
763
918
  ? 'rounded-xl border p-3.5 transition-all duration-150 relative'
764
- : 'flex items-start', isCard &&
919
+ : 'flex items-center', isCard &&
765
920
  (disabled
766
- ? 'border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/40 opacity-70'
921
+ ? 'border-[var(--ui-border-muted)] bg-gray-50/50 dark:bg-gray-900/40 opacity-70'
767
922
  : checked || indeterminate
768
923
  ? 'border-blue-500/80 bg-blue-50/30 dark:bg-blue-950/20 dark:border-blue-500/60 shadow-xs'
769
- : 'border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 hover:border-gray-300 dark:hover:border-gray-700 shadow-2xs'), containerClass), children: jsxs("label", { htmlFor: checkboxId, className: buildClassName('inline-flex items-start relative select-none w-full', disabled ? 'cursor-not-allowed opacity-70' : 'cursor-pointer'), children: [jsxs("div", { className: "relative inline-flex items-center shrink-0 pt-0.5", children: [jsx("input", { ref: innerRef, ...rest, id: checkboxId, name: name, type: "checkbox", disabled: disabled, checked: checked, onChange: onChange, "aria-checked": indeterminate ? 'mixed' : checked, className: buildClassName('peer cursor-pointer transition-all appearance-none rounded', currentSize.box, 'border focus:ring-2 focus:ring-offset-2', 'checked:bg-blue-600 checked:border-blue-600 dark:checked:bg-blue-600 dark:checked:border-blue-600', 'focus:ring-[var(--ui-focus-ring)] dark:focus:ring-offset-gray-900', disabled
770
- ? 'border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 pointer-events-none'
771
- : 'bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500 hover:shadow-xs', indeterminate &&
772
- '!bg-blue-600 !border-blue-600 dark:!bg-blue-600 dark:!border-blue-600', className) }), !indeterminate && (jsx("span", { className: buildClassName('absolute text-white pointer-events-none transition-opacity top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2', checked !== undefined
924
+ : 'border-[var(--ui-border)] bg-white dark:bg-gray-900 hover:border-gray-300 dark:hover:border-gray-700 shadow-2xs'), containerClass), children: jsxs("label", { htmlFor: checkboxId, className: buildClassName('inline-flex relative select-none w-full', description ? 'items-start' : 'items-center', disabled ? 'cursor-not-allowed opacity-70' : 'cursor-pointer'), children: [jsxs("div", { className: "relative inline-flex items-center justify-center shrink-0", children: [jsx("input", { ref: innerRef, ...rest, id: checkboxId, name: name, type: "checkbox", disabled: disabled, checked: checked, onChange: onChange, "aria-checked": indeterminate ? 'mixed' : checked, className: buildClassName('peer cursor-pointer transition-all appearance-none rounded', currentSize.box, 'border focus:ring-2 focus:ring-offset-2', 'checked:bg-blue-600 checked:border-blue-600 dark:checked:bg-blue-600 dark:checked:border-blue-600', 'focus:ring-[var(--ui-focus-ring)] dark:focus:ring-offset-gray-900', disabled
925
+ ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'
926
+ : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500', indeterminate &&
927
+ '!bg-blue-600 !border-blue-600 dark:!bg-blue-600 dark:!border-blue-600', className) }), !indeterminate && (jsx("span", { className: buildClassName('absolute inset-0 flex items-center justify-center text-white pointer-events-none transition-opacity', checked !== undefined
773
928
  ? checked
774
929
  ? 'opacity-100'
775
930
  : 'opacity-0'
776
- : 'opacity-0 peer-checked:opacity-100'), children: jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", stroke: "currentColor", strokeWidth: "1", children: jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })), indeterminate && (jsx("span", { className: "absolute text-white pointer-events-none top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 opacity-100 z-10", children: jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { fillRule: "evenodd", d: "M4 10a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1z", clipRule: "evenodd" }) }) }))] }), (label || description) && (jsxs("div", { className: "ml-2.5 flex flex-col justify-center min-w-0 flex-1", children: [label && (jsx(Label, { htmlFor: checkboxId, className: buildClassName(disabled
931
+ : 'opacity-0 peer-checked:opacity-100'), children: jsx("svg", { className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", children: jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })), indeterminate && (jsx("span", { className: "absolute inset-0 flex items-center justify-center text-white pointer-events-none opacity-100 z-10", children: jsx("svg", { className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", children: jsx("path", { fillRule: "evenodd", d: "M4 10a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1z", clipRule: "evenodd" }) }) }))] }), (label || description) && (jsxs("div", { className: "ml-2.5 flex flex-col justify-center min-w-0 flex-1", children: [label && (jsx(Label, { htmlFor: checkboxId, className: buildClassName(disabled
777
932
  ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'
778
933
  : 'cursor-pointer text-gray-800 dark:text-gray-200 font-medium', currentSize.text, labelClass), children: label })), description && (jsx("span", { className: buildClassName('mt-0.5 text-gray-500 dark:text-gray-400 font-normal leading-normal', currentSize.subtext), children: description }))] }))] }) }), (error || helperText) && (jsx("div", { className: "mt-1.5 ml-0.5", children: error ? (jsx(TextContent, { error: true, small: true, children: error })) : (jsx(TextContent, { muted: true, small: true, children: helperText })) }))] }));
779
934
  });
@@ -842,7 +997,7 @@ const CheckboxGroup = (props) => {
842
997
  : inline
843
998
  ? 'flex flex-wrap gap-3'
844
999
  : 'flex flex-col gap-3';
845
- return (jsxs("div", { className: buildClassName('mb-3 space-y-3', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsx(Label, { className: labelClass, children: label }), labelHint && (jsx(BodyText, { muted: true, small: true, children: labelHint }))] })), showSelectAll && items.length > 0 && (jsx("div", { className: "pb-1 border-b border-gray-200 dark:border-gray-800", children: jsx(Checkbox, { id: `${groupId}-select-all`, label: selectAllLabel, size: size, variant: variant, checked: allSelected, indeterminate: isIndeterminate, disabled: disabled || enabledItems.length === 0, onChange: handleSelectAllChange }) })), jsx("div", { className: layoutClass, children: items.map((item, index) => {
1000
+ return (jsxs("div", { className: buildClassName('mb-3 space-y-3', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsx(Label, { className: labelClass, children: label }), labelHint && (jsx(BodyText, { muted: true, small: true, children: labelHint }))] })), showSelectAll && items.length > 0 && (jsx("div", { className: "pb-1 border-b border-[var(--ui-border)]", children: jsx(Checkbox, { id: `${groupId}-select-all`, label: selectAllLabel, size: size, variant: variant, checked: allSelected, indeterminate: isIndeterminate, disabled: disabled || enabledItems.length === 0, onChange: handleSelectAllChange }) })), jsx("div", { className: layoutClass, children: items.map((item, index) => {
846
1001
  const key = typeof item.value === 'string' || typeof item.value === 'number' ? item.value : index;
847
1002
  return (jsx(Checkbox, { name: name, id: `${groupId}-${String(item.value)}`, label: item.label, description: item.description, value: String(item.value), size: size, variant: variant, disabled: disabled || item.disabled, checked: currentValue.includes(item.value), onChange: handleGroupChange }, key));
848
1003
  }) }), (error || helperText) && (jsx("div", { className: "mt-1.5 ml-0.5", children: error ? (jsx(TextContent, { error: true, small: true, children: error })) : (jsx(TextContent, { muted: true, small: true, children: helperText })) }))] }));
@@ -922,27 +1077,8 @@ const usePagination = ({ totalPages, currentPage, siblingCount = 1, // number of
922
1077
 
923
1078
  var _path$9;
924
1079
  function _extends$9() { return _extends$9 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$9.apply(null, arguments); }
925
- var SvgChevronLeft = function SvgChevronLeft(props) {
926
- return /*#__PURE__*/React.createElement("svg", _extends$9({
927
- xmlns: "http://www.w3.org/2000/svg",
928
- width: 24,
929
- height: 24,
930
- fill: "none",
931
- stroke: "currentColor",
932
- strokeLinecap: "round",
933
- strokeLinejoin: "round",
934
- strokeWidth: 2,
935
- className: "lucide lucide-chevron-left-icon lucide-chevron-left",
936
- viewBox: "0 0 24 24"
937
- }, props), _path$9 || (_path$9 = /*#__PURE__*/React.createElement("path", {
938
- d: "m15 18-6-6 6-6"
939
- })));
940
- };
941
-
942
- var _path$8;
943
- function _extends$8() { return _extends$8 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$8.apply(null, arguments); }
944
1080
  var SvgChevronRight = function SvgChevronRight(props) {
945
- return /*#__PURE__*/React.createElement("svg", _extends$8({
1081
+ return /*#__PURE__*/React.createElement("svg", _extends$9({
946
1082
  xmlns: "http://www.w3.org/2000/svg",
947
1083
  width: 24,
948
1084
  height: 24,
@@ -953,7 +1089,7 @@ var SvgChevronRight = function SvgChevronRight(props) {
953
1089
  strokeWidth: 2,
954
1090
  className: "lucide lucide-chevron-right-icon lucide-chevron-right",
955
1091
  viewBox: "0 0 24 24"
956
- }, props), _path$8 || (_path$8 = /*#__PURE__*/React.createElement("path", {
1092
+ }, props), _path$9 || (_path$9 = /*#__PURE__*/React.createElement("path", {
957
1093
  d: "m9 18 6-6-6-6"
958
1094
  })));
959
1095
  };
@@ -1075,10 +1211,10 @@ const useRowSelection = ({ items, getKey, selectedRowKeys, defaultSelectedRowKey
1075
1211
  };
1076
1212
  };
1077
1213
 
1078
- var _path$7;
1079
- function _extends$7() { return _extends$7 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$7.apply(null, arguments); }
1214
+ var _path$8;
1215
+ function _extends$8() { return _extends$8 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$8.apply(null, arguments); }
1080
1216
  var SvgArrowDownWideNarrow = function SvgArrowDownWideNarrow(props) {
1081
- return /*#__PURE__*/React.createElement("svg", _extends$7({
1217
+ return /*#__PURE__*/React.createElement("svg", _extends$8({
1082
1218
  xmlns: "http://www.w3.org/2000/svg",
1083
1219
  width: 24,
1084
1220
  height: 24,
@@ -1089,15 +1225,15 @@ var SvgArrowDownWideNarrow = function SvgArrowDownWideNarrow(props) {
1089
1225
  strokeWidth: 2,
1090
1226
  className: "lucide lucide-arrow-down-wide-narrow-icon lucide-arrow-down-wide-narrow",
1091
1227
  viewBox: "0 0 24 24"
1092
- }, props), _path$7 || (_path$7 = /*#__PURE__*/React.createElement("path", {
1228
+ }, props), _path$8 || (_path$8 = /*#__PURE__*/React.createElement("path", {
1093
1229
  d: "m3 16 4 4 4-4M7 20V4M11 4h10M11 8h7M11 12h4"
1094
1230
  })));
1095
1231
  };
1096
1232
 
1097
- var _path$6;
1098
- function _extends$6() { return _extends$6 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$6.apply(null, arguments); }
1233
+ var _path$7;
1234
+ function _extends$7() { return _extends$7 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$7.apply(null, arguments); }
1099
1235
  var SvgArrowDownNarrowWide = function SvgArrowDownNarrowWide(props) {
1100
- return /*#__PURE__*/React.createElement("svg", _extends$6({
1236
+ return /*#__PURE__*/React.createElement("svg", _extends$7({
1101
1237
  xmlns: "http://www.w3.org/2000/svg",
1102
1238
  width: 24,
1103
1239
  height: 24,
@@ -1108,15 +1244,15 @@ var SvgArrowDownNarrowWide = function SvgArrowDownNarrowWide(props) {
1108
1244
  strokeWidth: 2,
1109
1245
  className: "lucide lucide-arrow-down-narrow-wide-icon lucide-arrow-down-narrow-wide",
1110
1246
  viewBox: "0 0 24 24"
1111
- }, props), _path$6 || (_path$6 = /*#__PURE__*/React.createElement("path", {
1247
+ }, props), _path$7 || (_path$7 = /*#__PURE__*/React.createElement("path", {
1112
1248
  d: "m3 16 4 4 4-4M7 20V4M11 4h4M11 8h7M11 12h10"
1113
1249
  })));
1114
1250
  };
1115
1251
 
1116
- var _path$5;
1117
- function _extends$5() { return _extends$5 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$5.apply(null, arguments); }
1252
+ var _path$6;
1253
+ function _extends$6() { return _extends$6 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$6.apply(null, arguments); }
1118
1254
  var SvgArrowDownAz = function SvgArrowDownAz(props) {
1119
- return /*#__PURE__*/React.createElement("svg", _extends$5({
1255
+ return /*#__PURE__*/React.createElement("svg", _extends$6({
1120
1256
  xmlns: "http://www.w3.org/2000/svg",
1121
1257
  width: 24,
1122
1258
  height: 24,
@@ -1127,15 +1263,15 @@ var SvgArrowDownAz = function SvgArrowDownAz(props) {
1127
1263
  strokeWidth: 2,
1128
1264
  className: "lucide lucide-arrow-down-az-icon lucide-arrow-down-a-z",
1129
1265
  viewBox: "0 0 24 24"
1130
- }, props), _path$5 || (_path$5 = /*#__PURE__*/React.createElement("path", {
1266
+ }, props), _path$6 || (_path$6 = /*#__PURE__*/React.createElement("path", {
1131
1267
  d: "m3 16 4 4 4-4M7 20V4M20 8h-5M15 10V6.5a2.5 2.5 0 0 1 5 0V10M15 14h5l-5 6h5"
1132
1268
  })));
1133
1269
  };
1134
1270
 
1135
- var _path$4;
1136
- function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
1271
+ var _path$5;
1272
+ function _extends$5() { return _extends$5 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$5.apply(null, arguments); }
1137
1273
  var SvgArrowDownZa = function SvgArrowDownZa(props) {
1138
- return /*#__PURE__*/React.createElement("svg", _extends$4({
1274
+ return /*#__PURE__*/React.createElement("svg", _extends$5({
1139
1275
  xmlns: "http://www.w3.org/2000/svg",
1140
1276
  width: 24,
1141
1277
  height: 24,
@@ -1146,15 +1282,15 @@ var SvgArrowDownZa = function SvgArrowDownZa(props) {
1146
1282
  strokeWidth: 2,
1147
1283
  className: "lucide lucide-arrow-down-za-icon lucide-arrow-down-z-a",
1148
1284
  viewBox: "0 0 24 24"
1149
- }, props), _path$4 || (_path$4 = /*#__PURE__*/React.createElement("path", {
1285
+ }, props), _path$5 || (_path$5 = /*#__PURE__*/React.createElement("path", {
1150
1286
  d: "m3 16 4 4 4-4M7 4v16M15 4h5l-5 6h5M15 20v-3.5a2.5 2.5 0 0 1 5 0V20M20 18h-5"
1151
1287
  })));
1152
1288
  };
1153
1289
 
1154
- var _path$3;
1155
- function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
1290
+ var _path$4;
1291
+ function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
1156
1292
  var SvgArrowUpDown = function SvgArrowUpDown(props) {
1157
- return /*#__PURE__*/React.createElement("svg", _extends$3({
1293
+ return /*#__PURE__*/React.createElement("svg", _extends$4({
1158
1294
  xmlns: "http://www.w3.org/2000/svg",
1159
1295
  width: 24,
1160
1296
  height: 24,
@@ -1165,7 +1301,7 @@ var SvgArrowUpDown = function SvgArrowUpDown(props) {
1165
1301
  strokeWidth: 2,
1166
1302
  className: "lucide lucide-arrow-up-down-icon lucide-arrow-up-down",
1167
1303
  viewBox: "0 0 24 24"
1168
- }, props), _path$3 || (_path$3 = /*#__PURE__*/React.createElement("path", {
1304
+ }, props), _path$4 || (_path$4 = /*#__PURE__*/React.createElement("path", {
1169
1305
  d: "m21 16-4 4-4-4M17 20V4M3 8l4-4 4 4M7 4v16"
1170
1306
  })));
1171
1307
  };
@@ -1207,7 +1343,7 @@ const autoSortItems = (items, column, sort) => {
1207
1343
  return 0;
1208
1344
  });
1209
1345
  };
1210
- function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, paginationContainerClass, }) {
1346
+ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, stickyHeader = true, stickyPagination = true, paginationContainerClass, }) {
1211
1347
  const internalSorting = useRef({});
1212
1348
  const [sortedItems, setSortedItems] = useState(items);
1213
1349
  useEffect(() => {
@@ -1252,12 +1388,13 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
1252
1388
  });
1253
1389
  const densityCellClass = DENSITY_CELL_CLASS$2[density];
1254
1390
  const colSize = columns.length + (selectable ? 1 : 0);
1255
- return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName('overflow-x-auto overflow-y-hidden rounded-lg border border-[var(--ui-border)]', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxs(TableHead, { className: headClass, children: [selectable && (jsx(TableHeaderCell, { className: buildClassName('bg-gray-50 dark:bg-gray-800 w-px', densityCellClass), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1391
+ const wrapperHasOverflow = /\boverflow-(x-|y-)?(auto|hidden|scroll|visible|clip)\b/.test(wrapperClass);
1392
+ return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName(!wrapperHasOverflow && 'overflow-x-auto', 'rounded-lg border border-[var(--ui-border)]', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxs(TableHead, { className: headClass, children: [selectable && (jsx(TableHeaderCell, { className: buildClassName('bg-gray-50 dark:bg-gray-800 w-px', densityCellClass, stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]'), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1256
1393
  if (el)
1257
1394
  el.indeterminate = someSelected;
1258
- }, onChange: toggleAll }) })), columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
1259
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1260
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
1395
+ }, onChange: toggleAll }) })), columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]', column.sticky === 'left' &&
1396
+ 'sticky left-0 z-30 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1397
+ 'sticky right-0 z-30 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
1261
1398
  const key = getKey(item, idx);
1262
1399
  const rowSelectable = !isRowSelectable || isRowSelectable(item);
1263
1400
  return (jsxs(TableRow, { className: buildClassName('group', onRowClick && 'cursor-pointer', striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', getRowClass(item, idx)), onClick: onRowClick ? () => onRowClick(item, idx) : undefined, children: [selectable && (jsx(TableCell, { className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40'), children: jsx("span", { onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { "aria-label": "Select row", checked: isSelected(key), disabled: !rowSelectable, onChange: () => toggleRow(key) }) }) })), columns.map((column) => {
@@ -1268,7 +1405,7 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
1268
1405
  ? column.render(item)
1269
1406
  : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
1270
1407
  })] }, key));
1271
- })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: buildClassName('rounded-b-lg border-t border-[var(--ui-border)]', paginationContainerClass), onChange: setPagination }))] }));
1408
+ })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: buildClassName('rounded-b-lg border border-[var(--ui-border)]', stickyPagination && 'sticky bottom-0 z-20 bg-white dark:bg-gray-800', paginationContainerClass), onChange: setPagination }))] }));
1272
1409
  }
1273
1410
  DataTable.displayName = 'DataTable';
1274
1411
 
@@ -1383,8 +1520,8 @@ const DetailedInformation = forwardRef((props, ref) => {
1383
1520
  const isMultiColumn = columns > 1;
1384
1521
  return (jsxs("div", { ref: ref, className: buildClassName(isCard
1385
1522
  ? compact
1386
- ? 'p-3 sm:p-4 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-gray-200 dark:border-gray-700'
1387
- : 'p-4 sm:p-6 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-gray-200 dark:border-gray-700'
1523
+ ? 'p-3 sm:p-4 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-[var(--ui-border)]'
1524
+ : 'p-4 sm:p-6 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-[var(--ui-border)]'
1388
1525
  : isBordered
1389
1526
  ? compact
1390
1527
  ? 'p-3 sm:p-4 border border-[var(--ui-border)] rounded-2xl'
@@ -1402,8 +1539,8 @@ const DetailedInformation = forwardRef((props, ref) => {
1402
1539
  const isVertical = layout === 'vertical' || isMultiColumn;
1403
1540
  return (jsxs("div", { className: buildClassName(isMultiColumn && isCard
1404
1541
  ? compact
1405
- ? 'p-3 bg-white dark:bg-gray-900 rounded-xl border border-gray-200/80 dark:border-gray-700/80 shadow-2xs flex flex-col gap-1'
1406
- : 'p-4 bg-white dark:bg-gray-900 rounded-xl border border-gray-200/80 dark:border-gray-700/80 shadow-2xs flex flex-col gap-1'
1542
+ ? 'p-3 bg-white dark:bg-gray-900 rounded-xl border border-[var(--ui-border)] shadow-2xs flex flex-col gap-1'
1543
+ : 'p-4 bg-white dark:bg-gray-900 rounded-xl border border-[var(--ui-border)] shadow-2xs flex flex-col gap-1'
1407
1544
  : isVertical
1408
1545
  ? 'flex flex-col gap-1 py-2 px-1'
1409
1546
  : 'grid grid-cols-3 gap-4 items-center py-2.5 px-1', compact && !isMultiColumn ? 'py-1.5' : ''), children: [jsxs("dt", { className: buildClassName('text-sm/6 font-medium text-gray-900 dark:text-gray-100 flex items-center gap-1.5', labelClass, detail.labelClass), children: [detail.icon && jsx("span", { className: "shrink-0 text-gray-400", children: detail.icon }), jsx("span", { children: detail.label }), detail.helpText && (jsx("span", { className: "text-xs text-gray-400 font-normal cursor-help", title: detail.helpText, children: "(?)" }))] }), jsx("dd", { className: buildClassName('text-sm/6 text-gray-700 dark:text-gray-300', !isVertical && 'sm:col-span-2 sm:mt-0', detail.contentClass), children: detail.copyable && copyText ? (jsx(CopyableValue, { text: copyText, children: displayValue })) : (displayValue) })] }, detail.label || index));
@@ -1416,41 +1553,6 @@ const Dot = ({ as = 'span', className, ...props }) => React__default.createEleme
1416
1553
  ...props,
1417
1554
  });
1418
1555
 
1419
- const alignmentMap = {
1420
- center: 'items-center justify-center h-full',
1421
- start: 'justify-start h-full',
1422
- end: 'justify-end h-full',
1423
- top: 'items-start justify-center w-full',
1424
- bottom: 'items-end justify-center h-full',
1425
- };
1426
- const panelAlignmentMap = {
1427
- center: 'data-[closed]:scale-95 rounded-2xl',
1428
- start: 'data-[closed]:-translate-x-1/2 rounded-r-2xl',
1429
- end: 'data-[closed]:translate-x-1/2 rounded-l-2xl',
1430
- top: 'data-[closed]:-translate-y-1/2 rounded-b-2xl',
1431
- bottom: 'data-[closed]:translate-y-1/2 rounded-t-2xl md:rounded-t-3xl max-h-[92svh]',
1432
- };
1433
- const panelSizeMap = {
1434
- xs: 'max-w-xs',
1435
- sm: 'max-w-sm',
1436
- md: 'max-w-md',
1437
- lg: 'max-w-lg',
1438
- xl: 'max-w-xl',
1439
- '2xl': 'max-w-2xl',
1440
- full: 'w-full',
1441
- };
1442
- const Drawer = ({ isOpen, onClose = () => { }, closeOnOutsideClick = true, align = 'end', size = 'md', backdrop = true, title, description, children, footer, footerSticky = false, panelClass = '', contentClass = '', titleClass = '', descriptionClass = '', titleSticky = false, showBackButton = false, showCloseButton = true, dragHandle, }) => {
1443
- const showTitleSection = Boolean(title || description || showBackButton || showCloseButton);
1444
- const shouldShowDragHandle = dragHandle !== null && dragHandle !== void 0 ? dragHandle : align === 'bottom';
1445
- const handleDialogClose = () => {
1446
- if (closeOnOutsideClick) {
1447
- onClose === null || onClose === void 0 ? void 0 : onClose();
1448
- }
1449
- };
1450
- return (jsxs(Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: handleDialogClose, transition: true, children: [backdrop && (jsx(DialogBackdrop, { className: "fixed inset-0 bg-black/40 backdrop-blur-xs transition-opacity duration-200" })), jsx("div", { className: "fixed inset-0 w-screen h-[100svh]", children: jsx("div", { className: buildClassName('flex', alignmentMap[align]), children: jsxs(DialogPanel, { transition: true, className: buildClassName('w-full max-w-full bg-white dark:bg-gray-800 shadow-xl flex flex-col min-w-0', 'overflow-y-auto overflow-x-hidden duration-200 ease-out data-[closed]:opacity-0', panelAlignmentMap[align], panelSizeMap[size], panelClass), children: [shouldShowDragHandle && (jsx("div", { className: "w-12 h-1.5 rounded-full bg-gray-300 dark:bg-gray-600 mx-auto my-2.5 shrink-0 cursor-grab", "data-testid": "drawer-drag-handle" })), showTitleSection && (jsxs("div", { className: buildClassName('space-y-1 py-3 px-4 md:px-6 flex flex-col border-b border-gray-100 dark:border-gray-700/60 shrink-0', titleSticky && 'sticky top-0 bg-white dark:bg-gray-800 z-10'), children: [jsxs("div", { className: "flex items-center justify-between gap-3 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [showBackButton && (jsx(Button, { iconOnly: true, "aria-label": "Back", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, children: jsx(SvgChevronLeft, { className: "size-4" }) })), title && (jsx(DialogTitle, { as: "h3", className: buildClassName('text-lg font-semibold text-gray-900 dark:text-white truncate tracking-tight min-w-0', titleClass), children: title }))] }), showCloseButton && (jsx(Button, { iconOnly: true, "aria-label": "Close drawer", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, className: "rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 shrink-0", children: jsx(SvgX, { className: "size-4" }) }))] }), description && (jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal truncate', descriptionClass), children: description }))] })), jsx("div", { className: buildClassName('flex-1 p-4 md:p-6 space-y-4 min-w-0', contentClass), children: children }), footer && (jsx("div", { className: buildClassName('p-4 border-t border-gray-100 dark:border-gray-700/60 bg-gray-50/50 dark:bg-gray-800/80 shrink-0 min-w-0', footerSticky && 'sticky bottom-0 z-10'), children: footer }))] }) }) })] }));
1451
- };
1452
- Drawer.displayName = 'Drawer';
1453
-
1454
1556
  const WIDTH_CLASS = {
1455
1557
  auto: 'w-auto min-w-[120px]',
1456
1558
  sm: 'w-44',
@@ -1476,7 +1578,7 @@ const Dropdown = ({ triggerButton, renderTriggerButton, className, items, render
1476
1578
  variant: (_b = triggerButton.props.variant) !== null && _b !== void 0 ? _b : variant,
1477
1579
  size: (_c = triggerButton.props.size) !== null && _c !== void 0 ? _c : size,
1478
1580
  disabled: (_d = triggerButton.props.disabled) !== null && _d !== void 0 ? _d : disabled,
1479
- }) })) : (jsx(MenuButton, { as: Fragment$1, children: triggerButton })), jsx(MenuItems, { transition: transition, anchor: anchor, className: buildClassName('origin-top-right rounded-xl shadow-lg p-1.5 text-sm transition duration-100 ease-out z-50', 'border border-gray-200/80 dark:border-gray-700/80 bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200', 'focus:outline-none data-[closed]:scale-95 data-[closed]:opacity-0', '[--anchor-gap:--spacing(1)]', widthClass, itemsContainerClass), "data-testid": "dropdown-items", as: "ul", children: items.map((item, idx) => (jsxs(Fragment$1, { children: [item.groupTitle && (jsx("li", { className: "px-2.5 pt-2 pb-1 text-[11px] font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider select-none", "data-testid": `dropdown-group-${item.id}`, children: item.groupTitle }, `group-${item.id}`)), jsx(MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled, active }) => (jsx("div", { onClick: () => {
1581
+ }) })) : (jsx(MenuButton, { as: Fragment$1, children: triggerButton })), jsx(MenuItems, { transition: transition, anchor: anchor, className: buildClassName('origin-top-right rounded-xl shadow-lg p-1.5 text-sm transition duration-100 ease-out z-50', 'border border-[var(--ui-border)] bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200', 'focus:outline-none data-[closed]:scale-95 data-[closed]:opacity-0', '[--anchor-gap:--spacing(1)]', widthClass, itemsContainerClass), "data-testid": "dropdown-items", as: "ul", children: items.map((item, idx) => (jsxs(Fragment$1, { children: [item.groupTitle && (jsx("li", { className: "px-2.5 pt-2 pb-1 text-[11px] font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider select-none", "data-testid": `dropdown-group-${item.id}`, children: item.groupTitle }, `group-${item.id}`)), jsx(MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled, active }) => (jsx("div", { onClick: () => {
1480
1582
  var _a;
1481
1583
  if (!disabled) {
1482
1584
  (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, item);
@@ -1488,14 +1590,14 @@ const Dropdown = ({ triggerButton, renderTriggerButton, className, items, render
1488
1590
  : 'hover:bg-rose-50 dark:hover:bg-rose-950/40')
1489
1591
  : buildClassName('text-gray-700 dark:text-gray-200', active
1490
1592
  ? 'bg-gray-100 dark:bg-gray-700/80'
1491
- : 'hover:bg-gray-100/80 dark:hover:bg-gray-700/80'), disabled && 'opacity-40 cursor-not-allowed pointer-events-none', menuItemClass), "data-testid": `dropdown-item-${item.id}`, children: renderItem ? (renderItem(item)) : (jsxs(Fragment, { children: [jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [item.icon && (jsx("span", { className: buildClassName('shrink-0', item.danger ? 'text-rose-500' : 'text-gray-400 dark:text-gray-500'), children: item.icon })), jsxs("div", { className: "flex flex-col min-w-0", children: [item.label && jsx("span", { className: "font-medium truncate", children: item.label }), item.description && (jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500 font-normal truncate", children: item.description }))] })] }), item.shortcut && (jsx("kbd", { className: "shrink-0 text-[10px] font-medium font-mono px-1.5 py-0.5 rounded bg-gray-100 dark:bg-gray-700/80 border border-gray-200/60 dark:border-gray-600/60 text-gray-400 dark:text-gray-400", children: item.shortcut }))] })) })) }), item.divider && idx < items.length - 1 && (jsx("li", { className: "my-1 h-px bg-gray-200/80 dark:bg-gray-700/80", "data-testid": "dropdown-divider" }, `divider-${item.id}`))] }, item.id))) })] }));
1593
+ : 'hover:bg-gray-100/80 dark:hover:bg-gray-700/80'), disabled && 'opacity-40 cursor-not-allowed pointer-events-none', menuItemClass), "data-testid": `dropdown-item-${item.id}`, children: renderItem ? (renderItem(item)) : (jsxs(Fragment, { children: [jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [item.icon && (jsx("span", { className: buildClassName('shrink-0', item.danger ? 'text-rose-500' : 'text-gray-400 dark:text-gray-500'), children: item.icon })), jsxs("div", { className: "flex flex-col min-w-0", children: [item.label && jsx("span", { className: "font-medium truncate", children: item.label }), item.description && (jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500 font-normal truncate", children: item.description }))] })] }), item.shortcut && (jsx("kbd", { className: "shrink-0 text-[10px] font-medium font-mono px-1.5 py-0.5 rounded bg-gray-100 dark:bg-gray-700/80 border border-[var(--ui-border-muted)] text-gray-400 dark:text-gray-400", children: item.shortcut }))] })) })) }), item.divider && idx < items.length - 1 && (jsx("li", { className: "my-1 h-px bg-gray-200/80 dark:bg-gray-700/80", "data-testid": "dropdown-divider" }, `divider-${item.id}`))] }, item.id))) })] }));
1492
1594
  };
1493
1595
  Dropdown.displayName = 'Dropdown';
1494
1596
 
1495
- var _path$2;
1496
- function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); }
1597
+ var _path$3;
1598
+ function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
1497
1599
  var SvgFolderPlus = function SvgFolderPlus(props) {
1498
- return /*#__PURE__*/React.createElement("svg", _extends$2({
1600
+ return /*#__PURE__*/React.createElement("svg", _extends$3({
1499
1601
  xmlns: "http://www.w3.org/2000/svg",
1500
1602
  width: 24,
1501
1603
  height: 24,
@@ -1506,7 +1608,7 @@ var SvgFolderPlus = function SvgFolderPlus(props) {
1506
1608
  strokeWidth: 2,
1507
1609
  className: "lucide lucide-folder-plus-icon lucide-folder-plus",
1508
1610
  viewBox: "0 0 24 24"
1509
- }, props), _path$2 || (_path$2 = /*#__PURE__*/React.createElement("path", {
1611
+ }, props), _path$3 || (_path$3 = /*#__PURE__*/React.createElement("path", {
1510
1612
  d: "M12 10v6M9 13h6M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
1511
1613
  })));
1512
1614
  };
@@ -1515,15 +1617,401 @@ const EmptyState = ({ title, description, className, action = null, }) => {
1515
1617
  return (jsx("div", { className: buildClassName('w-full flex justify-center px-4 pt-16', className), children: jsxs("div", { className: "max-w-md flex flex-col items-center gap-4", children: [jsx(SvgFolderPlus, { className: "size-8 text-[var(--ui-text)]" }), jsx(HeadingText.SubTitle, { children: title }), description && (jsx(BodyText, { as: "p", className: "text-center", muted: true, small: true, children: description })), action] }) }));
1516
1618
  };
1517
1619
 
1518
- const sizeClasses$4 = {
1519
- sm: {
1520
- input: 'px-2.5 py-1 text-xs leading-5',
1521
- group: 'w-8 text-xs',
1522
- icon: 'size-3.5',
1523
- text: 'text-xs',
1524
- },
1525
- md: {
1526
- input: 'px-3.5 py-2 text-sm leading-6',
1620
+ function FloatingActionButton({ icon, activeIcon, label, variant = 'primary', size = 'md', position = 'bottom-right', speedDialActions, isOpen: externalIsOpen, onToggle, disabled = false, onClick, 'aria-label': ariaLabel, containerClass = '', className = '', }) {
1621
+ const [internalIsOpen, setInternalIsOpen] = useState(false);
1622
+ const isSpeedDial = Array.isArray(speedDialActions) && speedDialActions.length > 0;
1623
+ const isOpen = externalIsOpen !== undefined ? externalIsOpen : internalIsOpen;
1624
+ const toggleOpen = () => {
1625
+ const nextState = !isOpen;
1626
+ setInternalIsOpen(nextState);
1627
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(nextState);
1628
+ };
1629
+ const handleMainClick = () => {
1630
+ if (disabled)
1631
+ return;
1632
+ if (isSpeedDial) {
1633
+ toggleOpen();
1634
+ }
1635
+ else {
1636
+ onClick === null || onClick === void 0 ? void 0 : onClick();
1637
+ }
1638
+ };
1639
+ const handleSubActionClick = (action) => {
1640
+ var _a;
1641
+ if (action.disabled)
1642
+ return;
1643
+ (_a = action.onClick) === null || _a === void 0 ? void 0 : _a.call(action);
1644
+ setInternalIsOpen(false);
1645
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(false);
1646
+ };
1647
+ const positionClasses = {
1648
+ 'bottom-right': 'fixed bottom-6 right-6 z-40',
1649
+ 'bottom-left': 'fixed bottom-6 left-6 z-40',
1650
+ 'bottom-center': 'fixed bottom-6 left-1/2 -translate-x-1/2 z-40',
1651
+ inline: 'relative inline-flex z-10',
1652
+ }[position];
1653
+ const variantClasses = {
1654
+ primary: 'bg-blue-600 hover:bg-blue-700 active:bg-blue-800 text-white shadow-lg shadow-blue-600/30',
1655
+ secondary: 'bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-800 dark:text-gray-100 border border-[var(--ui-border)] shadow-lg',
1656
+ danger: 'bg-red-600 hover:bg-red-700 active:bg-red-800 text-white shadow-lg shadow-red-600/30',
1657
+ dark: 'bg-gray-900 hover:bg-black active:bg-black text-white shadow-lg shadow-gray-900/40',
1658
+ }[variant];
1659
+ const sizeClasses = {
1660
+ sm: label ? 'px-3.5 py-2 text-xs gap-2 rounded-full' : 'p-2.5 rounded-full',
1661
+ md: label ? 'px-5 py-3 text-sm gap-2.5 rounded-full' : 'p-3.5 rounded-full',
1662
+ lg: label ? 'px-6 py-4 text-base gap-3 rounded-full' : 'p-4 rounded-full',
1663
+ }[size];
1664
+ return (jsxs("div", { className: buildClassName(positionClasses, containerClass), "data-testid": "fab-container", children: [isSpeedDial && isOpen && (jsx("div", { className: "fixed inset-0 bg-black/25 backdrop-blur-xs z-30 transition-opacity duration-200", onClick: () => toggleOpen(), "data-testid": "fab-backdrop" })), isSpeedDial && (jsx("div", { className: buildClassName('absolute bottom-full mb-3 flex flex-col gap-2.5 z-40 transition-all duration-200 origin-bottom', position === 'bottom-left'
1665
+ ? 'items-start left-0'
1666
+ : position === 'bottom-center'
1667
+ ? 'items-center left-1/2 -translate-x-1/2'
1668
+ : 'items-end right-0', isOpen
1669
+ ? 'scale-100 opacity-100 pointer-events-auto'
1670
+ : 'scale-90 opacity-0 pointer-events-none'), "data-testid": "fab-speed-dial-menu", children: speedDialActions.map((action) => {
1671
+ const isDanger = action.theme === 'danger';
1672
+ const isPrimary = action.theme === 'primary';
1673
+ return (jsxs("button", { type: "button", disabled: action.disabled, onClick: () => handleSubActionClick(action), className: buildClassName('flex items-center gap-2.5 py-2 px-3.5 rounded-full text-xs font-semibold shadow-md transition-all duration-150 cursor-pointer group', action.disabled && 'opacity-50 cursor-not-allowed pointer-events-none', !action.disabled &&
1674
+ (isDanger
1675
+ ? 'bg-red-600 text-white hover:bg-red-700'
1676
+ : isPrimary
1677
+ ? 'bg-blue-600 text-white hover:bg-blue-700'
1678
+ : 'bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-700 border border-[var(--ui-border)]')), "data-testid": `fab-action-${action.id}`, children: [jsx("span", { className: "text-sm", children: action.icon }), jsx("span", { className: "whitespace-nowrap", children: action.label })] }, action.id));
1679
+ }) })), jsxs("button", { type: "button", disabled: disabled, onClick: handleMainClick, "aria-label": ariaLabel || (typeof label === 'string' ? label : 'Floating action'), "aria-expanded": isSpeedDial ? isOpen : undefined, className: buildClassName('inline-flex items-center justify-center font-semibold transition-all duration-200 cursor-pointer select-none z-40 active:scale-95', disabled && 'opacity-50 cursor-not-allowed pointer-events-none shadow-none', variantClasses, sizeClasses, className), "data-testid": "fab-button", children: [jsx("span", { className: buildClassName('transition-transform duration-200', isOpen && 'rotate-45'), children: isOpen && activeIcon ? activeIcon : icon }), label && jsx("span", { className: "whitespace-nowrap", children: label })] })] }));
1680
+ }
1681
+ FloatingActionButton.displayName = 'FloatingActionButton';
1682
+
1683
+ const GAP_MAP = {
1684
+ none: 'gap-0',
1685
+ xs: 'gap-1',
1686
+ sm: 'gap-2',
1687
+ md: 'gap-4',
1688
+ lg: 'gap-6',
1689
+ xl: 'gap-8',
1690
+ '2xl': 'gap-12',
1691
+ };
1692
+ const GAP_X_MAP = {
1693
+ none: 'gap-x-0',
1694
+ xs: 'gap-x-1',
1695
+ sm: 'gap-x-2',
1696
+ md: 'gap-x-4',
1697
+ lg: 'gap-x-6',
1698
+ xl: 'gap-x-8',
1699
+ '2xl': 'gap-x-12',
1700
+ };
1701
+ const GAP_Y_MAP = {
1702
+ none: 'gap-y-0',
1703
+ xs: 'gap-y-1',
1704
+ sm: 'gap-y-2',
1705
+ md: 'gap-y-4',
1706
+ lg: 'gap-y-6',
1707
+ xl: 'gap-y-8',
1708
+ '2xl': 'gap-y-12',
1709
+ };
1710
+ const ALIGN_MAP = {
1711
+ start: 'items-start',
1712
+ center: 'items-center',
1713
+ end: 'items-end',
1714
+ baseline: 'items-baseline',
1715
+ stretch: 'items-stretch',
1716
+ };
1717
+ const JUSTIFY_MAP = {
1718
+ start: 'justify-start',
1719
+ center: 'justify-center',
1720
+ end: 'justify-end',
1721
+ between: 'justify-between',
1722
+ around: 'justify-around',
1723
+ evenly: 'justify-evenly',
1724
+ };
1725
+ const DIRECTION_MAP = {
1726
+ row: 'flex-row',
1727
+ 'row-reverse': 'flex-row-reverse',
1728
+ col: 'flex-col',
1729
+ 'col-reverse': 'flex-col-reverse',
1730
+ };
1731
+ const WRAP_MAP = {
1732
+ wrap: 'flex-wrap',
1733
+ nowrap: 'flex-nowrap',
1734
+ 'wrap-reverse': 'flex-wrap-reverse',
1735
+ };
1736
+ /**
1737
+ * Resolves the `order` prop to inline styles when it's a raw number.
1738
+ *
1739
+ * `'first'` / `'last'` map to the static `order-first`/`order-last` Tailwind
1740
+ * utilities (safe, since those exact class names are literal elsewhere).
1741
+ * Arbitrary numeric orders can't be expressed as a safe literal class (the
1742
+ * value is unbounded), so they're applied as an inline `order` style instead
1743
+ * — that works regardless of what the consuming app's Tailwind build scans.
1744
+ */
1745
+ const resolveOrderStyle = (order) => typeof order === 'number' ? { order } : undefined;
1746
+ const resolveOrderClassName = (order) => {
1747
+ if (order === 'first')
1748
+ return '-order-1';
1749
+ if (order === 'last')
1750
+ return 'order-last';
1751
+ return undefined;
1752
+ };
1753
+ /** Width-fraction span classes used by `Flex.Item` (unprefixed / base breakpoint). */
1754
+ const FLEX_SPAN_MAP = {
1755
+ 1: 'w-1/12 flex-none',
1756
+ 2: 'w-2/12 flex-none',
1757
+ 3: 'w-3/12 flex-none',
1758
+ 4: 'w-4/12 flex-none',
1759
+ 5: 'w-5/12 flex-none',
1760
+ 6: 'w-6/12 flex-none',
1761
+ 7: 'w-7/12 flex-none',
1762
+ 8: 'w-8/12 flex-none',
1763
+ 9: 'w-9/12 flex-none',
1764
+ 10: 'w-10/12 flex-none',
1765
+ 11: 'w-11/12 flex-none',
1766
+ 12: 'w-full flex-none',
1767
+ auto: 'w-auto flex-none',
1768
+ full: 'w-full flex-none',
1769
+ };
1770
+ const FLEX_SM_SPAN_MAP = {
1771
+ 1: 'sm:w-1/12',
1772
+ 2: 'sm:w-2/12',
1773
+ 3: 'sm:w-3/12',
1774
+ 4: 'sm:w-4/12',
1775
+ 5: 'sm:w-5/12',
1776
+ 6: 'sm:w-6/12',
1777
+ 7: 'sm:w-7/12',
1778
+ 8: 'sm:w-8/12',
1779
+ 9: 'sm:w-9/12',
1780
+ 10: 'sm:w-10/12',
1781
+ 11: 'sm:w-11/12',
1782
+ 12: 'sm:w-full',
1783
+ auto: 'sm:w-auto',
1784
+ full: 'sm:w-full',
1785
+ };
1786
+ const FLEX_MD_SPAN_MAP = {
1787
+ 1: 'md:w-1/12',
1788
+ 2: 'md:w-2/12',
1789
+ 3: 'md:w-3/12',
1790
+ 4: 'md:w-4/12',
1791
+ 5: 'md:w-5/12',
1792
+ 6: 'md:w-6/12',
1793
+ 7: 'md:w-7/12',
1794
+ 8: 'md:w-8/12',
1795
+ 9: 'md:w-9/12',
1796
+ 10: 'md:w-10/12',
1797
+ 11: 'md:w-11/12',
1798
+ 12: 'md:w-full',
1799
+ auto: 'md:w-auto',
1800
+ full: 'md:w-full',
1801
+ };
1802
+ const FLEX_LG_SPAN_MAP = {
1803
+ 1: 'lg:w-1/12',
1804
+ 2: 'lg:w-2/12',
1805
+ 3: 'lg:w-3/12',
1806
+ 4: 'lg:w-4/12',
1807
+ 5: 'lg:w-5/12',
1808
+ 6: 'lg:w-6/12',
1809
+ 7: 'lg:w-7/12',
1810
+ 8: 'lg:w-8/12',
1811
+ 9: 'lg:w-9/12',
1812
+ 10: 'lg:w-10/12',
1813
+ 11: 'lg:w-11/12',
1814
+ 12: 'lg:w-full',
1815
+ auto: 'lg:w-auto',
1816
+ full: 'lg:w-full',
1817
+ };
1818
+ const FLEX_XL_SPAN_MAP = {
1819
+ 1: 'xl:w-1/12',
1820
+ 2: 'xl:w-2/12',
1821
+ 3: 'xl:w-3/12',
1822
+ 4: 'xl:w-4/12',
1823
+ 5: 'xl:w-5/12',
1824
+ 6: 'xl:w-6/12',
1825
+ 7: 'xl:w-7/12',
1826
+ 8: 'xl:w-8/12',
1827
+ 9: 'xl:w-9/12',
1828
+ 10: 'xl:w-10/12',
1829
+ 11: 'xl:w-11/12',
1830
+ 12: 'xl:w-full',
1831
+ auto: 'xl:w-auto',
1832
+ full: 'xl:w-full',
1833
+ };
1834
+ const FLEX_XXL_SPAN_MAP = {
1835
+ 1: '2xl:w-1/12',
1836
+ 2: '2xl:w-2/12',
1837
+ 3: '2xl:w-3/12',
1838
+ 4: '2xl:w-4/12',
1839
+ 5: '2xl:w-5/12',
1840
+ 6: '2xl:w-6/12',
1841
+ 7: '2xl:w-7/12',
1842
+ 8: '2xl:w-8/12',
1843
+ 9: '2xl:w-9/12',
1844
+ 10: '2xl:w-10/12',
1845
+ 11: '2xl:w-11/12',
1846
+ 12: '2xl:w-full',
1847
+ auto: '2xl:w-auto',
1848
+ full: '2xl:w-full',
1849
+ };
1850
+ /** `col-span-*` classes used by `Grid.Col` (unprefixed / base breakpoint). */
1851
+ const GRID_SPAN_MAP = {
1852
+ 1: 'col-span-1',
1853
+ 2: 'col-span-2',
1854
+ 3: 'col-span-3',
1855
+ 4: 'col-span-4',
1856
+ 5: 'col-span-5',
1857
+ 6: 'col-span-6',
1858
+ 7: 'col-span-7',
1859
+ 8: 'col-span-8',
1860
+ 9: 'col-span-9',
1861
+ 10: 'col-span-10',
1862
+ 11: 'col-span-11',
1863
+ 12: 'col-span-12',
1864
+ auto: 'col-auto',
1865
+ full: 'col-span-full',
1866
+ };
1867
+ const GRID_SM_SPAN_MAP = {
1868
+ 1: 'sm:col-span-1',
1869
+ 2: 'sm:col-span-2',
1870
+ 3: 'sm:col-span-3',
1871
+ 4: 'sm:col-span-4',
1872
+ 5: 'sm:col-span-5',
1873
+ 6: 'sm:col-span-6',
1874
+ 7: 'sm:col-span-7',
1875
+ 8: 'sm:col-span-8',
1876
+ 9: 'sm:col-span-9',
1877
+ 10: 'sm:col-span-10',
1878
+ 11: 'sm:col-span-11',
1879
+ 12: 'sm:col-span-12',
1880
+ auto: 'sm:col-auto',
1881
+ full: 'sm:col-span-full',
1882
+ };
1883
+ const GRID_MD_SPAN_MAP = {
1884
+ 1: 'md:col-span-1',
1885
+ 2: 'md:col-span-2',
1886
+ 3: 'md:col-span-3',
1887
+ 4: 'md:col-span-4',
1888
+ 5: 'md:col-span-5',
1889
+ 6: 'md:col-span-6',
1890
+ 7: 'md:col-span-7',
1891
+ 8: 'md:col-span-8',
1892
+ 9: 'md:col-span-9',
1893
+ 10: 'md:col-span-10',
1894
+ 11: 'md:col-span-11',
1895
+ 12: 'md:col-span-12',
1896
+ auto: 'md:col-auto',
1897
+ full: 'md:col-span-full',
1898
+ };
1899
+ const GRID_LG_SPAN_MAP = {
1900
+ 1: 'lg:col-span-1',
1901
+ 2: 'lg:col-span-2',
1902
+ 3: 'lg:col-span-3',
1903
+ 4: 'lg:col-span-4',
1904
+ 5: 'lg:col-span-5',
1905
+ 6: 'lg:col-span-6',
1906
+ 7: 'lg:col-span-7',
1907
+ 8: 'lg:col-span-8',
1908
+ 9: 'lg:col-span-9',
1909
+ 10: 'lg:col-span-10',
1910
+ 11: 'lg:col-span-11',
1911
+ 12: 'lg:col-span-12',
1912
+ auto: 'lg:col-auto',
1913
+ full: 'lg:col-span-full',
1914
+ };
1915
+ const GRID_XL_SPAN_MAP = {
1916
+ 1: 'xl:col-span-1',
1917
+ 2: 'xl:col-span-2',
1918
+ 3: 'xl:col-span-3',
1919
+ 4: 'xl:col-span-4',
1920
+ 5: 'xl:col-span-5',
1921
+ 6: 'xl:col-span-6',
1922
+ 7: 'xl:col-span-7',
1923
+ 8: 'xl:col-span-8',
1924
+ 9: 'xl:col-span-9',
1925
+ 10: 'xl:col-span-10',
1926
+ 11: 'xl:col-span-11',
1927
+ 12: 'xl:col-span-12',
1928
+ auto: 'xl:col-auto',
1929
+ full: 'xl:col-span-full',
1930
+ };
1931
+ const GRID_XXL_SPAN_MAP = {
1932
+ 1: '2xl:col-span-1',
1933
+ 2: '2xl:col-span-2',
1934
+ 3: '2xl:col-span-3',
1935
+ 4: '2xl:col-span-4',
1936
+ 5: '2xl:col-span-5',
1937
+ 6: '2xl:col-span-6',
1938
+ 7: '2xl:col-span-7',
1939
+ 8: '2xl:col-span-8',
1940
+ 9: '2xl:col-span-9',
1941
+ 10: '2xl:col-span-10',
1942
+ 11: '2xl:col-span-11',
1943
+ 12: '2xl:col-span-12',
1944
+ auto: '2xl:col-auto',
1945
+ full: '2xl:col-span-full',
1946
+ };
1947
+ /**
1948
+ * Preset track-count classes for `Grid`'s `cols` prop. Each preset
1949
+ * progressively reveals more columns at wider breakpoints so a grid is
1950
+ * responsive out of the box without the caller specifying per-item spans.
1951
+ */
1952
+ const GRID_COLS_MAP = {
1953
+ 1: 'grid-cols-1',
1954
+ 2: 'grid-cols-1 sm:grid-cols-2',
1955
+ 3: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3',
1956
+ 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
1957
+ 5: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5',
1958
+ 6: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6',
1959
+ 7: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-7',
1960
+ 8: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-8',
1961
+ 9: 'grid-cols-1 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-9',
1962
+ 10: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-10',
1963
+ 11: 'grid-cols-1 sm:grid-cols-3 md:grid-cols-6 lg:grid-cols-11',
1964
+ 12: 'grid-cols-12',
1965
+ auto: 'grid-cols-none auto-cols-auto',
1966
+ };
1967
+
1968
+ const FlexItem = forwardRef((props, ref) => {
1969
+ const { as: Component = 'div', span, sm, md, lg, xl, xxl, grow, shrink, order, className, style, children, ...restProps } = props;
1970
+ const classes = buildClassName('min-w-0 box-border', span && FLEX_SPAN_MAP[String(span)], sm && FLEX_SM_SPAN_MAP[String(sm)], md && FLEX_MD_SPAN_MAP[String(md)], lg && FLEX_LG_SPAN_MAP[String(lg)], xl && FLEX_XL_SPAN_MAP[String(xl)], xxl && FLEX_XXL_SPAN_MAP[String(xxl)], resolveOrderClassName(order), grow === true && 'grow', grow === false && 'grow-0', shrink === true && 'shrink', shrink === false && 'shrink-0', className);
1971
+ return (jsx(Component, { ref: ref, className: classes, style: { ...resolveOrderStyle(order), ...style }, ...restProps, children: children }));
1972
+ });
1973
+ FlexItem.displayName = 'Flex.Item';
1974
+ const Flex = forwardRef((props, ref) => {
1975
+ const { as: Component = 'div', gap, gapX, gapY, align = 'stretch', justify = 'start', direction = 'row', wrap = 'wrap', inline = false, className, children, ...restProps } = props;
1976
+ const classes = buildClassName(inline ? 'inline-flex' : 'flex', DIRECTION_MAP[direction] || 'flex-row', WRAP_MAP[wrap] || 'flex-wrap', 'w-full', !gapX && !gapY && gap && GAP_MAP[gap], gapX && GAP_X_MAP[gapX], gapY && GAP_Y_MAP[gapY], ALIGN_MAP[align] || 'items-stretch', JUSTIFY_MAP[justify] || 'justify-start', className);
1977
+ return (jsx(Component, { ref: ref, className: classes, ...restProps, children: children }));
1978
+ });
1979
+ Flex.Item = FlexItem;
1980
+ Flex.Col = FlexItem;
1981
+ Flex.displayName = 'Flex';
1982
+
1983
+ const GridContext = createContext({ isAutoFit: false });
1984
+ const GridCol = forwardRef((props, ref) => {
1985
+ const { as: Component = 'div', span, sm, md, lg, xl, xxl, grow, shrink, order, className, style, children, ...restProps } = props;
1986
+ const { isAutoFit } = useContext(GridContext);
1987
+ const classes = buildClassName('min-w-0 box-border', span ? GRID_SPAN_MAP[String(span)] : isAutoFit ? undefined : 'col-span-12 sm:col-span-4', sm && GRID_SM_SPAN_MAP[String(sm)], md && GRID_MD_SPAN_MAP[String(md)], lg && GRID_LG_SPAN_MAP[String(lg)], xl && GRID_XL_SPAN_MAP[String(xl)], xxl && GRID_XXL_SPAN_MAP[String(xxl)], resolveOrderClassName(order), grow === true && 'grow', grow === false && 'grow-0', shrink === true && 'shrink', shrink === false && 'shrink-0', className);
1988
+ return (jsx(Component, { ref: ref, className: classes, style: { ...resolveOrderStyle(order), ...style }, ...restProps, children: children }));
1989
+ });
1990
+ GridCol.displayName = 'Grid.Col';
1991
+ const Grid = forwardRef((props, ref) => {
1992
+ const { as: Component = 'div', cols, minColWidth, autoFit = true, gap = 'md', gapX, gapY, align = 'stretch', justify, direction = 'row', wrap = 'wrap', flex = false, inline = false, className, style, children, ...restProps } = props;
1993
+ const isAutoFit = Boolean(!flex && minColWidth);
1994
+ const classes = buildClassName(flex ? (inline ? 'inline-flex' : 'flex') : inline ? 'inline-grid' : 'grid', flex && (DIRECTION_MAP[direction] || 'flex-row'), flex && (WRAP_MAP[wrap] || 'flex-wrap'), !flex &&
1995
+ !minColWidth &&
1996
+ (cols ? GRID_COLS_MAP[String(cols)] || 'grid-cols-12' : 'grid-cols-12'), !flex && 'justify-items-stretch', 'w-full', !gapX && !gapY && GAP_MAP[gap], gapX && GAP_X_MAP[gapX], gapY && GAP_Y_MAP[gapY], ALIGN_MAP[align] || 'items-stretch', justify && (JUSTIFY_MAP[justify] || 'justify-start'), className);
1997
+ const gridTemplateColumns = !flex && minColWidth
1998
+ ? `repeat(${autoFit ? 'auto-fit' : 'auto-fill'}, minmax(${minColWidth}, 1fr))`
1999
+ : undefined;
2000
+ return (jsx(GridContext.Provider, { value: { isAutoFit }, children: jsx(Component, { ref: ref, className: classes, style: gridTemplateColumns ? { gridTemplateColumns, ...style } : style, ...restProps, children: children }) }));
2001
+ });
2002
+ Grid.Col = GridCol;
2003
+ Grid.Item = GridCol;
2004
+ Grid.displayName = 'Grid';
2005
+
2006
+ const sizeClasses$4 = {
2007
+ sm: {
2008
+ input: 'px-2.5 py-1.5 text-xs leading-5',
2009
+ group: 'w-8 text-xs',
2010
+ icon: 'size-3.5',
2011
+ text: 'text-xs',
2012
+ },
2013
+ md: {
2014
+ input: 'px-3.5 py-2 text-sm leading-6',
1527
2015
  group: 'w-10 text-sm',
1528
2016
  icon: 'size-4',
1529
2017
  text: 'text-sm',
@@ -1539,9 +2027,9 @@ function buildInputClass(className, { isFocusWithin = false, disabled = false, h
1539
2027
  const currentSize = sizeClasses$4[size] || sizeClasses$4.md;
1540
2028
  return buildClassName('transition-all duration-150', 'block w-full rounded-lg bg-white', currentSize.input, 'text-gray-900 outline outline-1 -outline-offset-1', hasError
1541
2029
  ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
1542
- : 'outline-gray-300 dark:outline-gray-600', disabled
1543
- ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 dark:text-gray-600 dark:placeholder-gray-600 placeholder-gray-400 outline-gray-200 dark:outline-gray-700'
1544
- : 'bg-white dark:bg-gray-700 dark:text-white outline-gray-300 dark:outline-gray-600 dark:placeholder-gray-400 placeholder-gray-400', isFocusWithin
2030
+ : 'outline-[var(--ui-border)]', disabled
2031
+ ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 dark:text-gray-600 dark:placeholder-gray-600 placeholder-gray-400 outline-[var(--ui-border-muted)]'
2032
+ : 'bg-white dark:bg-gray-700 dark:text-white outline-[var(--ui-border)] dark:placeholder-gray-400 placeholder-gray-400', isFocusWithin
1545
2033
  ? 'focus-within:outline-[var(--ui-focus-ring)] focus-within:outline-2 focus-within:-outline-offset-2'
1546
2034
  : 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', className);
1547
2035
  }
@@ -1579,11 +2067,11 @@ const Input = forwardRef((props, ref) => {
1579
2067
  const actualRightGroup = rightGroup !== null && rightGroup !== void 0 ? rightGroup : (showClearButton ? (jsx("button", { type: "button", onClick: handleClear, className: "p-1 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer", title: "Clear text", tabIndex: -1, children: jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: currentSize.icon, children: jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) }) })) : null);
1580
2068
  const hasRightGroup = actualRightGroup !== null && actualRightGroup !== undefined;
1581
2069
  const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
1582
- return (jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsx("span", { className: "inline-flex items-center px-3 rounded-l-lg border border-r-0 border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: prefix })), jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), jsx("input", { ref: innerRef, autoComplete: "off", ...inputProps, value: value, defaultValue: defaultValue, onChange: handleInputChange, maxLength: maxLength, name: name, id: id, type: type, className: buildClassName(buildInputClass(className, {
2070
+ return (jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsx("span", { className: "inline-flex items-center px-3 rounded-l-lg border border-r-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: prefix })), jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), jsx("input", { ref: innerRef, autoComplete: "off", ...inputProps, value: value, defaultValue: defaultValue, onChange: handleInputChange, maxLength: maxLength, name: name, id: id, type: type, className: buildClassName(buildInputClass(className, {
1583
2071
  disabled: inputProps.disabled,
1584
2072
  hasError,
1585
2073
  size,
1586
- }), prefix ? '!rounded-l-none' : '', suffix ? '!rounded-r-none' : '', hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '') }), hasRightGroup && (jsx("span", { className: buildClassName('absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: actualRightGroup }))] }), suffix && (jsx("span", { className: "inline-flex items-center px-3 rounded-r-lg border border-l-0 border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: suffix }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
2074
+ }), prefix ? '!rounded-l-none' : '', suffix ? '!rounded-r-none' : '', hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '') }), hasRightGroup && (jsx("span", { className: buildClassName('absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: actualRightGroup }))] }), suffix && (jsx("span", { className: "inline-flex items-center px-3 rounded-r-lg border border-l-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: suffix }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
1587
2075
  ? 'text-red-500 font-semibold'
1588
2076
  : 'text-gray-400 dark:text-gray-500'), children: [charLength, maxLength ? ` / ${maxLength}` : ''] }))] })) : null] }));
1589
2077
  });
@@ -1633,6 +2121,170 @@ const PasswordInput = forwardRef((props, ref) => {
1633
2121
  });
1634
2122
  PasswordInput.displayName = 'PasswordInput';
1635
2123
 
2124
+ function PinInput({ length = 4, value: externalValue, onChange, onComplete, mask = false, size = 'md', type = 'numeric', error, disabled = false, autoFocus = false, containerClass = '', inputClass = '', }) {
2125
+ const [internalValue, setInternalValue] = useState('');
2126
+ const inputRefs = useRef([]);
2127
+ const pinValue = externalValue !== undefined ? externalValue : internalValue;
2128
+ const digits = Array.from({ length }, (_, i) => pinValue[i] || '');
2129
+ useEffect(() => {
2130
+ if (autoFocus && inputRefs.current[0] && !disabled) {
2131
+ inputRefs.current[0].focus();
2132
+ }
2133
+ }, [autoFocus, disabled]);
2134
+ const updatePin = (newDigits) => {
2135
+ const newPin = newDigits.join('').slice(0, length);
2136
+ setInternalValue(newPin);
2137
+ onChange === null || onChange === void 0 ? void 0 : onChange(newPin);
2138
+ if (newPin.length === length) {
2139
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(newPin);
2140
+ }
2141
+ };
2142
+ const handleInputChange = (e, index) => {
2143
+ var _a;
2144
+ const char = e.target.value.slice(-1);
2145
+ if (!char)
2146
+ return;
2147
+ const isValid = type === 'numeric' ? /^[0-9]$/.test(char) : /^[a-zA-Z0-9]$/.test(char);
2148
+ if (!isValid)
2149
+ return;
2150
+ const nextDigits = [...digits];
2151
+ nextDigits[index] = char;
2152
+ updatePin(nextDigits);
2153
+ if (index < length - 1 && inputRefs.current[index + 1]) {
2154
+ (_a = inputRefs.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
2155
+ }
2156
+ };
2157
+ const handleKeyDown = (e, index) => {
2158
+ var _a, _b, _c;
2159
+ if (e.key === 'Backspace') {
2160
+ if (!digits[index] && index > 0 && inputRefs.current[index - 1]) {
2161
+ const nextDigits = [...digits];
2162
+ nextDigits[index - 1] = '';
2163
+ updatePin(nextDigits);
2164
+ (_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
2165
+ }
2166
+ else if (digits[index]) {
2167
+ const nextDigits = [...digits];
2168
+ nextDigits[index] = '';
2169
+ updatePin(nextDigits);
2170
+ }
2171
+ }
2172
+ else if (e.key === 'ArrowLeft' && index > 0) {
2173
+ (_b = inputRefs.current[index - 1]) === null || _b === void 0 ? void 0 : _b.focus();
2174
+ }
2175
+ else if (e.key === 'ArrowRight' && index < length - 1) {
2176
+ (_c = inputRefs.current[index + 1]) === null || _c === void 0 ? void 0 : _c.focus();
2177
+ }
2178
+ };
2179
+ const handlePaste = (e) => {
2180
+ e.preventDefault();
2181
+ if (disabled)
2182
+ return;
2183
+ const pastedData = e.clipboardData.getData('text').trim();
2184
+ const regex = type === 'numeric' ? /[0-9]/g : /[a-zA-Z0-9]/g;
2185
+ const matchedChars = pastedData.match(regex) || [];
2186
+ if (matchedChars.length === 0)
2187
+ return;
2188
+ const nextDigits = Array.from({ length }, (_, i) => matchedChars[i] || '');
2189
+ updatePin(nextDigits);
2190
+ const focusIndex = Math.min(matchedChars.length, length) - 1;
2191
+ const targetRef = inputRefs.current[focusIndex >= 0 ? focusIndex : 0];
2192
+ targetRef === null || targetRef === void 0 ? void 0 : targetRef.focus();
2193
+ };
2194
+ const sizeClasses = {
2195
+ sm: 'size-9 text-sm rounded-lg',
2196
+ md: 'size-11 text-base rounded-xl',
2197
+ lg: 'size-14 text-lg rounded-2xl',
2198
+ }[size];
2199
+ return (jsxs("div", { className: buildClassName('space-y-1.5', containerClass), "data-testid": "pin-input-container", children: [jsx("div", { className: "flex items-center gap-2.5 sm:gap-3", children: digits.map((digit, index) => {
2200
+ const isFilled = Boolean(digit);
2201
+ return (jsx("input", { ref: (el) => {
2202
+ inputRefs.current[index] = el;
2203
+ }, type: mask ? 'password' : 'text', inputMode: type === 'numeric' ? 'numeric' : 'text', pattern: type === 'numeric' ? '[0-9]*' : undefined, maxLength: 1, value: digit, disabled: disabled, onChange: (e) => handleInputChange(e, index), onKeyDown: (e) => handleKeyDown(e, index), onPaste: handlePaste, className: buildClassName('text-center font-bold transition-all duration-150 outline outline-1 -outline-offset-1 select-none', sizeClasses, disabled
2204
+ ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-600 outline-[var(--ui-border-muted)]'
2205
+ : error
2206
+ ? 'bg-red-50/50 dark:bg-red-950/20 text-red-600 dark:text-red-400 outline-red-500 focus:outline-red-500 focus:outline-2 focus:-outline-offset-2'
2207
+ : isFilled
2208
+ ? 'bg-blue-50/30 dark:bg-blue-950/30 text-gray-900 dark:text-white outline-blue-500 dark:outline-blue-400 focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2'
2209
+ : 'bg-white dark:bg-gray-800 text-gray-900 dark:text-white outline-[var(--ui-border)] focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', inputClass), "data-testid": `pin-input-box-${index}` }, index));
2210
+ }) }), typeof error === 'string' && (jsx("div", { className: "text-xs text-red-500 dark:text-red-400 font-medium pt-0.5", "data-testid": "pin-input-error", children: error }))] }));
2211
+ }
2212
+ PinInput.displayName = 'PinInput';
2213
+
2214
+ function PullArrowIcon({ progress }) {
2215
+ const rotation = Math.min(180, progress * 180);
2216
+ return (jsx("svg", { className: "size-4 text-blue-600 dark:text-blue-400 transition-transform duration-150", style: { transform: `rotate(${rotation}deg)` }, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 14l-7 7m0 0l-7-7m7 7V3" }) }));
2217
+ }
2218
+ function PullToRefresh({ onRefresh, pullThreshold = 70, maxPullDistance = 120, disabled = false, refreshing: externalRefreshing, pullingContent, refreshingContent, children, className = '', contentClass = '', }) {
2219
+ const containerRef = useRef(null);
2220
+ const startYRef = useRef(0);
2221
+ const isPullingRef = useRef(false);
2222
+ const [pullDistance, setPullDistance] = useState(0);
2223
+ const [internalRefreshing, setInternalRefreshing] = useState(false);
2224
+ const isRefreshing = externalRefreshing !== undefined ? externalRefreshing : internalRefreshing;
2225
+ const handleTouchStart = useCallback((e) => {
2226
+ if (disabled || isRefreshing)
2227
+ return;
2228
+ const container = containerRef.current;
2229
+ if (container && container.scrollTop === 0) {
2230
+ startYRef.current = e.touches[0].clientY;
2231
+ isPullingRef.current = true;
2232
+ }
2233
+ }, [disabled, isRefreshing]);
2234
+ const handleTouchMove = useCallback((e) => {
2235
+ if (!isPullingRef.current || disabled || isRefreshing)
2236
+ return;
2237
+ const container = containerRef.current;
2238
+ if (!container || container.scrollTop > 0)
2239
+ return;
2240
+ const currentY = e.touches[0].clientY;
2241
+ const rawDistance = currentY - startYRef.current;
2242
+ if (rawDistance > 0) {
2243
+ // Rubber-band resistance formula
2244
+ const dampened = Math.min(maxPullDistance, rawDistance * 0.45);
2245
+ setPullDistance(dampened);
2246
+ if (e.cancelable) {
2247
+ e.preventDefault();
2248
+ }
2249
+ }
2250
+ else {
2251
+ setPullDistance(0);
2252
+ }
2253
+ }, [disabled, isRefreshing, maxPullDistance]);
2254
+ const handleTouchEnd = useCallback(async () => {
2255
+ if (!isPullingRef.current || disabled || isRefreshing)
2256
+ return;
2257
+ isPullingRef.current = false;
2258
+ if (pullDistance >= pullThreshold) {
2259
+ setPullDistance(pullThreshold);
2260
+ setInternalRefreshing(true);
2261
+ try {
2262
+ await onRefresh();
2263
+ }
2264
+ finally {
2265
+ setInternalRefreshing(false);
2266
+ setPullDistance(0);
2267
+ }
2268
+ }
2269
+ else {
2270
+ setPullDistance(0);
2271
+ }
2272
+ }, [disabled, isRefreshing, onRefresh, pullDistance, pullThreshold]);
2273
+ const progress = Math.min(1, pullDistance / pullThreshold);
2274
+ const isReady = pullDistance >= pullThreshold;
2275
+ return (jsxs("div", { ref: containerRef, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, className: buildClassName('relative overflow-y-auto overscroll-none', className), "data-testid": "pull-to-refresh-container", children: [jsx("div", { className: "left-0 right-0 top-0 flex items-center justify-center pointer-events-none transition-all duration-150 z-20", style: {
2276
+ height: isRefreshing ? `${pullThreshold}px` : `${pullDistance}px`,
2277
+ opacity: pullDistance > 0 || isRefreshing ? 1 : 0,
2278
+ }, "data-testid": "pull-to-refresh-indicator", children: jsx("div", { className: "flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-white dark:bg-gray-800 border border-[var(--ui-border)] shadow-md text-xs font-semibold text-gray-700 dark:text-gray-200", children: isRefreshing ? (refreshingContent || (jsxs(Fragment, { children: [jsx(Loader, { size: "sm" }), jsx("span", { children: "Refreshing..." })] }))) : pullingContent ? (pullingContent) : (jsxs(Fragment, { children: [jsx(PullArrowIcon, { progress: progress }), jsx("span", { children: isReady ? 'Release to refresh' : 'Pull down to refresh' })] })) }) }), jsx("div", { className: buildClassName('transition-transform duration-150', contentClass), style: {
2279
+ transform: isRefreshing
2280
+ ? `translateY(${pullThreshold}px)`
2281
+ : pullDistance > 0
2282
+ ? `translateY(${pullDistance}px)`
2283
+ : 'translateY(0px)',
2284
+ }, "data-testid": "pull-to-refresh-content", children: children })] }));
2285
+ }
2286
+ PullToRefresh.displayName = 'PullToRefresh';
2287
+
1636
2288
  const SIZE_MAP = {
1637
2289
  sm: 'size-4',
1638
2290
  md: 'size-4.5',
@@ -1648,8 +2300,8 @@ const Radio = forwardRef((props, ref) => {
1648
2300
  const generatedId = useId();
1649
2301
  const radioId = id !== null && id !== void 0 ? id : (name && rest.value ? `${name}-${rest.value}` : generatedId);
1650
2302
  return (jsxs("div", { className: buildClassName(wrapperClass), children: [jsxs("div", { className: buildClassName('flex items-start gap-2.5', containerClass), children: [jsx("div", { className: "grid place-items-center shrink-0 pt-0.5", children: jsx("input", { ref: ref, ...rest, id: radioId, name: name, type: "radio", disabled: disabled, "aria-checked": rest.checked, className: buildClassName('peer transition-all col-start-1 row-start-1 appearance-none shrink-0 rounded-full', 'border focus:ring-2 focus:ring-offset-2', 'checked:border-5 checked:bg-white', 'dark:focus:ring-offset-gray-800', SIZE_MAP[size], THEME_MAP[theme], disabled
1651
- ? 'border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 pointer-events-none'
1652
- : 'bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer', className) }) }), (label || description) && (jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsx(Label, { htmlFor: radioId, className: buildClassName(disabled
2303
+ ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'
2304
+ : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer', className) }) }), (label || description) && (jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsx(Label, { htmlFor: radioId, className: buildClassName(disabled
1653
2305
  ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'
1654
2306
  : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium', labelClass), children: label })), description && (jsx("p", { className: buildClassName('text-xs leading-normal', disabled
1655
2307
  ? 'text-gray-300 dark:text-gray-600'
@@ -1688,7 +2340,7 @@ const RadioGroup = (props) => {
1688
2340
  if (isCards) {
1689
2341
  return (jsxs("label", { htmlFor: `${name}-${item.value}`, className: buildClassName('relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1', isSelected
1690
2342
  ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'
1691
- : 'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
2343
+ : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
1692
2344
  'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsx(Radio, { name: name, id: `${name}-${item.value}`, value: item.value, "aria-label": item.label, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange, containerClass: "pt-0.5" }), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
1693
2345
  }
1694
2346
  return (jsx(Radio, { name: name, id: `${name}-${item.value}`, label: item.label, description: item.description, value: item.value, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange }, item.value));
@@ -1783,7 +2435,7 @@ const RadioSwitch = ({ label, items, selected, size = 'md', theme = 'primary', d
1783
2435
  onChange(getValue(nextItem));
1784
2436
  }
1785
2437
  };
1786
- return (jsxs("div", { ref: containerRef, role: "radiogroup", tabIndex: 0, "aria-label": label, onKeyDown: handleGroupKeyDown, className: buildClassName('relative inline-grid grid-flow-col auto-cols-fr items-stretch bg-gray-100 dark:bg-gray-800/80 border border-gray-200/80 dark:border-gray-700/80 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-primary-ring)]', SIZE_CONTAINER_CLASS$1[size], disabled && 'opacity-60 pointer-events-none', wrapperClass), children: [jsx("div", { className: buildClassName('absolute transition-all duration-200 ease-[cubic-bezier(.25,.8,.25,1)] pointer-events-none', THEME_SWITCH_CLASS[theme], size === 'sm' ? 'rounded-md' : 'rounded-lg', style.ready ? 'opacity-100' : 'opacity-0', switchClass), style: {
2438
+ return (jsxs("div", { ref: containerRef, role: "radiogroup", tabIndex: 0, "aria-label": label, onKeyDown: handleGroupKeyDown, className: buildClassName('relative inline-grid grid-flow-col auto-cols-fr items-stretch bg-gray-100 dark:bg-gray-800/80 border border-[var(--ui-border)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-primary-ring)]', SIZE_CONTAINER_CLASS$1[size], disabled && 'opacity-60 pointer-events-none', wrapperClass), children: [jsx("div", { className: buildClassName('absolute transition-all duration-200 ease-[cubic-bezier(.25,.8,.25,1)] pointer-events-none', THEME_SWITCH_CLASS[theme], size === 'sm' ? 'rounded-md' : 'rounded-lg', style.ready ? 'opacity-100' : 'opacity-0', switchClass), style: {
1787
2439
  transform: `translate(${style.left}px, ${style.top}px)`,
1788
2440
  width: style.width,
1789
2441
  height: style.height,
@@ -1963,155 +2615,1112 @@ const RangeSlider = ({ label, labelHint, labelClass = '', containerClass = '', c
1963
2615
  window.addEventListener('pointermove', stablePointerMoveRef.current);
1964
2616
  window.addEventListener('pointerup', stablePointerUpRef.current);
1965
2617
  };
1966
- const handleTrackClick = (e) => {
1967
- if (!trackRef.current)
2618
+ const handleTrackClick = (e) => {
2619
+ if (!trackRef.current)
2620
+ return;
2621
+ const rect = trackRef.current.getBoundingClientRect();
2622
+ const x = Math.min(Math.max(e.clientX - rect.left, 0), rect.width);
2623
+ const rawVal = min + (x / rect.width) * (max - min);
2624
+ const snappedVal = snapToStep(rawVal);
2625
+ const pxMin = (percent(valueMin) / 100) * rect.width;
2626
+ const pxMax = (percent(valueMax) / 100) * rect.width;
2627
+ if (x <= pxMin) {
2628
+ onChange(Math.min(snappedVal, valueMax - step), valueMax);
2629
+ return;
2630
+ }
2631
+ if (x >= pxMax) {
2632
+ onChange(valueMin, Math.max(snappedVal, valueMin + step));
2633
+ return;
2634
+ }
2635
+ const distMin = Math.abs(snappedVal - valueMin);
2636
+ const distMax = Math.abs(snappedVal - valueMax);
2637
+ if (distMin < distMax) {
2638
+ onChange(Math.min(snappedVal, valueMax - step), valueMax);
2639
+ }
2640
+ else {
2641
+ onChange(valueMin, Math.max(snappedVal, valueMin + step));
2642
+ }
2643
+ };
2644
+ // Keyboard accessibility handler for thumbs
2645
+ const handleKeyDown = (thumb) => (e) => {
2646
+ let delta = 0;
2647
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowDown')
2648
+ delta = -step;
2649
+ else if (e.key === 'ArrowRight' || e.key === 'ArrowUp')
2650
+ delta = step;
2651
+ else if (e.key === 'Home') {
2652
+ if (thumb === 'min')
2653
+ onChange(min, valueMax);
2654
+ else
2655
+ onChange(valueMin, valueMin + step);
2656
+ return;
2657
+ }
2658
+ else if (e.key === 'End') {
2659
+ if (thumb === 'min')
2660
+ onChange(valueMax - step, valueMax);
2661
+ else
2662
+ onChange(valueMin, max);
2663
+ return;
2664
+ }
2665
+ if (delta !== 0) {
2666
+ e.preventDefault();
2667
+ if (thumb === 'min') {
2668
+ const next = snapToStep(valueMin + delta);
2669
+ onChange(Math.min(next, valueMax - step), valueMax);
2670
+ }
2671
+ else {
2672
+ const next = snapToStep(valueMax + delta);
2673
+ onChange(valueMin, Math.max(next, valueMin + step));
2674
+ }
2675
+ }
2676
+ };
2677
+ const markEntries = marks
2678
+ ? Object.entries(marks).map(([k, v]) => ({ value: Number(k), label: v }))
2679
+ : null;
2680
+ return (jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), children: [label && (jsxs("div", { className: "flex items-center justify-between mb-1", children: [jsx(Label, { className: labelClass, children: label }), labelHint] })), jsxs("div", { ref: trackRef, onMouseDown: handleTrackClick, className: "relative h-8 select-none w-full flex items-center cursor-pointer", "data-testid": "range-track", children: [jsx("div", { className: buildClassName('absolute top-1/2 left-0 right-0 rounded-full bg-gray-200 dark:bg-gray-700 -translate-y-1/2', currentSize.track) }), jsx("div", { className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full transition-all duration-150 ease-out', hasError ? 'bg-red-500' : 'bg-blue-600 dark:bg-blue-500', currentSize.track), style: {
2681
+ left: `${percent(valueMin)}%`,
2682
+ width: `${percent(valueMax) - percent(valueMin)}%`,
2683
+ } }), jsx("div", { role: "slider", tabIndex: 0, "aria-label": "Minimum value", "aria-valuenow": valueMin, "aria-valuemin": min, "aria-valuemax": valueMax - step, onPointerDown: startDrag('min'), onMouseEnter: () => setHoveringThumb('min'), onMouseLeave: () => setHoveringThumb(null), onKeyDown: handleKeyDown('min'), className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full focus:outline-none', 'bg-white border-2 shadow-md cursor-pointer touch-none', hasError ? 'border-red-600' : 'border-blue-600', 'transition-all duration-150 ease-out', currentSize.thumb, (activeThumbState === 'min' || hoveringThumb === 'min') &&
2684
+ (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2685
+ left: `calc(${percent(valueMin)}% - ${currentSize.thumbPx / 2}px)`,
2686
+ zIndex: activeThumbState === 'min' ? 50 : 30,
2687
+ }, "data-testid": "thumb-min", children: showTooltips && (activeThumbState === 'min' || hoveringThumb === 'min') && (jsxs("div", { className: "absolute -top-7 left-1/2 -translate-x-1/2 px-2 py-0.5 rounded bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-[11px] font-semibold shadow-md pointer-events-none z-50 whitespace-nowrap", children: [Math.round(valueMin), valueSuffix, jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-100" })] })) }), jsx("div", { role: "slider", tabIndex: 0, "aria-label": "Maximum value", "aria-valuenow": valueMax, "aria-valuemin": valueMin + step, "aria-valuemax": max, onPointerDown: startDrag('max'), onMouseEnter: () => setHoveringThumb('max'), onMouseLeave: () => setHoveringThumb(null), onKeyDown: handleKeyDown('max'), className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full focus:outline-none', 'bg-white border-2 shadow-md cursor-pointer touch-none', hasError ? 'border-red-600' : 'border-blue-600', 'transition-all duration-150 ease-out', currentSize.thumb, (activeThumbState === 'max' || hoveringThumb === 'max') &&
2688
+ (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2689
+ left: `calc(${percent(valueMax)}% - ${currentSize.thumbPx / 2}px)`,
2690
+ zIndex: activeThumbState === 'max' ? 50 : 40,
2691
+ }, "data-testid": "thumb-max", children: showTooltips && (activeThumbState === 'max' || hoveringThumb === 'max') && (jsxs("div", { className: "absolute -top-7 left-1/2 -translate-x-1/2 px-2 py-0.5 rounded bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-[11px] font-semibold shadow-md pointer-events-none z-50 whitespace-nowrap", children: [Math.round(valueMax), valueSuffix, jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-100" })] })) })] }), markEntries && (jsx("div", { className: "relative w-full h-4 mt-1", children: markEntries.map((m) => {
2692
+ const markPercent = percent(m.value);
2693
+ return (jsxs("div", { className: "absolute top-0 transform -translate-x-1/2 flex flex-col items-center", style: { left: `${markPercent}%` }, children: [jsx("span", { className: "w-1 h-1.5 bg-gray-300 dark:bg-gray-600 rounded-full" }), jsx("span", { className: "text-[10px] font-medium text-gray-400 dark:text-gray-500 mt-0.5", children: m.label })] }, m.value));
2694
+ }) })), jsxs("div", { className: buildClassName('flex justify-between font-medium text-gray-700 dark:text-gray-300', currentSize.text), children: [jsxs("span", { children: [Math.round(valueMin), valueSuffix] }), jsxs("span", { children: [Math.round(valueMax), valueSuffix] })] }), (showErrorMessage && hasError) || helperText ? (jsx("div", { className: "mt-1", children: showErrorMessage && hasError ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null })) : null] }));
2695
+ };
2696
+ RangeSlider.displayName = 'RangeSlider';
2697
+
2698
+ const useDebounce = (value, delay) => {
2699
+ const [debouncedValue, setDebouncedValue] = useState(value);
2700
+ useEffect(() => {
2701
+ const handler = setTimeout(() => {
2702
+ setDebouncedValue(value);
2703
+ }, delay);
2704
+ // Cancel the timeout if value or delay changes
2705
+ return () => {
2706
+ clearTimeout(handler);
2707
+ };
2708
+ }, [value, delay]);
2709
+ return debouncedValue;
2710
+ };
2711
+ const useDebounceFn = (fn, ms) => {
2712
+ const timeout = useRef(null);
2713
+ useEffect(() => {
2714
+ return () => clearTimeout(timeout.current);
2715
+ }, []);
2716
+ return useCallback((...args) => {
2717
+ clearTimeout(timeout.current);
2718
+ timeout.current = setTimeout(() => fn(...args), ms);
2719
+ }, [fn, ms]);
2720
+ };
2721
+
2722
+ var _path$2;
2723
+ function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); }
2724
+ var SvgCheck = function SvgCheck(props) {
2725
+ return /*#__PURE__*/React.createElement("svg", _extends$2({
2726
+ xmlns: "http://www.w3.org/2000/svg",
2727
+ width: 24,
2728
+ height: 24,
2729
+ fill: "none",
2730
+ stroke: "currentColor",
2731
+ strokeLinecap: "round",
2732
+ strokeLinejoin: "round",
2733
+ strokeWidth: 2,
2734
+ className: "lucide lucide-check-icon lucide-check",
2735
+ viewBox: "0 0 24 24"
2736
+ }, props), _path$2 || (_path$2 = /*#__PURE__*/React.createElement("path", {
2737
+ d: "M20 6 9 17l-5-5"
2738
+ })));
2739
+ };
2740
+
2741
+ var _circle$1, _path$1;
2742
+ function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
2743
+ var SvgCirclePlus = function SvgCirclePlus(props) {
2744
+ return /*#__PURE__*/React.createElement("svg", _extends$1({
2745
+ xmlns: "http://www.w3.org/2000/svg",
2746
+ width: 24,
2747
+ height: 24,
2748
+ fill: "none",
2749
+ stroke: "currentColor",
2750
+ strokeLinecap: "round",
2751
+ strokeLinejoin: "round",
2752
+ strokeWidth: 2,
2753
+ className: "lucide lucide-circle-plus-icon lucide-circle-plus",
2754
+ viewBox: "0 0 24 24"
2755
+ }, props), _circle$1 || (_circle$1 = /*#__PURE__*/React.createElement("circle", {
2756
+ cx: 12,
2757
+ cy: 12,
2758
+ r: 10
2759
+ })), _path$1 || (_path$1 = /*#__PURE__*/React.createElement("path", {
2760
+ d: "M8 12h8M12 8v8"
2761
+ })));
2762
+ };
2763
+
2764
+ var _circle, _path;
2765
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2766
+ var SvgSearch = function SvgSearch(props) {
2767
+ return /*#__PURE__*/React.createElement("svg", _extends({
2768
+ xmlns: "http://www.w3.org/2000/svg",
2769
+ width: 24,
2770
+ height: 24,
2771
+ fill: "none",
2772
+ stroke: "currentColor",
2773
+ strokeLinecap: "round",
2774
+ strokeLinejoin: "round",
2775
+ strokeWidth: 2,
2776
+ className: "lucide lucide-search-icon lucide-search",
2777
+ viewBox: "0 0 24 24"
2778
+ }, props), _circle || (_circle = /*#__PURE__*/React.createElement("circle", {
2779
+ cx: 11,
2780
+ cy: 11,
2781
+ r: 8
2782
+ })), _path || (_path = /*#__PURE__*/React.createElement("path", {
2783
+ d: "m21 21-4.3-4.3"
2784
+ })));
2785
+ };
2786
+
2787
+ const sizeConfigMap = {
2788
+ sm: {
2789
+ input: 'h-8 text-xs px-2.5',
2790
+ icon: 'size-3.5',
2791
+ badgeSize: 'sm',
2792
+ group: 'w-8',
2793
+ },
2794
+ md: {
2795
+ input: 'h-10 text-sm px-3',
2796
+ icon: 'size-4',
2797
+ badgeSize: 'md',
2798
+ group: 'w-10',
2799
+ },
2800
+ lg: {
2801
+ input: 'h-12 text-base px-3.5',
2802
+ icon: 'size-5',
2803
+ badgeSize: 'md',
2804
+ group: 'w-12',
2805
+ },
2806
+ };
2807
+ function MobilePicker(props) {
2808
+ const { options = [], groups, selected = null, onChange = () => { }, size = 'md', labelKey = 'label', valueKey = 'value', id, name, label, labelWrapperClass, labelClass, labelHint, title, description, placeholder = 'Choose an option...', disabled = false, multiple = false, maxSelection, showSelectAll = false, confirmText = 'Apply Selection', searchable = true, searchPlaceholder = 'Search options...', async = false, onSearch, loading = false, typeToSearchText = 'Type to search options...', filterOption, quickOptions, quickOptionsTitle = 'Quick Picks', allowClear = false, allowFreeText = false, allowAdd = false, addNewText = 'Create', onAdd = () => { }, leftGroup, error, showErrorMessage = true, helperText, noOptionsText = 'No options available', renderOption, containerClass, sheetClass, } = props;
2809
+ const [isOpen, setIsOpen] = useState(false);
2810
+ const [query, setQuery] = useState('');
2811
+ const debouncedQuery = useDebounce(query, 400);
2812
+ const [optionsLoading, setOptionsLoading] = useState(false);
2813
+ const [draftSelected, setDraftSelected] = useState(selected);
2814
+ const [viewportHeight, setViewportHeight] = useState(null);
2815
+ useEffect(() => {
2816
+ if (!isOpen) {
2817
+ setViewportHeight(null);
2818
+ return;
2819
+ }
2820
+ const updateHeight = () => {
2821
+ if (typeof window !== 'undefined' && window.visualViewport) {
2822
+ setViewportHeight(window.visualViewport.height);
2823
+ }
2824
+ };
2825
+ updateHeight();
2826
+ const vv = typeof window !== 'undefined' ? window.visualViewport : null;
2827
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('resize', updateHeight);
2828
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('scroll', updateHeight);
2829
+ return () => {
2830
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('resize', updateHeight);
2831
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('scroll', updateHeight);
2832
+ };
2833
+ }, [isOpen]);
2834
+ const currentSize = sizeConfigMap[size] || sizeConfigMap.md;
2835
+ const hasError = Boolean(error);
2836
+ const isAsyncLoading = loading || optionsLoading;
2837
+ const baseInputClass = useMemo(() => buildInputClass('', { disabled, hasError, size }), [disabled, hasError, size]);
2838
+ const onSearchRef = useRef(onSearch);
2839
+ useEffect(() => {
2840
+ onSearchRef.current = onSearch;
2841
+ }, [onSearch]);
2842
+ const handleAsyncSearch = useCallback(async (searchString) => {
2843
+ var _a;
2844
+ try {
2845
+ setOptionsLoading(true);
2846
+ await ((_a = onSearchRef.current) === null || _a === void 0 ? void 0 : _a.call(onSearchRef, searchString));
2847
+ }
2848
+ catch (err) {
2849
+ console.error('Error loading options:', err);
2850
+ }
2851
+ finally {
2852
+ setOptionsLoading(false);
2853
+ }
2854
+ }, []);
2855
+ useEffect(() => {
2856
+ if (isOpen && async) {
2857
+ handleAsyncSearch(debouncedQuery);
2858
+ }
2859
+ }, [isOpen, async, debouncedQuery, handleAsyncSearch]);
2860
+ const getDisplayValue = useCallback((opt) => {
2861
+ var _a, _b;
2862
+ if (typeof opt === 'string')
2863
+ return opt;
2864
+ return (_b = (_a = opt === null || opt === void 0 ? void 0 : opt[labelKey]) !== null && _a !== void 0 ? _a : opt === null || opt === void 0 ? void 0 : opt[valueKey]) !== null && _b !== void 0 ? _b : String(opt);
2865
+ }, [labelKey, valueKey]);
2866
+ const getValue = useCallback((opt) => {
2867
+ var _a, _b;
2868
+ if (typeof opt === 'string')
2869
+ return opt;
2870
+ return (_b = (_a = opt === null || opt === void 0 ? void 0 : opt[valueKey]) !== null && _a !== void 0 ? _a : opt === null || opt === void 0 ? void 0 : opt[labelKey]) !== null && _b !== void 0 ? _b : String(opt);
2871
+ }, [valueKey, labelKey]);
2872
+ const normalizedSelected = useMemo(() => {
2873
+ if (multiple) {
2874
+ if (Array.isArray(selected))
2875
+ return selected;
2876
+ if (selected !== null && selected !== undefined)
2877
+ return [selected];
2878
+ return [];
2879
+ }
2880
+ else {
2881
+ if (Array.isArray(selected))
2882
+ return selected.length > 0 ? selected[0] : null;
2883
+ return selected !== null && selected !== void 0 ? selected : null;
2884
+ }
2885
+ }, [multiple, selected]);
2886
+ const normalizedDraft = useMemo(() => {
2887
+ if (multiple) {
2888
+ if (Array.isArray(draftSelected))
2889
+ return draftSelected;
2890
+ if (draftSelected !== null && draftSelected !== undefined)
2891
+ return [draftSelected];
2892
+ return [];
2893
+ }
2894
+ else {
2895
+ if (Array.isArray(draftSelected))
2896
+ return draftSelected.length > 0 ? draftSelected[0] : null;
2897
+ return draftSelected !== null && draftSelected !== void 0 ? draftSelected : null;
2898
+ }
2899
+ }, [multiple, draftSelected]);
2900
+ const rawAllOptions = useMemo(() => {
2901
+ if (groups === null || groups === void 0 ? void 0 : groups.length) {
2902
+ return groups.flatMap((g) => g.options);
2903
+ }
2904
+ return options !== null && options !== void 0 ? options : [];
2905
+ }, [groups, options]);
2906
+ const allOptions = useMemo(() => {
2907
+ const list = [...rawAllOptions];
2908
+ const selectedList = Array.isArray(normalizedDraft)
2909
+ ? normalizedDraft
2910
+ : normalizedDraft
2911
+ ? [normalizedDraft]
2912
+ : [];
2913
+ for (const sel of selectedList) {
2914
+ if (sel !== null && sel !== undefined) {
2915
+ const selVal = getValue(sel);
2916
+ const exists = list.some((item) => getValue(item) === selVal);
2917
+ if (!exists) {
2918
+ list.unshift(sel);
2919
+ }
2920
+ }
2921
+ }
2922
+ return list;
2923
+ }, [rawAllOptions, normalizedDraft, getValue]);
2924
+ useEffect(() => {
2925
+ if (isOpen) {
2926
+ setDraftSelected(normalizedSelected);
2927
+ setQuery('');
2928
+ }
2929
+ }, [isOpen, normalizedSelected]);
2930
+ const defaultFilter = useCallback((opt, q) => {
2931
+ var _a;
2932
+ if (!q.trim())
2933
+ return true;
2934
+ const searchTarget = ((_a = getDisplayValue(opt)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
2935
+ return searchTarget.includes(q.trim().toLowerCase());
2936
+ }, [getDisplayValue]);
2937
+ const activeFilter = filterOption || defaultFilter;
2938
+ const filteredOptions = useMemo(() => {
2939
+ if (async)
2940
+ return allOptions;
2941
+ if (!query.trim())
2942
+ return allOptions;
2943
+ return allOptions.filter((opt) => activeFilter(opt, query));
2944
+ }, [allOptions, query, async, activeFilter]);
2945
+ const filteredGroups = useMemo(() => {
2946
+ if (!(groups === null || groups === void 0 ? void 0 : groups.length))
2947
+ return null;
2948
+ if (async)
2949
+ return groups;
2950
+ if (!query.trim())
2951
+ return groups;
2952
+ return groups
2953
+ .map((g) => ({
2954
+ ...g,
2955
+ options: g.options.filter((opt) => activeFilter(opt, query)),
2956
+ }))
2957
+ .filter((g) => g.options.length > 0);
2958
+ }, [groups, query, async, activeFilter]);
2959
+ const createFreeTextOption = useCallback((text) => {
2960
+ const sample = allOptions[0] || (Array.isArray(selected) ? selected[0] : selected);
2961
+ if (typeof sample === 'string' ||
2962
+ (!sample && typeof labelKey === 'string' && labelKey === 'label')) {
2963
+ return text;
2964
+ }
2965
+ return {
2966
+ [labelKey]: text,
2967
+ [valueKey]: text,
2968
+ };
2969
+ }, [allOptions, selected, labelKey, valueKey]);
2970
+ const handleToggleOption = (option) => {
2971
+ const optVal = getValue(option);
2972
+ if (multiple) {
2973
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
2974
+ const index = current.findIndex((item) => getValue(item) === optVal);
2975
+ if (index > -1) {
2976
+ current.splice(index, 1);
2977
+ setDraftSelected(current);
2978
+ }
2979
+ else {
2980
+ if (maxSelection && current.length >= maxSelection)
2981
+ return;
2982
+ current.push(option);
2983
+ setDraftSelected(current);
2984
+ }
2985
+ }
2986
+ else {
2987
+ setDraftSelected(option);
2988
+ onChange(option);
2989
+ setIsOpen(false);
2990
+ }
2991
+ };
2992
+ const handleCommitFreeText = (text) => {
2993
+ const trimmed = text.trim();
2994
+ if (!trimmed)
2995
+ return;
2996
+ const existing = allOptions.find((opt) => getDisplayValue(opt).toLowerCase() === trimmed.toLowerCase());
2997
+ const optionToCommit = existing || createFreeTextOption(trimmed);
2998
+ if (multiple) {
2999
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
3000
+ const already = current.some((item) => getDisplayValue(item).toLowerCase() === trimmed.toLowerCase());
3001
+ if (!already) {
3002
+ if (maxSelection && current.length >= maxSelection)
3003
+ return;
3004
+ current.push(optionToCommit);
3005
+ setDraftSelected(current);
3006
+ }
3007
+ setQuery('');
3008
+ }
3009
+ else {
3010
+ setDraftSelected(optionToCommit);
3011
+ onChange(optionToCommit);
3012
+ setIsOpen(false);
3013
+ }
3014
+ };
3015
+ const handleAddAndSelect = async (valueToAdd) => {
3016
+ try {
3017
+ const result = await onAdd(valueToAdd);
3018
+ const optionToCommit = (result || valueToAdd);
3019
+ if (multiple) {
3020
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
3021
+ current.push(optionToCommit);
3022
+ setDraftSelected(current);
3023
+ setQuery('');
3024
+ }
3025
+ else {
3026
+ setDraftSelected(optionToCommit);
3027
+ onChange(optionToCommit);
3028
+ setIsOpen(false);
3029
+ }
3030
+ }
3031
+ catch (err) {
3032
+ console.error('MobilePicker onAdd error:', err);
3033
+ }
3034
+ };
3035
+ const isAllSelected = useMemo(() => {
3036
+ if (!multiple || !Array.isArray(normalizedDraft) || !allOptions.length)
3037
+ return false;
3038
+ return allOptions.length === normalizedDraft.length;
3039
+ }, [multiple, normalizedDraft, allOptions]);
3040
+ const handleToggleSelectAll = () => {
3041
+ if (isAllSelected) {
3042
+ setDraftSelected([]);
3043
+ }
3044
+ else {
3045
+ setDraftSelected(allOptions);
3046
+ }
3047
+ };
3048
+ const handleConfirmMultiSelect = () => {
3049
+ onChange(normalizedDraft);
3050
+ setIsOpen(false);
3051
+ };
3052
+ const handleClearSingleSelect = (e) => {
3053
+ e.preventDefault();
3054
+ e.stopPropagation();
3055
+ setDraftSelected(multiple ? [] : null);
3056
+ onChange(multiple ? [] : null);
3057
+ };
3058
+ const handleTriggerClick = (e) => {
3059
+ if (disabled)
3060
+ return;
3061
+ const isClearClick = e.target.closest('[data-testid="mobile-picker-clear-button"]');
3062
+ if (isClearClick)
3063
+ return;
3064
+ setIsOpen(true);
3065
+ };
3066
+ const isOptionSelected = (option) => {
3067
+ const optVal = getValue(option);
3068
+ if (multiple) {
3069
+ return (Array.isArray(normalizedDraft) && normalizedDraft.some((item) => getValue(item) === optVal));
3070
+ }
3071
+ else {
3072
+ return Boolean(normalizedDraft && getValue(normalizedDraft) === optVal);
3073
+ }
3074
+ };
3075
+ const shouldShowTypeToSearch = async && !query && !isAsyncLoading && allOptions.length === 0;
3076
+ const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
3077
+ return (jsxs("div", { className: buildClassName('group space-y-2 w-full', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs("button", { type: "button", id: id, name: name, disabled: disabled, onClick: handleTriggerClick, className: buildClassName(baseInputClass, 'w-full flex items-center justify-between gap-2 cursor-pointer relative text-left', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : ''), "data-testid": "mobile-picker-trigger", children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute left-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), jsx("div", { className: "flex-1 flex flex-wrap items-center gap-1.5 min-w-0 overflow-hidden", children: multiple ? (Array.isArray(normalizedSelected) && normalizedSelected.length > 0 ? (normalizedSelected.map((item, idx) => (jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, children: getDisplayValue(item) }, `${getValue(item)}-${idx}`)))) : (jsx("span", { className: "text-gray-400 dark:text-gray-500", children: placeholder }))) : normalizedSelected ? (jsx("span", { className: "text-gray-900 dark:text-white font-normal truncate", children: getDisplayValue(normalizedSelected) })) : (jsx("span", { className: "text-gray-400 dark:text-gray-500", children: placeholder })) }), jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [allowClear && !multiple && normalizedSelected && (jsx("span", { role: "button", "aria-label": "Clear selection", tabIndex: 0, onClick: handleClearSingleSelect, className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full cursor-pointer z-10", "data-testid": "mobile-picker-clear-button", children: jsx(SvgX, { className: "size-3.5 stroke-gray-500 dark:stroke-gray-400" }) })), jsx(SvgChevronDown, { className: buildClassName(currentSize.icon, 'stroke-gray-500 shrink-0') })] })] }), showErrorMessage && error && (jsx("div", { className: "mt-1", children: jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsx("div", { className: "mt-1", children: jsx(TextContent, { muted: true, small: true, children: helperText }) })), jsxs(Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: () => setIsOpen(false), transition: true, children: [jsx(DialogBackdrop, { className: "fixed inset-0 bg-black/50 backdrop-blur-xs transition-opacity duration-200" }), jsx("div", { className: "fixed left-0 top-0 w-full flex items-end justify-center pointer-events-none z-50", style: {
3078
+ height: viewportHeight ? `${viewportHeight}px` : '100dvh',
3079
+ }, children: jsxs(DialogPanel, { transition: true, className: buildClassName('w-full max-w-full md:max-w-lg bg-white dark:bg-gray-900 shadow-2xl rounded-t-3xl max-h-[85vh] max-h-[85dvh] flex flex-col pointer-events-auto overscroll-contain touch-pan-y', 'duration-200 ease-out data-[closed]:translate-y-full data-[closed]:opacity-0', sheetClass), style: {
3080
+ maxHeight: viewportHeight ? `${Math.floor(viewportHeight * 0.9)}px` : undefined,
3081
+ }, "data-testid": "mobile-picker-sheet", children: [jsx("div", { className: "w-12 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700 mx-auto my-2.5 shrink-0" }), jsxs("div", { className: "px-4 pb-3 border-b border-[var(--ui-border-muted)] flex items-center justify-between gap-3 shrink-0", children: [jsxs("div", { className: "min-w-0 flex-1", children: [jsx(DialogTitle, { as: "h3", className: "text-base md:text-lg font-bold text-gray-900 dark:text-white truncate", children: title || label || 'Select Option' }), description && (jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 truncate mt-0.5", children: description }))] }), jsx(Button, { iconOnly: true, "aria-label": "Close picker", variant: "plain", theme: "secondary", size: "xs", onClick: () => setIsOpen(false), className: "rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 shrink-0", children: jsx(SvgX, { className: "size-4" }) })] }), searchable && (jsx("div", { className: "p-3 border-b border-[var(--ui-border-muted)] bg-gray-50 dark:bg-gray-800/50 shrink-0", children: jsxs("div", { className: "relative", children: [jsx(SvgSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-gray-400" }), jsx("input", { type: "text", value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: (e) => {
3082
+ if (allowFreeText && e.key === 'Enter' && query.trim()) {
3083
+ e.preventDefault();
3084
+ handleCommitFreeText(query);
3085
+ }
3086
+ }, placeholder: searchPlaceholder, className: "w-full pl-9 pr-10 py-2 text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-xl text-gray-900 dark:text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500", "data-testid": "mobile-picker-search-input" }), jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1.5", children: isAsyncLoading ? (jsx(Loader, { size: "xs" })) : (query && (jsx("button", { type: "button", onClick: () => setQuery(''), className: "p-0.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200", children: jsx(SvgX, { className: "size-3.5" }) }))) })] }) })), quickOptions && quickOptions.length > 0 && (jsxs("div", { className: "px-3 py-2 bg-gray-50/60 dark:bg-gray-800/40 border-b border-[var(--ui-border-muted)] shrink-0", children: [jsx("div", { className: "text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-1.5 px-1", children: quickOptionsTitle }), jsx("div", { className: "flex items-center gap-2 overflow-x-auto no-scrollbar pb-1", children: quickOptions.map((chip, cIdx) => {
3087
+ const isSelected = isOptionSelected(chip);
3088
+ return (jsx("button", { type: "button", onClick: () => handleToggleOption(chip), className: buildClassName('px-3 py-1 rounded-full text-xs font-medium shrink-0 transition-colors cursor-pointer border', isSelected
3089
+ ? 'bg-blue-600 text-white border-blue-600'
3090
+ : 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-700'), children: getDisplayValue(chip) }, cIdx));
3091
+ }) })] })), multiple && showSelectAll && allOptions.length > 0 && (jsxs("div", { className: "px-4 py-2 bg-gray-50/80 dark:bg-gray-800/80 border-b border-[var(--ui-border-muted)] flex items-center justify-between text-xs shrink-0", children: [jsx("button", { type: "button", onClick: handleToggleSelectAll, className: "font-semibold text-blue-600 dark:text-blue-400 hover:underline cursor-pointer", children: isAllSelected ? 'Deselect All' : 'Select All' }), jsxs("span", { className: "text-gray-500 dark:text-gray-400 font-medium", children: [Array.isArray(normalizedDraft) ? normalizedDraft.length : 0, " of", ' ', allOptions.length] })] })), jsxs("div", { onScroll: (e) => {
3092
+ const el = e.currentTarget;
3093
+ if (el.scrollTop === 0) {
3094
+ el.scrollTop = 1;
3095
+ }
3096
+ else if (el.scrollTop + el.clientHeight >= el.scrollHeight) {
3097
+ el.scrollTop = el.scrollHeight - el.clientHeight - 1;
3098
+ }
3099
+ }, className: "flex-1 overflow-y-auto overscroll-contain touch-pan-y [-webkit-overflow-scrolling:touch] p-2 space-y-1 divide-y divide-gray-100 dark:divide-gray-800/60", children: [allowFreeText &&
3100
+ query.trim() &&
3101
+ !allOptions.some((opt) => getDisplayValue(opt).toLowerCase() === query.trim().toLowerCase()) && (jsxs("button", { type: "button", onClick: () => handleCommitFreeText(query), className: "w-full text-left flex items-center justify-between p-3.5 rounded-2xl bg-blue-50/80 dark:bg-blue-950/30 text-blue-600 dark:text-blue-400 font-medium hover:bg-blue-100/80 cursor-pointer", "data-testid": "mobile-picker-freetext-item", children: [jsxs("span", { className: "text-sm font-medium", children: ["Use \"", query.trim(), "\""] }), jsx(SvgChevronDown, { className: "size-4 rotate-[-90deg]" })] })), isAsyncLoading && allOptions.length === 0 ? (jsxs("div", { className: "py-12 flex flex-col items-center justify-center gap-2 text-sm text-gray-500 dark:text-gray-400 select-none", children: [jsx(Loader, { size: "md" }), jsx("span", { children: "Loading options..." })] })) : shouldShowTypeToSearch ? (jsx("div", { className: "py-12 text-center text-sm text-gray-500 dark:text-gray-400 select-none", children: typeToSearchText })) : filteredGroups ? (filteredGroups.map((grp, gIdx) => (jsxs("div", { className: "pt-2", children: [jsx("div", { className: "text-[11px] font-bold uppercase tracking-wider text-gray-400 dark:text-gray-500 px-3 py-1.5 select-none", children: grp.group }), jsx("div", { className: "space-y-1", children: grp.options.map((option) => {
3102
+ const optVal = getValue(option);
3103
+ const isSelected = isOptionSelected(option);
3104
+ const optDisabled = option.disabled;
3105
+ const optDesc = typeof option === 'object'
3106
+ ? (option === null || option === void 0 ? void 0 : option.description) || (option === null || option === void 0 ? void 0 : option.subtitle)
3107
+ : null;
3108
+ return (jsxs("div", { onClick: () => !optDisabled && handleToggleOption(option), className: buildClassName('w-full flex items-center justify-between p-3.5 rounded-2xl transition-colors cursor-pointer select-none', isSelected
3109
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3110
+ : 'text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800/70', optDisabled && 'opacity-50 pointer-events-none'), children: [jsxs("div", { className: "flex-1 min-w-0 pr-3", children: [jsx("div", { className: "text-sm/6 truncate", children: renderOption
3111
+ ? renderOption(option, isSelected)
3112
+ : getDisplayValue(option) }), optDesc && (jsx("div", { className: "text-xs text-gray-400 font-normal truncate mt-0.5", children: optDesc }))] }), isSelected && (jsx(SvgCheck, { className: "size-5 stroke-blue-600 dark:stroke-blue-400 shrink-0" }))] }, optVal));
3113
+ }) })] }, gIdx)))) : filteredOptions.length > 0 ? (filteredOptions.map((option) => {
3114
+ const optVal = getValue(option);
3115
+ const isSelected = isOptionSelected(option);
3116
+ const optDisabled = option.disabled;
3117
+ const optDesc = typeof option === 'object' ? (option === null || option === void 0 ? void 0 : option.description) || (option === null || option === void 0 ? void 0 : option.subtitle) : null;
3118
+ return (jsxs("div", { onClick: () => !optDisabled && handleToggleOption(option), className: buildClassName('w-full flex items-center justify-between p-3.5 rounded-2xl transition-colors cursor-pointer select-none', isSelected
3119
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3120
+ : 'text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800/70', optDisabled && 'opacity-50 pointer-events-none'), children: [jsxs("div", { className: "flex-1 min-w-0 pr-3", children: [jsx("div", { className: "text-sm/6 truncate", children: renderOption
3121
+ ? renderOption(option, isSelected)
3122
+ : getDisplayValue(option) }), optDesc && (jsx("div", { className: "text-xs text-gray-400 font-normal truncate mt-0.5", children: optDesc }))] }), isSelected && (jsx(SvgCheck, { className: "size-5 stroke-blue-600 dark:stroke-blue-400 shrink-0" }))] }, optVal));
3123
+ })) : (!allowFreeText &&
3124
+ !(allowAdd && query.trim()) && (jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400 select-none", children: query
3125
+ ? noOptionsText !== 'No options available'
3126
+ ? noOptionsText
3127
+ : `No results found for "${query}"`
3128
+ : noOptionsText }))), !allowFreeText && allowAdd && Boolean(query.trim()) && (jsxs("button", { type: "button", onClick: () => handleAddAndSelect(query.trim()), className: "w-full flex items-center gap-2.5 p-3.5 rounded-2xl text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer", children: [jsx(SvgCirclePlus, { className: "size-5 text-blue-600 dark:text-blue-400" }), jsxs("span", { className: "text-sm font-medium", children: [addNewText, " \"", query.trim(), "\""] })] }))] }), multiple && (jsx("div", { className: "p-4 border-t border-[var(--ui-border-muted)] bg-white dark:bg-gray-900 shrink-0", children: jsxs(Button, { fullWidth: true, theme: "primary", size: "md", onClick: handleConfirmMultiSelect, "data-testid": "mobile-picker-confirm-button", children: [confirmText, ' ', Array.isArray(normalizedDraft) && normalizedDraft.length > 0
3129
+ ? `(${normalizedDraft.length})`
3130
+ : ''] }) }))] }) })] })] }));
3131
+ }
3132
+ MobilePicker.displayName = 'MobilePicker';
3133
+
3134
+ function SingleWheelColumn({ column, itemHeight, height, disabled, onValueChange, }) {
3135
+ var _a;
3136
+ const containerRef = useRef(null);
3137
+ const [selectedValue, setSelectedValue] = useState(column.value !== undefined
3138
+ ? column.value
3139
+ : column.defaultValue !== undefined
3140
+ ? column.defaultValue
3141
+ : (_a = column.options[0]) === null || _a === void 0 ? void 0 : _a.value);
3142
+ const isControlled = column.value !== undefined;
3143
+ const currentValue = isControlled ? column.value : selectedValue;
3144
+ const selectedIndex = Math.max(0, column.options.findIndex((opt) => opt.value === currentValue));
3145
+ const paddingY = (height - itemHeight) / 2;
3146
+ // Sync scroll position when active value changes externally
3147
+ useEffect(() => {
3148
+ if (containerRef.current) {
3149
+ const targetScrollTop = selectedIndex * itemHeight;
3150
+ if (Math.abs(containerRef.current.scrollTop - targetScrollTop) > 2) {
3151
+ containerRef.current.scrollTop = targetScrollTop;
3152
+ }
3153
+ }
3154
+ }, [selectedIndex, itemHeight]);
3155
+ const handleScroll = () => {
3156
+ var _a;
3157
+ if (!containerRef.current || disabled)
3158
+ return;
3159
+ const scrollTop = containerRef.current.scrollTop;
3160
+ const index = Math.round(scrollTop / itemHeight);
3161
+ const targetOption = column.options[index];
3162
+ if (targetOption && targetOption.value !== currentValue && !targetOption.disabled) {
3163
+ if (!isControlled) {
3164
+ setSelectedValue(targetOption.value);
3165
+ }
3166
+ (_a = column.onChange) === null || _a === void 0 ? void 0 : _a.call(column, targetOption.value);
3167
+ onValueChange(targetOption.value);
3168
+ }
3169
+ };
3170
+ return (jsx("div", { ref: containerRef, onScroll: handleScroll, className: buildClassName('flex-1 h-full overflow-y-auto no-scrollbar snap-y snap-mandatory relative z-10 select-none text-center', disabled && 'pointer-events-none opacity-40'), style: {
3171
+ paddingTop: `${paddingY}px`,
3172
+ paddingBottom: `${paddingY}px`,
3173
+ scrollSnapType: 'y mandatory',
3174
+ }, "data-testid": `wheel-column-${column.id}`, children: column.options.map((opt, index) => {
3175
+ const isSelected = opt.value === currentValue;
3176
+ return (jsx("div", { onClick: () => {
3177
+ if (disabled || opt.disabled || !containerRef.current)
3178
+ return;
3179
+ const targetTop = index * itemHeight;
3180
+ if (typeof containerRef.current.scrollTo === 'function') {
3181
+ containerRef.current.scrollTo({
3182
+ top: targetTop,
3183
+ behavior: 'smooth',
3184
+ });
3185
+ }
3186
+ else {
3187
+ containerRef.current.scrollTop = targetTop;
3188
+ }
3189
+ }, className: buildClassName('flex items-center justify-center font-semibold snap-center transition-all duration-150 cursor-pointer', opt.disabled && 'opacity-30 cursor-not-allowed', isSelected
3190
+ ? 'text-blue-600 dark:text-blue-400 text-sm font-bold scale-105'
3191
+ : 'text-gray-500 dark:text-gray-400 text-xs hover:text-gray-800 dark:hover:text-gray-200'), style: { height: `${itemHeight}px` }, "data-testid": `wheel-item-${column.id}-${opt.value}`, children: opt.label }, `${opt.value}-${index}`));
3192
+ }) }));
3193
+ }
3194
+ function WheelPicker({ columns, height = 200, itemHeight = 40, onChange, disabled = false, containerClass = '', }) {
3195
+ const valuesRef = useRef({});
3196
+ const handleColumnChange = (columnId, value) => {
3197
+ valuesRef.current[columnId] = value;
3198
+ onChange === null || onChange === void 0 ? void 0 : onChange({ ...valuesRef.current });
3199
+ };
3200
+ const highlightTop = (height - itemHeight) / 2;
3201
+ return (jsxs("div", { className: buildClassName('w-full bg-white dark:bg-gray-900 border border-[var(--ui-border)] rounded-2xl relative overflow-hidden flex items-center shadow-xs select-none', containerClass), style: { height: `${height}px` }, "data-testid": "wheel-picker", children: [jsx("div", { className: "absolute inset-x-2 rounded-xl bg-gray-100/90 dark:bg-gray-800/90 border border-blue-500/20 dark:border-blue-400/20 z-0 pointer-events-none", style: {
3202
+ height: `${itemHeight}px`,
3203
+ top: `${highlightTop}px`,
3204
+ }, "data-testid": "wheel-highlight-window" }), jsx("div", { className: "absolute top-0 inset-x-0 bg-gradient-to-b from-white via-white/80 dark:from-gray-900 dark:via-gray-900/80 to-transparent pointer-events-none z-20", style: { height: `${highlightTop}px` } }), jsx("div", { className: "absolute bottom-0 inset-x-0 bg-gradient-to-t from-white via-white/80 dark:from-gray-900 dark:via-gray-900/80 to-transparent pointer-events-none z-20", style: { height: `${highlightTop}px` } }), jsx("div", { className: "w-full h-full flex items-center justify-around relative z-10 px-2", children: columns.map((col) => (jsx(SingleWheelColumn, { column: col, itemHeight: itemHeight, height: height, disabled: disabled, onValueChange: (val) => handleColumnChange(col.id, val) }, col.id))) })] }));
3205
+ }
3206
+ WheelPicker.displayName = 'WheelPicker';
3207
+
3208
+ function ChevronLeftIcon$1() {
3209
+ return (jsx("svg", { className: "size-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M15 19l-7-7 7-7" }) }));
3210
+ }
3211
+ function SearchIcon$1() {
3212
+ return (jsx("svg", { className: "size-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }));
3213
+ }
3214
+ function ClearIcon() {
3215
+ return (jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }));
3216
+ }
3217
+ function MobileHeader({ title, subtitle, titleAlign = 'center', onBack, backLabel = 'Back', leading, actions, searchable = false, searchValue: externalSearchValue, onSearchChange, searchPlaceholder = 'Search...', sticky = true, transparent = false, bottomSlot, className = '', }) {
3218
+ const [isSearchActive, setIsSearchActive] = useState(false);
3219
+ const [internalSearchValue, setInternalSearchValue] = useState('');
3220
+ const searchValue = externalSearchValue !== undefined ? externalSearchValue : internalSearchValue;
3221
+ const handleSearchInput = (e) => {
3222
+ const val = e.target.value;
3223
+ setInternalSearchValue(val);
3224
+ onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(val);
3225
+ };
3226
+ const handleClearSearch = () => {
3227
+ setInternalSearchValue('');
3228
+ onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange('');
3229
+ };
3230
+ return (jsxs("header", { className: buildClassName('w-full transition-colors select-none z-30', sticky && 'sticky top-0', transparent
3231
+ ? 'bg-white/80 dark:bg-gray-900/80 backdrop-blur-md border-b border-[var(--ui-border-muted)]'
3232
+ : 'bg-white dark:bg-gray-900 border-b border-[var(--ui-border)] shadow-xs', 'pt-[env(safe-area-inset-top,0px)]', className), "data-testid": "mobile-header", children: [jsx("div", { className: "h-14 px-3.5 flex items-center justify-between gap-3 relative", children: searchable && isSearchActive ? (jsxs("div", { className: "flex-1 flex items-center gap-2", "data-testid": "mobile-header-search-container", children: [jsxs("div", { className: "relative flex-1 flex items-center", children: [jsx("span", { className: "absolute left-3 pointer-events-none", children: jsx(SearchIcon$1, {}) }), jsx("input", { type: "text", value: searchValue, onChange: handleSearchInput, placeholder: searchPlaceholder, autoFocus: true, className: "w-full pl-9 pr-8 py-1.5 text-xs bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white rounded-full border border-transparent focus:border-blue-500 focus:outline-hidden transition-all", "data-testid": "mobile-header-search-input" }), searchValue && (jsx("button", { type: "button", onClick: handleClearSearch, "aria-label": "Clear search", className: "absolute right-2.5 p-0.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 cursor-pointer", children: jsx(ClearIcon, {}) }))] }), jsx("button", { type: "button", onClick: () => setIsSearchActive(false), className: "text-xs font-semibold text-blue-600 dark:text-blue-400 px-2 py-1.5 rounded-lg hover:bg-blue-50 dark:hover:bg-blue-950/40 cursor-pointer", children: "Cancel" })] })) : (jsxs(Fragment, { children: [jsx("div", { className: "flex items-center gap-1 min-w-[40px] shrink-0 z-10", children: onBack ? (jsxs("button", { type: "button", onClick: onBack, "aria-label": backLabel, className: "flex items-center gap-0.5 text-blue-600 dark:text-blue-400 hover:text-blue-700 p-1 -ml-1 rounded-xl transition-colors cursor-pointer", "data-testid": "mobile-header-back-btn", children: [jsx(ChevronLeftIcon$1, {}), jsx("span", { className: "text-xs font-semibold hidden sm:inline", children: backLabel })] })) : (leading) }), jsxs("div", { className: buildClassName('flex-1 min-w-0 px-2', titleAlign === 'center'
3233
+ ? 'absolute inset-x-12 text-center pointer-events-none flex flex-col items-center justify-center'
3234
+ : 'text-left'), children: [title && (jsx("div", { className: "text-sm font-bold text-gray-900 dark:text-white truncate pointer-events-auto", "data-testid": "mobile-header-title", children: title })), subtitle && (jsx("div", { className: "text-[11px] text-gray-500 dark:text-gray-400 truncate pointer-events-auto", "data-testid": "mobile-header-subtitle", children: subtitle }))] }), jsxs("div", { className: "flex items-center gap-1 min-w-[40px] shrink-0 justify-end z-10", children: [searchable && (jsx("button", { type: "button", onClick: () => setIsSearchActive(true), "aria-label": "Search", className: "p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-xl transition-colors cursor-pointer", "data-testid": "mobile-header-search-toggle", children: jsx(SearchIcon$1, {}) })), actions === null || actions === void 0 ? void 0 : actions.map((action) => {
3235
+ const badgeColor = {
3236
+ danger: 'bg-red-500 text-white',
3237
+ info: 'bg-blue-500 text-white',
3238
+ success: 'bg-emerald-500 text-white',
3239
+ }[action.badgeVariant || 'danger'];
3240
+ return (jsxs("button", { type: "button", disabled: action.disabled, onClick: action.onClick, "aria-label": action.label, className: buildClassName('p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-xl transition-colors relative cursor-pointer', action.disabled && 'opacity-40 cursor-not-allowed pointer-events-none'), "data-testid": `mobile-header-action-${action.id}`, children: [jsx("span", { className: "text-base", children: action.icon }), action.badge !== undefined && action.badge !== null && (jsx("span", { className: buildClassName('absolute top-1 right-1 min-w-[14px] h-3.5 px-0.5 rounded-full text-[9px] font-bold flex items-center justify-center shadow-xs', badgeColor), "data-testid": `mobile-header-badge-${action.id}`, children: action.badge }))] }, action.id));
3241
+ })] })] })) }), bottomSlot && (jsx("div", { className: "px-3 py-2 border-t border-[var(--ui-border-muted)]", "data-testid": "mobile-header-bottom-slot", children: bottomSlot }))] }));
3242
+ }
3243
+ MobileHeader.displayName = 'MobileHeader';
3244
+
3245
+ function ChevronLeftIcon() {
3246
+ return (jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M15 19l-7-7 7-7" }) }));
3247
+ }
3248
+ function ChevronRightIcon() {
3249
+ return (jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M9 5l7 7-7 7" }) }));
3250
+ }
3251
+ function MobileStepper({ steps, activeStep, variant = 'dots', onBack, onNext, backLabel = 'Back', nextLabel = 'Next', stepTitle, nextDisabled = false, backDisabled = false, nextLoading = false, className = '', }) {
3252
+ const isFirstStep = activeStep <= 0;
3253
+ const isLastStep = activeStep >= steps - 1;
3254
+ const progressPercent = Math.min(Math.max(((activeStep + 1) / steps) * 100, 0), 100);
3255
+ return (jsxs("div", { className: buildClassName('w-full flex flex-col gap-2 p-3 bg-white dark:bg-gray-900 border border-[var(--ui-border)] rounded-2xl shadow-xs select-none', className), "data-testid": "mobile-stepper", children: [stepTitle && (jsxs("div", { className: "flex items-center justify-between px-1", children: [jsx("span", { className: "text-xs font-bold text-gray-900 dark:text-white truncate", "data-testid": "mobile-stepper-title", children: stepTitle }), jsxs("span", { className: "text-[11px] font-medium text-gray-500 dark:text-gray-400 shrink-0 ml-2", children: [activeStep + 1, " / ", steps] })] })), jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsx(Button, { size: "xs", variant: "plain", theme: "secondary", disabled: disabledBack(isFirstStep, backDisabled), onClick: onBack, "aria-label": "Previous step", leftIcon: jsx(ChevronLeftIcon, {}), "data-testid": "mobile-stepper-back-btn", children: backLabel }), jsxs("div", { className: "flex items-center justify-center flex-1", "data-testid": "mobile-stepper-indicator", children: [variant === 'dots' && (jsx("div", { className: "flex items-center gap-1.5", "data-testid": "mobile-stepper-dots", children: Array.from({ length: steps }).map((_, index) => {
3256
+ const isActive = index === activeStep;
3257
+ const isCompleted = index < activeStep;
3258
+ return (jsx("span", { className: buildClassName('h-2 transition-all duration-300 rounded-full', isActive
3259
+ ? 'w-5 bg-blue-600 dark:bg-blue-400'
3260
+ : isCompleted
3261
+ ? 'w-2 bg-blue-300 dark:bg-blue-800'
3262
+ : 'w-2 bg-gray-200 dark:bg-gray-700'), "data-testid": `mobile-stepper-dot-${index}` }, index));
3263
+ }) })), variant === 'progress' && (jsx("div", { className: "w-full max-w-[140px] bg-gray-200 dark:bg-gray-700 h-2 rounded-full overflow-hidden", "data-testid": "mobile-stepper-progress", children: jsx("div", { className: "bg-blue-600 dark:bg-blue-400 h-full transition-all duration-300 rounded-full", style: { width: `${progressPercent}%` } }) })), variant === 'text' && (jsxs("div", { className: "text-xs font-semibold text-gray-600 dark:text-gray-300", "data-testid": "mobile-stepper-text", children: ["Step ", activeStep + 1, " of ", steps] }))] }), jsx(Button, { size: "xs", variant: "default", theme: "primary", disabled: nextDisabled, loading: nextLoading, onClick: onNext, "aria-label": "Next step", rightIcon: !isLastStep ? jsx(ChevronRightIcon, {}) : undefined, "data-testid": "mobile-stepper-next-btn", children: nextLabel })] })] }));
3264
+ }
3265
+ function disabledBack(isFirstStep, backDisabled) {
3266
+ return isFirstStep || backDisabled;
3267
+ }
3268
+ MobileStepper.displayName = 'MobileStepper';
3269
+
3270
+ const themeClasses = {
3271
+ danger: 'bg-red-600 text-white hover:bg-red-700 active:bg-red-800',
3272
+ primary: 'bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800',
3273
+ success: 'bg-emerald-600 text-white hover:bg-emerald-700 active:bg-emerald-800',
3274
+ warning: 'bg-amber-500 text-white hover:bg-amber-600 active:bg-amber-700',
3275
+ info: 'bg-cyan-600 text-white hover:bg-cyan-700 active:bg-cyan-800',
3276
+ secondary: 'bg-gray-600 text-white hover:bg-gray-700 active:bg-gray-800',
3277
+ gray: 'bg-gray-500 text-white hover:bg-gray-600 active:bg-gray-700',
3278
+ };
3279
+ const SwipeableRow = ({ children, leftActions = [], rightActions = [], actionWidth = 76, threshold = 40, fullSwipeToExecute = false, fullSwipeThreshold = 180, disabled = false, className = '', contentClassName = '', onOpen, onClose, }) => {
3280
+ const [offset, setOffset] = useState(0);
3281
+ const [isDragging, setIsDragging] = useState(false);
3282
+ const containerRef = useRef(null);
3283
+ const startXRef = useRef(0);
3284
+ const startYRef = useRef(0);
3285
+ const initialOffsetRef = useRef(0);
3286
+ const isHorizontalSwipeRef = useRef(null);
3287
+ const maxLeftWidth = useMemo(() => leftActions.length * actionWidth, [leftActions, actionWidth]);
3288
+ const maxRightWidth = useMemo(() => rightActions.length * actionWidth, [rightActions, actionWidth]);
3289
+ const handleClose = useCallback(() => {
3290
+ setOffset(0);
3291
+ onClose === null || onClose === void 0 ? void 0 : onClose();
3292
+ }, [onClose]);
3293
+ const handleOpenLeft = useCallback(() => {
3294
+ if (maxLeftWidth > 0) {
3295
+ setOffset(maxLeftWidth);
3296
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen('left');
3297
+ }
3298
+ else {
3299
+ handleClose();
3300
+ }
3301
+ }, [maxLeftWidth, onOpen, handleClose]);
3302
+ const handleOpenRight = useCallback(() => {
3303
+ if (maxRightWidth > 0) {
3304
+ setOffset(-maxRightWidth);
3305
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen('right');
3306
+ }
3307
+ else {
3308
+ handleClose();
3309
+ }
3310
+ }, [maxRightWidth, onOpen, handleClose]);
3311
+ const handleDragStart = (clientX, clientY) => {
3312
+ if (disabled)
1968
3313
  return;
1969
- const rect = trackRef.current.getBoundingClientRect();
1970
- const x = Math.min(Math.max(e.clientX - rect.left, 0), rect.width);
1971
- const rawVal = min + (x / rect.width) * (max - min);
1972
- const snappedVal = snapToStep(rawVal);
1973
- const pxMin = (percent(valueMin) / 100) * rect.width;
1974
- const pxMax = (percent(valueMax) / 100) * rect.width;
1975
- if (x <= pxMin) {
1976
- onChange(Math.min(snappedVal, valueMax - step), valueMax);
3314
+ setIsDragging(true);
3315
+ startXRef.current = clientX;
3316
+ startYRef.current = clientY;
3317
+ initialOffsetRef.current = offset;
3318
+ isHorizontalSwipeRef.current = null;
3319
+ };
3320
+ const handleDragMove = (clientX, clientY) => {
3321
+ if (!isDragging || disabled)
1977
3322
  return;
3323
+ const deltaX = clientX - startXRef.current;
3324
+ const deltaY = clientY - startYRef.current;
3325
+ // Lock direction once initial movement surpasses 5px
3326
+ if (isHorizontalSwipeRef.current === null) {
3327
+ if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
3328
+ isHorizontalSwipeRef.current = Math.abs(deltaX) > Math.abs(deltaY);
3329
+ }
1978
3330
  }
1979
- if (x >= pxMax) {
1980
- onChange(valueMin, Math.max(snappedVal, valueMin + step));
3331
+ if (isHorizontalSwipeRef.current === false) {
1981
3332
  return;
1982
3333
  }
1983
- const distMin = Math.abs(snappedVal - valueMin);
1984
- const distMax = Math.abs(snappedVal - valueMax);
1985
- if (distMin < distMax) {
1986
- onChange(Math.min(snappedVal, valueMax - step), valueMax);
3334
+ let nextOffset = initialOffsetRef.current + deltaX;
3335
+ // Limit drag range with resistance overscroll
3336
+ if (nextOffset > 0) {
3337
+ if (!leftActions.length) {
3338
+ nextOffset = 0;
3339
+ }
3340
+ else if (nextOffset > maxLeftWidth && !fullSwipeToExecute) {
3341
+ const overflow = nextOffset - maxLeftWidth;
3342
+ nextOffset = maxLeftWidth + overflow * 0.2;
3343
+ }
1987
3344
  }
1988
- else {
1989
- onChange(valueMin, Math.max(snappedVal, valueMin + step));
3345
+ else if (nextOffset < 0) {
3346
+ if (!rightActions.length) {
3347
+ nextOffset = 0;
3348
+ }
3349
+ else if (Math.abs(nextOffset) > maxRightWidth && !fullSwipeToExecute) {
3350
+ const overflow = Math.abs(nextOffset) - maxRightWidth;
3351
+ nextOffset = -(maxRightWidth + overflow * 0.2);
3352
+ }
1990
3353
  }
3354
+ setOffset(nextOffset);
1991
3355
  };
1992
- // Keyboard accessibility handler for thumbs
1993
- const handleKeyDown = (thumb) => (e) => {
1994
- let delta = 0;
1995
- if (e.key === 'ArrowLeft' || e.key === 'ArrowDown')
1996
- delta = -step;
1997
- else if (e.key === 'ArrowRight' || e.key === 'ArrowUp')
1998
- delta = step;
1999
- else if (e.key === 'Home') {
2000
- if (thumb === 'min')
2001
- onChange(min, valueMax);
2002
- else
2003
- onChange(valueMin, valueMin + step);
3356
+ const handleDragEnd = () => {
3357
+ if (!isDragging)
2004
3358
  return;
2005
- }
2006
- else if (e.key === 'End') {
2007
- if (thumb === 'min')
2008
- onChange(valueMax - step, valueMax);
2009
- else
2010
- onChange(valueMin, max);
3359
+ setIsDragging(false);
3360
+ if (isHorizontalSwipeRef.current === false) {
2011
3361
  return;
2012
3362
  }
2013
- if (delta !== 0) {
2014
- e.preventDefault();
2015
- if (thumb === 'min') {
2016
- const next = snapToStep(valueMin + delta);
2017
- onChange(Math.min(next, valueMax - step), valueMax);
3363
+ // Check full swipe auto-execution
3364
+ if (fullSwipeToExecute) {
3365
+ if (offset > fullSwipeThreshold && leftActions.length > 0) {
3366
+ leftActions[0].onClick();
3367
+ handleClose();
3368
+ return;
3369
+ }
3370
+ if (offset < -fullSwipeThreshold && rightActions.length > 0) {
3371
+ rightActions[0].onClick();
3372
+ handleClose();
3373
+ return;
3374
+ }
3375
+ }
3376
+ // Snap logic
3377
+ if (offset > 0) {
3378
+ if (offset > threshold) {
3379
+ handleOpenLeft();
2018
3380
  }
2019
3381
  else {
2020
- const next = snapToStep(valueMax + delta);
2021
- onChange(valueMin, Math.max(next, valueMin + step));
3382
+ handleClose();
3383
+ }
3384
+ }
3385
+ else if (offset < 0) {
3386
+ if (Math.abs(offset) > threshold) {
3387
+ handleOpenRight();
3388
+ }
3389
+ else {
3390
+ handleClose();
2022
3391
  }
2023
3392
  }
2024
3393
  };
2025
- const markEntries = marks
2026
- ? Object.entries(marks).map(([k, v]) => ({ value: Number(k), label: v }))
2027
- : null;
2028
- return (jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), children: [label && (jsxs("div", { className: "flex items-center justify-between mb-1", children: [jsx(Label, { className: labelClass, children: label }), labelHint] })), jsxs("div", { ref: trackRef, onMouseDown: handleTrackClick, className: "relative h-8 select-none w-full flex items-center cursor-pointer", "data-testid": "range-track", children: [jsx("div", { className: buildClassName('absolute top-1/2 left-0 right-0 rounded-full bg-gray-200 dark:bg-gray-700 -translate-y-1/2', currentSize.track) }), jsx("div", { className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full transition-all duration-150 ease-out', hasError ? 'bg-red-500' : 'bg-blue-600 dark:bg-blue-500', currentSize.track), style: {
2029
- left: `${percent(valueMin)}%`,
2030
- width: `${percent(valueMax) - percent(valueMin)}%`,
2031
- } }), jsx("div", { role: "slider", tabIndex: 0, "aria-label": "Minimum value", "aria-valuenow": valueMin, "aria-valuemin": min, "aria-valuemax": valueMax - step, onPointerDown: startDrag('min'), onMouseEnter: () => setHoveringThumb('min'), onMouseLeave: () => setHoveringThumb(null), onKeyDown: handleKeyDown('min'), className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full focus:outline-none', 'bg-white border-2 shadow-md cursor-pointer touch-none', hasError ? 'border-red-600' : 'border-blue-600', 'transition-all duration-150 ease-out', currentSize.thumb, (activeThumbState === 'min' || hoveringThumb === 'min') &&
2032
- (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2033
- left: `calc(${percent(valueMin)}% - ${currentSize.thumbPx / 2}px)`,
2034
- zIndex: activeThumbState === 'min' ? 50 : 30,
2035
- }, "data-testid": "thumb-min", children: showTooltips && (activeThumbState === 'min' || hoveringThumb === 'min') && (jsxs("div", { className: "absolute -top-7 left-1/2 -translate-x-1/2 px-2 py-0.5 rounded bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-[11px] font-semibold shadow-md pointer-events-none z-50 whitespace-nowrap", children: [Math.round(valueMin), valueSuffix, jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-100" })] })) }), jsx("div", { role: "slider", tabIndex: 0, "aria-label": "Maximum value", "aria-valuenow": valueMax, "aria-valuemin": valueMin + step, "aria-valuemax": max, onPointerDown: startDrag('max'), onMouseEnter: () => setHoveringThumb('max'), onMouseLeave: () => setHoveringThumb(null), onKeyDown: handleKeyDown('max'), className: buildClassName('absolute top-1/2 -translate-y-1/2 rounded-full focus:outline-none', 'bg-white border-2 shadow-md cursor-pointer touch-none', hasError ? 'border-red-600' : 'border-blue-600', 'transition-all duration-150 ease-out', currentSize.thumb, (activeThumbState === 'max' || hoveringThumb === 'max') &&
2036
- (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2037
- left: `calc(${percent(valueMax)}% - ${currentSize.thumbPx / 2}px)`,
2038
- zIndex: activeThumbState === 'max' ? 50 : 40,
2039
- }, "data-testid": "thumb-max", children: showTooltips && (activeThumbState === 'max' || hoveringThumb === 'max') && (jsxs("div", { className: "absolute -top-7 left-1/2 -translate-x-1/2 px-2 py-0.5 rounded bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-[11px] font-semibold shadow-md pointer-events-none z-50 whitespace-nowrap", children: [Math.round(valueMax), valueSuffix, jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-100" })] })) })] }), markEntries && (jsx("div", { className: "relative w-full h-4 mt-1", children: markEntries.map((m) => {
2040
- const markPercent = percent(m.value);
2041
- return (jsxs("div", { className: "absolute top-0 transform -translate-x-1/2 flex flex-col items-center", style: { left: `${markPercent}%` }, children: [jsx("span", { className: "w-1 h-1.5 bg-gray-300 dark:bg-gray-600 rounded-full" }), jsx("span", { className: "text-[10px] font-medium text-gray-400 dark:text-gray-500 mt-0.5", children: m.label })] }, m.value));
2042
- }) })), jsxs("div", { className: buildClassName('flex justify-between font-medium text-gray-700 dark:text-gray-300', currentSize.text), children: [jsxs("span", { children: [Math.round(valueMin), valueSuffix] }), jsxs("span", { children: [Math.round(valueMax), valueSuffix] })] }), (showErrorMessage && hasError) || helperText ? (jsx("div", { className: "mt-1", children: showErrorMessage && hasError ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null })) : null] }));
2043
- };
2044
- RangeSlider.displayName = 'RangeSlider';
2045
-
2046
- const useDebounce = (value, delay) => {
2047
- const [debouncedValue, setDebouncedValue] = useState(value);
3394
+ // Touch Handlers
3395
+ const handleTouchStart = (e) => {
3396
+ const touch = e.touches[0];
3397
+ handleDragStart(touch.clientX, touch.clientY);
3398
+ };
3399
+ const handleTouchMove = (e) => {
3400
+ const touch = e.touches[0];
3401
+ handleDragMove(touch.clientX, touch.clientY);
3402
+ };
3403
+ const handleTouchEnd = () => {
3404
+ handleDragEnd();
3405
+ };
3406
+ // Pointer/Mouse Handlers
3407
+ const handlePointerDown = (e) => {
3408
+ if (e.pointerType === 'mouse' && e.button !== 0)
3409
+ return;
3410
+ handleDragStart(e.clientX, e.clientY);
3411
+ };
3412
+ const handlePointerMove = (e) => {
3413
+ if (!isDragging)
3414
+ return;
3415
+ handleDragMove(e.clientX, e.clientY);
3416
+ };
3417
+ const handlePointerUp = () => {
3418
+ handleDragEnd();
3419
+ };
3420
+ // Close row on click outside if swiped open
2048
3421
  useEffect(() => {
2049
- const handler = setTimeout(() => {
2050
- setDebouncedValue(value);
2051
- }, delay);
2052
- // Cancel the timeout if value or delay changes
3422
+ if (offset === 0)
3423
+ return;
3424
+ const handleClickOutside = (e) => {
3425
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
3426
+ handleClose();
3427
+ }
3428
+ };
3429
+ document.addEventListener('click', handleClickOutside);
2053
3430
  return () => {
2054
- clearTimeout(handler);
3431
+ document.removeEventListener('click', handleClickOutside);
2055
3432
  };
2056
- }, [value, delay]);
2057
- return debouncedValue;
2058
- };
2059
- const useDebounceFn = (fn, ms) => {
2060
- const timeout = useRef(null);
2061
- useEffect(() => {
2062
- return () => clearTimeout(timeout.current);
2063
- }, []);
2064
- return useCallback((...args) => {
2065
- clearTimeout(timeout.current);
2066
- timeout.current = setTimeout(() => fn(...args), ms);
2067
- }, [fn, ms]);
2068
- };
2069
-
2070
- var _path$1;
2071
- function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
2072
- var SvgCheck = function SvgCheck(props) {
2073
- return /*#__PURE__*/React.createElement("svg", _extends$1({
2074
- xmlns: "http://www.w3.org/2000/svg",
2075
- width: 24,
2076
- height: 24,
2077
- fill: "none",
2078
- stroke: "currentColor",
2079
- strokeLinecap: "round",
2080
- strokeLinejoin: "round",
2081
- strokeWidth: 2,
2082
- className: "lucide lucide-check-icon lucide-check",
2083
- viewBox: "0 0 24 24"
2084
- }, props), _path$1 || (_path$1 = /*#__PURE__*/React.createElement("path", {
2085
- d: "M20 6 9 17l-5-5"
2086
- })));
3433
+ }, [offset, handleClose]);
3434
+ const renderActionButton = (action) => {
3435
+ const themeStyle = themeClasses[action.theme || 'primary'];
3436
+ return (jsxs("button", { type: "button", style: { width: `${actionWidth}px` }, onClick: (e) => {
3437
+ e.stopPropagation();
3438
+ action.onClick();
3439
+ handleClose();
3440
+ }, className: buildClassName('h-full flex flex-col items-center justify-center gap-1 text-xs font-semibold shrink-0 cursor-pointer transition-colors px-2 select-none', themeStyle, action.className), "data-testid": `swipe-action-${action.id}`, children: [action.icon && jsx("span", { className: "shrink-0", children: action.icon }), action.label && jsx("span", { className: "truncate max-w-full", children: action.label })] }, action.id));
3441
+ };
3442
+ return (jsxs("div", { ref: containerRef, className: buildClassName('relative overflow-hidden rounded-xl border border-[var(--ui-border-muted)] bg-white dark:bg-gray-800 select-none touch-pan-y', className), "data-testid": "swipeable-row", children: [leftActions.length > 0 && (jsx("div", { className: "absolute left-0 top-0 bottom-0 flex items-center h-full z-0", style: { width: `${maxLeftWidth}px` }, "data-testid": "swipe-left-actions", children: leftActions.map(renderActionButton) })), rightActions.length > 0 && (jsx("div", { className: "absolute right-0 top-0 bottom-0 flex items-center justify-end h-full z-0", style: { width: `${maxRightWidth}px` }, "data-testid": "swipe-right-actions", children: rightActions.map(renderActionButton) })), jsx("div", { onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerUp, style: {
3443
+ transform: `translateX(${offset}px)`,
3444
+ transition: isDragging ? 'none' : 'transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1)',
3445
+ }, className: buildClassName('relative z-10 w-full bg-white dark:bg-gray-800 shadow-xs cursor-grab active:cursor-grabbing', contentClassName), "data-testid": "swipeable-row-content", children: children })] }));
2087
3446
  };
3447
+ SwipeableRow.displayName = 'SwipeableRow';
2088
3448
 
2089
- var _circle, _path;
2090
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2091
- var SvgCirclePlus = function SvgCirclePlus(props) {
2092
- return /*#__PURE__*/React.createElement("svg", _extends({
2093
- xmlns: "http://www.w3.org/2000/svg",
2094
- width: 24,
2095
- height: 24,
2096
- fill: "none",
2097
- stroke: "currentColor",
2098
- strokeLinecap: "round",
2099
- strokeLinejoin: "round",
2100
- strokeWidth: 2,
2101
- className: "lucide lucide-circle-plus-icon lucide-circle-plus",
2102
- viewBox: "0 0 24 24"
2103
- }, props), _circle || (_circle = /*#__PURE__*/React.createElement("circle", {
2104
- cx: 12,
2105
- cy: 12,
2106
- r: 10
2107
- })), _path || (_path = /*#__PURE__*/React.createElement("path", {
2108
- d: "M8 12h8M12 8v8"
2109
- })));
3449
+ function SearchIcon() {
3450
+ return (jsx("svg", { className: "size-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }));
3451
+ }
3452
+ function FilterIcon() {
3453
+ return (jsx("svg", { className: "size-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" }) }));
3454
+ }
3455
+ function SortIcon() {
3456
+ return (jsx("svg", { className: "size-3.5 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
3457
+ }
3458
+ function CheckIcon() {
3459
+ return (jsx("svg", { className: "size-4 text-blue-600 dark:text-blue-400 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M5 13l4 4L19 7" }) }));
3460
+ }
3461
+ const parseNumericValue = (val) => {
3462
+ if (typeof val === 'number')
3463
+ return val;
3464
+ if (val === null || val === undefined)
3465
+ return NaN;
3466
+ const cleaned = String(val).replace(/[^0-9.-]/g, '');
3467
+ return cleaned !== '' ? Number(cleaned) : NaN;
2110
3468
  };
3469
+ function DataList({ items, columns, renderItem, searchable = false, searchQuery: externalSearchQuery, onSearchChange, searchFields, filterFields, selectedFilters: externalFilters, onFilterChange, sorting: externalSorting, onSortChange, swipeableActions, rowKey = 'id', selectable = false, selectedKeys = [], onSelectionChange, onItemClick, loading = false, emptyMessage = 'No items found', pagination, setPagination, containerClass = '', itemClass = '', }) {
3470
+ // Internal Search State
3471
+ const [internalSearchQuery, setInternalSearchQuery] = useState('');
3472
+ const searchQuery = externalSearchQuery !== undefined ? externalSearchQuery : internalSearchQuery;
3473
+ const handleSearchInput = (query) => {
3474
+ onSearchChange ? onSearchChange(query) : setInternalSearchQuery(query);
3475
+ };
3476
+ // Internal Filter State
3477
+ const [internalFilters, setInternalFilters] = useState({});
3478
+ const selectedFilters = externalFilters !== undefined ? externalFilters : internalFilters;
3479
+ // Mobile Bottom Sheet Filter Drawer State
3480
+ const [isFilterSheetOpen, setIsFilterSheetOpen] = useState(false);
3481
+ const [draftFilters, setDraftFilters] = useState({});
3482
+ // Mobile Bottom Sheet Sort Drawer State
3483
+ const [isSortSheetOpen, setIsSortSheetOpen] = useState(false);
3484
+ // Active Filter Count Calculation
3485
+ const activeFilterCount = useMemo(() => {
3486
+ let count = 0;
3487
+ Object.values(selectedFilters).forEach((val) => {
3488
+ if (Array.isArray(val)) {
3489
+ count += val.length;
3490
+ }
3491
+ else if (val !== '' && val !== null && val !== undefined && val !== 'all') {
3492
+ count += 1;
3493
+ }
3494
+ });
3495
+ return count;
3496
+ }, [selectedFilters]);
3497
+ // Internal Sort State
3498
+ const [internalSort, setInternalSort] = useState(() => {
3499
+ if (externalSorting && Object.keys(externalSorting).length > 0) {
3500
+ const field = Object.keys(externalSorting)[0];
3501
+ return { field, dir: externalSorting[field] };
3502
+ }
3503
+ return null;
3504
+ });
3505
+ React__default.useEffect(() => {
3506
+ if (externalSorting !== undefined) {
3507
+ if (Object.keys(externalSorting).length > 0) {
3508
+ const field = Object.keys(externalSorting)[0];
3509
+ setInternalSort({ field, dir: externalSorting[field] });
3510
+ }
3511
+ else {
3512
+ setInternalSort(null);
3513
+ }
3514
+ }
3515
+ }, [externalSorting]);
3516
+ const activeSort = internalSort;
3517
+ const sortableColumns = useMemo(() => (columns === null || columns === void 0 ? void 0 : columns.filter((c) => c.sortable)) || [], [columns]);
3518
+ const sortOptions = useMemo(() => {
3519
+ const opts = [{ label: 'Default Order', value: '' }];
3520
+ sortableColumns.forEach((col) => {
3521
+ const isNum = col.type === 'number';
3522
+ const isDate = col.type === 'date';
3523
+ const lowHigh = isNum
3524
+ ? `${col.label} (Low to High)`
3525
+ : isDate
3526
+ ? `${col.label} (Oldest First)`
3527
+ : `${col.label} (A to Z)`;
3528
+ const highLow = isNum
3529
+ ? `${col.label} (High to Low)`
3530
+ : isDate
3531
+ ? `${col.label} (Newest First)`
3532
+ : `${col.label} (Z to A)`;
3533
+ opts.push({ label: lowHigh, value: `${col.name}:asc` });
3534
+ opts.push({ label: highLow, value: `${col.name}:desc` });
3535
+ });
3536
+ return opts;
3537
+ }, [sortableColumns]);
3538
+ const handleSortSelect = (val) => {
3539
+ if (!val) {
3540
+ setInternalSort(null);
3541
+ onSortChange === null || onSortChange === void 0 ? void 0 : onSortChange({});
3542
+ return;
3543
+ }
3544
+ const [field, dir] = val.split(':');
3545
+ const sortObj = { [field]: dir };
3546
+ setInternalSort({ field, dir: dir });
3547
+ onSortChange === null || onSortChange === void 0 ? void 0 : onSortChange(sortObj);
3548
+ };
3549
+ const activeSortLabel = useMemo(() => {
3550
+ if (!activeSort)
3551
+ return 'Sort';
3552
+ const currVal = `${activeSort.field}:${activeSort.dir}`;
3553
+ const match = sortOptions.find((o) => o.value === currVal);
3554
+ if (!match || !match.value)
3555
+ return 'Sort';
3556
+ return `Sort: ${match.label}`;
3557
+ }, [activeSort, sortOptions]);
3558
+ // Processed Items (Filter + Search + Sort)
3559
+ const processedItems = useMemo(() => {
3560
+ let result = [...items];
3561
+ // 1. Apply Search
3562
+ if (searchQuery.trim()) {
3563
+ const q = searchQuery.toLowerCase().trim();
3564
+ const fieldsToSearch = searchFields || (columns === null || columns === void 0 ? void 0 : columns.map((c) => c.name)) || ['id', 'name', 'title'];
3565
+ result = result.filter((item) => fieldsToSearch.some((field) => {
3566
+ const val = get(item, field);
3567
+ return val !== null && val !== undefined && String(val).toLowerCase().includes(q);
3568
+ }));
3569
+ }
3570
+ // 2. Apply Filters (supporting array checkboxes or single values)
3571
+ const filterKeys = Object.keys(selectedFilters);
3572
+ if (filterKeys.length > 0) {
3573
+ result = result.filter((item) => filterKeys.every((key) => {
3574
+ const filterVal = selectedFilters[key];
3575
+ if (filterVal === undefined || filterVal === null || filterVal === '')
3576
+ return true;
3577
+ const actual = String(get(item, key));
3578
+ if (Array.isArray(filterVal)) {
3579
+ if (filterVal.length === 0)
3580
+ return true;
3581
+ return filterVal.map(String).includes(actual);
3582
+ }
3583
+ return actual === String(filterVal);
3584
+ }));
3585
+ }
3586
+ // 3. Apply Auto Sorting
3587
+ if (activeSort) {
3588
+ const { field, dir } = activeSort;
3589
+ const colDef = columns === null || columns === void 0 ? void 0 : columns.find((c) => c.name === field);
3590
+ const isAsc = dir === 'asc' || dir === '1';
3591
+ result.sort((a, b) => {
3592
+ const valA = get(a, field);
3593
+ const valB = get(b, field);
3594
+ const numA = parseNumericValue(valA);
3595
+ const numB = parseNumericValue(valB);
3596
+ if ((colDef === null || colDef === void 0 ? void 0 : colDef.type) === 'number' || (!isNaN(numA) && !isNaN(numB))) {
3597
+ return isAsc ? numA - numB : numB - numA;
3598
+ }
3599
+ if ((colDef === null || colDef === void 0 ? void 0 : colDef.type) === 'date') {
3600
+ const dA = new Date(valA).getTime();
3601
+ const dB = new Date(valB).getTime();
3602
+ if (!isNaN(dA) && !isNaN(dB)) {
3603
+ return isAsc ? dA - dB : dB - dA;
3604
+ }
3605
+ }
3606
+ const strA = String(valA !== null && valA !== void 0 ? valA : '');
3607
+ const strB = String(valB !== null && valB !== void 0 ? valB : '');
3608
+ return isAsc
3609
+ ? strA.localeCompare(strB, undefined, { numeric: true })
3610
+ : strB.localeCompare(strA, undefined, { numeric: true });
3611
+ });
3612
+ }
3613
+ return result;
3614
+ }, [items, searchQuery, searchFields, columns, selectedFilters, activeSort]);
3615
+ // Draft Filters Matching Count
3616
+ const draftMatchingCount = useMemo(() => {
3617
+ let result = [...items];
3618
+ const filterKeys = Object.keys(draftFilters);
3619
+ if (filterKeys.length > 0) {
3620
+ result = result.filter((item) => filterKeys.every((key) => {
3621
+ const filterVal = draftFilters[key];
3622
+ if (filterVal === undefined || filterVal === null || filterVal === '')
3623
+ return true;
3624
+ const actual = String(get(item, key));
3625
+ if (Array.isArray(filterVal)) {
3626
+ if (filterVal.length === 0)
3627
+ return true;
3628
+ return filterVal.map(String).includes(actual);
3629
+ }
3630
+ return actual === String(filterVal);
3631
+ }));
3632
+ }
3633
+ return result.length;
3634
+ }, [items, draftFilters]);
3635
+ const getKey = (item, idx) => {
3636
+ var _a;
3637
+ if (typeof rowKey === 'function')
3638
+ return rowKey(item);
3639
+ return (_a = item[rowKey]) !== null && _a !== void 0 ? _a : idx;
3640
+ };
3641
+ const isSelected = (key) => selectedKeys.includes(key);
3642
+ const toggleSelectAll = () => {
3643
+ if (selectedKeys.length === processedItems.length) {
3644
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([], []);
3645
+ }
3646
+ else {
3647
+ const allKeys = processedItems.map(getKey);
3648
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(allKeys, processedItems);
3649
+ }
3650
+ };
3651
+ const toggleItemSelect = (key, item) => {
3652
+ const nextKeys = isSelected(key)
3653
+ ? selectedKeys.filter((k) => k !== key)
3654
+ : [...selectedKeys, key];
3655
+ const nextItems = processedItems.filter((it, idx) => nextKeys.includes(getKey(it, idx)));
3656
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(nextKeys, nextItems);
3657
+ };
3658
+ const getItemClassStr = (item, idx) => {
3659
+ if (typeof itemClass === 'function')
3660
+ return itemClass(item, idx);
3661
+ return itemClass;
3662
+ };
3663
+ return (jsxs("div", { className: buildClassName('w-full space-y-3', containerClass), "data-testid": "data-list", children: [(searchable || (filterFields && filterFields.length > 0) || sortableColumns.length > 0) && (jsxs("div", { className: "p-3 bg-gray-50 dark:bg-gray-800/80 rounded-xl border border-[var(--ui-border)] space-y-3", children: [searchable && (jsx(Input, { value: searchQuery, onChange: (e) => handleSearchInput(e.target.value), placeholder: "Search items...", leftGroup: jsx(SearchIcon, {}), clearable: true, onClear: () => handleSearchInput(''), className: "w-full text-xs", size: "sm" })), ((filterFields && filterFields.length > 0) || sortableColumns.length > 0) && (jsxs("div", { className: "flex items-center gap-2", children: [filterFields && filterFields.length > 0 && (jsxs(Button, { theme: "secondary", size: "sm", onClick: () => {
3664
+ setDraftFilters(selectedFilters);
3665
+ setIsFilterSheetOpen(true);
3666
+ }, className: "flex items-center gap-1.5 text-xs font-semibold flex-1 justify-center", "data-testid": "data-list-filter-btn", children: [jsx(FilterIcon, {}), jsx("span", { children: "Filters" }), activeFilterCount > 0 && (jsx("span", { className: "ml-1 size-4 rounded-full bg-blue-600 text-white text-[10px] font-bold flex items-center justify-center", children: activeFilterCount }))] })), sortableColumns.length > 0 && (jsxs(Button, { theme: "secondary", size: "sm", onClick: () => setIsSortSheetOpen(true), className: "flex items-center gap-1.5 text-xs font-semibold flex-1 justify-center", "data-testid": "data-list-sort-btn", children: [jsx(SortIcon, {}), jsx("span", { children: activeSortLabel })] }))] }))] })), filterFields && filterFields.length > 0 && (jsx(Drawer, { isOpen: isFilterSheetOpen, onClose: () => setIsFilterSheetOpen(false), align: "bottom", title: "Filter Items", dragHandle: true, panelClass: "max-h-[85vh] rounded-t-2xl", footer: jsxs("div", { className: "flex items-center gap-3 w-full", children: [jsx(Button, { theme: "secondary", size: "md", onClick: () => setDraftFilters({}), className: "flex-1 text-xs", children: "Clear All" }), jsxs(Button, { theme: "primary", size: "md", onClick: () => {
3667
+ onFilterChange ? onFilterChange(draftFilters) : setInternalFilters(draftFilters);
3668
+ setIsFilterSheetOpen(false);
3669
+ }, className: "flex-1 text-xs font-semibold", "data-testid": "data-list-apply-filters-btn", children: ["Apply Filters (", draftMatchingCount, ")"] })] }), footerSticky: true, children: jsx("div", { className: "space-y-6 py-2", children: filterFields.map((field) => {
3670
+ const selectedArray = Array.isArray(draftFilters[field.name])
3671
+ ? draftFilters[field.name]
3672
+ : draftFilters[field.name] !== undefined && draftFilters[field.name] !== ''
3673
+ ? [draftFilters[field.name]]
3674
+ : [];
3675
+ return (jsxs("div", { className: "space-y-2.5", children: [jsx("h4", { className: "text-xs font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400 px-1", children: field.label }), jsx("div", { className: "space-y-1.5 bg-gray-50 dark:bg-gray-800/60 p-2.5 rounded-xl border border-[var(--ui-border-muted)]", children: field.options.map((opt) => {
3676
+ const checked = selectedArray.includes(opt.value);
3677
+ return (jsxs("label", { className: "flex items-center justify-between p-2 rounded-lg hover:bg-white dark:hover:bg-gray-800 cursor-pointer transition-colors", children: [jsx("span", { className: "text-sm font-medium text-gray-800 dark:text-gray-200", children: opt.label }), jsx(Checkbox, { checked: checked, onChange: () => {
3678
+ const next = checked
3679
+ ? selectedArray.filter((v) => v !== opt.value)
3680
+ : [...selectedArray, opt.value];
3681
+ setDraftFilters((prev) => ({
3682
+ ...prev,
3683
+ [field.name]: next,
3684
+ }));
3685
+ } })] }, String(opt.value)));
3686
+ }) })] }, field.name));
3687
+ }) }) })), sortableColumns.length > 0 && (jsx(Drawer, { isOpen: isSortSheetOpen, onClose: () => setIsSortSheetOpen(false), align: "bottom", title: "Sort Items By", dragHandle: true, panelClass: "max-h-[70vh] rounded-t-2xl", children: jsx("div", { className: "space-y-1 py-2", children: sortOptions.map((opt) => {
3688
+ const isSelected = (activeSort ? `${activeSort.field}:${activeSort.dir}` : '') === opt.value;
3689
+ return (jsxs("button", { type: "button", onClick: () => {
3690
+ handleSortSelect(opt.value);
3691
+ setIsSortSheetOpen(false);
3692
+ }, className: buildClassName('w-full flex items-center justify-between p-3.5 rounded-xl text-left transition-colors cursor-pointer', isSelected
3693
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3694
+ : 'hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-200 font-medium'), "data-testid": `data-list-sort-opt-${opt.value || 'default'}`, children: [jsx("span", { className: "text-sm", children: opt.label }), isSelected && jsx(CheckIcon, {})] }, opt.value));
3695
+ }) }) })), selectable && processedItems.length > 0 && (jsxs("div", { className: "p-3 bg-gray-50 dark:bg-gray-800/80 rounded-xl border border-[var(--ui-border)] flex items-center justify-between text-xs", children: [jsxs("label", { className: "flex items-center gap-2 font-medium text-gray-700 dark:text-gray-300 cursor-pointer", children: [jsx(Checkbox, { checked: processedItems.length > 0 && selectedKeys.length === processedItems.length, onChange: toggleSelectAll }), jsx("span", { children: "Select All Items" })] }), jsxs("span", { className: "text-gray-400 font-semibold", children: [selectedKeys.length, " of ", processedItems.length] })] })), jsx("div", { className: "space-y-3", children: loading ? (jsx("div", { className: "p-8 text-center text-sm text-gray-500 bg-white dark:bg-gray-800 rounded-xl border border-[var(--ui-border)]", children: "Loading items..." })) : processedItems.length === 0 ? (jsx("div", { className: "p-8 text-center text-sm text-gray-500 bg-white dark:bg-gray-800 rounded-xl border border-[var(--ui-border)]", children: emptyMessage })) : (processedItems.map((item, idx) => {
3696
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
3697
+ const key = getKey(item, idx);
3698
+ const selected = isSelected(key);
3699
+ const actions = swipeableActions === null || swipeableActions === void 0 ? void 0 : swipeableActions(item);
3700
+ const customClass = getItemClassStr(item, idx);
3701
+ const contentNode = renderItem ? (renderItem(item, idx)) : (jsxs("div", { onClick: () => onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick(item, idx), className: buildClassName('p-4 bg-white dark:bg-gray-800 rounded-xl border border-[var(--ui-border)] shadow-xs space-y-3 transition-colors', onItemClick && 'cursor-pointer hover:border-blue-500/50', selected && 'ring-2 ring-blue-500/50 bg-blue-50/20 dark:bg-blue-950/20', customClass), "data-testid": `data-list-item-${key}`, children: [jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-[var(--ui-border-muted)] pb-2.5", children: [jsx("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: selectable ? (jsx(Checkbox, { checked: selected, onChange: () => toggleItemSelect(key), "aria-label": `Select item ${key}`, label: jsx("span", { className: "font-bold text-sm text-gray-900 dark:text-white truncate block", children: columns && ((_a = columns[0]) === null || _a === void 0 ? void 0 : _a.render)
3702
+ ? columns[0].render(item)
3703
+ : String((_d = get(item, (_c = (_b = columns === null || columns === void 0 ? void 0 : columns[0]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'title')) !== null && _d !== void 0 ? _d : '') }) })) : (jsx("div", { className: "font-bold text-sm text-gray-900 dark:text-white truncate", children: columns && ((_e = columns[0]) === null || _e === void 0 ? void 0 : _e.render)
3704
+ ? columns[0].render(item)
3705
+ : String((_h = get(item, (_g = (_f = columns === null || columns === void 0 ? void 0 : columns[0]) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : 'title')) !== null && _h !== void 0 ? _h : '') })) }), columns && columns[1] && (jsx("div", { className: "shrink-0 text-xs", children: columns[1].render
3706
+ ? columns[1].render(item)
3707
+ : String((_j = get(item, columns[1].name)) !== null && _j !== void 0 ? _j : '') }))] }), columns && columns.length > 2 && (jsx("div", { className: "grid grid-cols-2 gap-2 text-xs pt-1", children: columns.slice(2).map((col) => {
3708
+ const val = col.render ? col.render(item) : get(item, col.name);
3709
+ if (val === null || val === undefined || val === '')
3710
+ return null;
3711
+ return (jsxs("div", { className: "min-w-0", children: [jsx("span", { className: "text-gray-400 dark:text-gray-500 font-medium block truncate", children: col.label }), jsx("span", { className: "text-gray-800 dark:text-gray-200 font-semibold block truncate mt-0.5", children: val })] }, String(col.name)));
3712
+ }) }))] }));
3713
+ if (actions && (((_k = actions.leftActions) === null || _k === void 0 ? void 0 : _k.length) || ((_l = actions.rightActions) === null || _l === void 0 ? void 0 : _l.length))) {
3714
+ return (jsx(SwipeableRow, { leftActions: actions.leftActions, rightActions: actions.rightActions, children: contentNode }, key));
3715
+ }
3716
+ return jsx("div", { children: contentNode }, key);
3717
+ })) }), pagination && pagination.total > 0 && (jsx("div", { className: "pt-2 flex justify-center", children: jsx(Pagination, { ...pagination, onChange: (newPag) => setPagination === null || setPagination === void 0 ? void 0 : setPagination(newPag) }) }))] }));
3718
+ }
3719
+ DataList.displayName = 'DataList';
2111
3720
 
2112
3721
  const sizeClasses$1 = {
2113
3722
  sm: {
2114
- input: 'px-2.5 py-1 text-xs leading-5 min-h-[30px]',
3723
+ input: 'px-2.5 py-1.5 text-xs leading-5 min-h-[32px]',
2115
3724
  group: 'w-8 text-xs',
2116
3725
  icon: 'size-3.5',
2117
3726
  badgeSize: 'sm',
@@ -2130,7 +3739,10 @@ const sizeClasses$1 = {
2130
3739
  },
2131
3740
  };
2132
3741
  const SelectBox = forwardRef((props, forwardedRef) => {
2133
- const { labelKey = 'label', valueKey = 'value', name, id = name, options = [], groups, selected, size = 'md', label = null, labelWrapperClass = '', labelClass = '', labelHint = null, disabled = false, containerClass = '', onChange = () => { }, placeholder, dropdownContainerClass = 'z-20', multiple = false, maxSelection, showSelectAll = false, immediate = true, showErrorMessage = true, error = null, helperText, leftGroup, renderOption, async = false, searchable = true, required = false, allowAdd = false, addNewText = 'Create', onAdd = () => { }, allowClear = false, modalDropdown = false, noOptionsText = 'No options available', } = props;
3742
+ const { labelKey = 'label', valueKey = 'value', name, id = name, options = [], groups, selected, size = 'md', label = null, labelWrapperClass = '', labelClass = '', labelHint = null, disabled = false, containerClass = '', onChange = () => { }, placeholder, dropdownContainerClass = 'z-20', multiple = false, maxSelection, showSelectAll = false, immediate = true, showErrorMessage = true, error = null, helperText, leftGroup, renderOption, async = false, searchable = true, required = false, allowAdd = false, addNewText = 'Create', onAdd = () => { }, allowClear = false, allowFreeText = false, modalDropdown = false, noOptionsText = 'No options available', } = props;
3743
+ if (props.asBottomSheet || props.mobileMode === 'sheet') {
3744
+ return jsx(MobilePicker, { ...props });
3745
+ }
2134
3746
  const hasError = Boolean(error);
2135
3747
  const [query, setQuery] = useState('');
2136
3748
  const debouncedQuery = useDebounce(query, 500);
@@ -2178,6 +3790,49 @@ const SelectBox = forwardRef((props, forwardedRef) => {
2178
3790
  const getValue = useCallback((opt) => {
2179
3791
  return typeof opt === 'string' ? opt : opt[valueKey];
2180
3792
  }, [valueKey]);
3793
+ const createFreeTextOption = useCallback((text) => {
3794
+ const sample = allOptions[0] || (Array.isArray(selected) ? selected[0] : selected);
3795
+ if (typeof sample === 'string' ||
3796
+ (!sample && typeof labelKey === 'string' && labelKey === 'label')) {
3797
+ return text;
3798
+ }
3799
+ return {
3800
+ [labelKey]: text,
3801
+ [valueKey]: text,
3802
+ };
3803
+ }, [allOptions, selected, labelKey, valueKey]);
3804
+ const handleFreeTextCommit = useCallback((queryText) => {
3805
+ const trimmed = queryText.trim();
3806
+ if (!trimmed)
3807
+ return;
3808
+ const existing = allOptions.find((opt) => {
3809
+ const display = getDisplayValue(opt);
3810
+ return (display === null || display === void 0 ? void 0 : display.toLowerCase()) === trimmed.toLowerCase();
3811
+ });
3812
+ const valueToCommit = existing || createFreeTextOption(trimmed);
3813
+ if (multiple) {
3814
+ const current = isArray(selected) ? selected : [];
3815
+ const alreadySelected = current.some((item) => { var _a; return ((_a = getDisplayValue(item)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === trimmed.toLowerCase(); });
3816
+ if (!alreadySelected) {
3817
+ if (maxSelection && current.length >= maxSelection)
3818
+ return;
3819
+ onChange([...current, valueToCommit]);
3820
+ }
3821
+ setQuery('');
3822
+ }
3823
+ else {
3824
+ onChange(valueToCommit);
3825
+ setQuery('');
3826
+ }
3827
+ }, [
3828
+ allOptions,
3829
+ getDisplayValue,
3830
+ createFreeTextOption,
3831
+ multiple,
3832
+ selected,
3833
+ maxSelection,
3834
+ onChange,
3835
+ ]);
2181
3836
  const removeSelection = (idx) => {
2182
3837
  var _a;
2183
3838
  if (!isArray(selected))
@@ -2250,11 +3905,25 @@ const SelectBox = forwardRef((props, forwardedRef) => {
2250
3905
  if (async && debouncedQuery)
2251
3906
  handleSearch(debouncedQuery);
2252
3907
  }, [debouncedQuery, async, handleSearch]);
3908
+ const normalizedSelected = useMemo(() => {
3909
+ if (multiple) {
3910
+ if (Array.isArray(selected))
3911
+ return selected;
3912
+ if (selected !== null && selected !== undefined)
3913
+ return [selected];
3914
+ return [];
3915
+ }
3916
+ else {
3917
+ if (Array.isArray(selected))
3918
+ return selected.length > 0 ? selected[0] : null;
3919
+ return selected !== null && selected !== void 0 ? selected : null;
3920
+ }
3921
+ }, [multiple, selected]);
2253
3922
  const isAllSelected = useMemo(() => {
2254
- if (!multiple || !Array.isArray(selected) || !allOptions.length)
3923
+ if (!multiple || !Array.isArray(normalizedSelected) || !allOptions.length)
2255
3924
  return false;
2256
- return allOptions.length === selected.length;
2257
- }, [multiple, selected, allOptions]);
3925
+ return allOptions.length === normalizedSelected.length;
3926
+ }, [multiple, normalizedSelected, allOptions]);
2258
3927
  const handleToggleSelectAll = () => {
2259
3928
  if (isAllSelected) {
2260
3929
  onChange([]);
@@ -2264,30 +3933,69 @@ const SelectBox = forwardRef((props, forwardedRef) => {
2264
3933
  }
2265
3934
  };
2266
3935
  const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
2267
- return (jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), ref: containerRef, children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, "aria-required": required, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs(Combobox, { multiple: multiple, immediate: immediate, name: name, value: selected, onChange: comboboxOnChangeWrapper, onClose: () => setQuery(''), disabled: disabled, children: [multiple ? (jsxs("div", { className: buildClassName(baseInputClass, 'flex flex-wrap gap-2 peer relative', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : ''), ref: forwardedRef, children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute left-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), isArray(selected) &&
2268
- (selected === null || selected === void 0 ? void 0 : selected.length) > 0 &&
2269
- selected.map((option, idx) => (jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, removable: !disabled, onRemove: () => removeSelection(idx), children: getDisplayValue(option) }, `${getValue(option)}-${idx}`))), jsx(ComboboxInput, { className: "outline-none flex-1 dark:placeholder-gray-400 placeholder-gray-400 bg-transparent", "aria-label": name, value: query, autoComplete: "off", placeholder: (selected === null || selected === void 0 ? void 0 : selected.length) ? '' : placeholder, onChange: (e) => setQuery(e.target.value), id: id, ref: inputRef, onKeyDown: (e) => {
2270
- if (multiple && e.key === 'Backspace' && !query) {
2271
- if (Array.isArray(selected) && selected.length > 0) {
2272
- removeSelection(selected.length - 1);
3936
+ return (jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), ref: containerRef, children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, "aria-required": required, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs(Combobox, { multiple: multiple, immediate: immediate, name: name, value: normalizedSelected, onChange: comboboxOnChangeWrapper, onClose: () => setQuery(''), disabled: disabled, by: (a, b) => (a && b ? getValue(a) === getValue(b) : a === b), children: [multiple ? (jsxs("div", { className: buildClassName(baseInputClass, 'flex flex-wrap gap-2 peer relative', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : ''), ref: forwardedRef, children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute left-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), isArray(normalizedSelected) &&
3937
+ (normalizedSelected === null || normalizedSelected === void 0 ? void 0 : normalizedSelected.length) > 0 &&
3938
+ normalizedSelected.map((option, idx) => (jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, removable: !disabled, onRemove: () => removeSelection(idx), children: getDisplayValue(option) }, `${getValue(option)}-${idx}`))), jsx(ComboboxInput, { className: "outline-none flex-1 dark:placeholder-gray-400 placeholder-gray-400 bg-transparent", "aria-label": name, value: query, autoComplete: "off", placeholder: (normalizedSelected === null || normalizedSelected === void 0 ? void 0 : normalizedSelected.length) ? '' : placeholder, onChange: (e) => {
3939
+ const val = e.target.value;
3940
+ if (allowFreeText && multiple && val.includes(',')) {
3941
+ const parts = val.split(',');
3942
+ parts.forEach((p) => {
3943
+ if (p.trim())
3944
+ handleFreeTextCommit(p.trim());
3945
+ });
3946
+ setQuery('');
3947
+ }
3948
+ else {
3949
+ setQuery(val);
3950
+ }
3951
+ }, id: id, ref: inputRef, onKeyDown: (e) => {
3952
+ if (allowFreeText && (e.key === 'Enter' || e.key === ',') && query.trim()) {
3953
+ e.preventDefault();
3954
+ handleFreeTextCommit(query.replace(/,/g, ''));
3955
+ }
3956
+ else if (multiple && e.key === 'Backspace' && !query) {
3957
+ if (Array.isArray(normalizedSelected) && normalizedSelected.length > 0) {
3958
+ removeSelection(normalizedSelected.length - 1);
2273
3959
  }
2274
3960
  }
2275
- }, "data-testid": "combobox-input" }), jsx(ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxs("div", { className: "relative", ref: forwardedRef, children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute left-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500 z-10', currentSize.group), children: leftGroup })), jsx(ComboboxInput, { "aria-label": name, displayValue: (option) => (option ? getDisplayValue(option) : null), autoComplete: "off", placeholder: placeholder, onChange: (event) => setQuery(event.target.value), className: buildClassName(baseInputClass, hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : ''), disabled: disabled, id: id, readOnly: !searchable, ref: inputRef, "data-testid": "combobox-input" }), allowClear && !isEmpty(selected) && (jsx(Button, { size: "xs", iconOnly: true, "aria-label": "Clear selection", theme: "secondary", variant: "plain", className: "group absolute inset-y-0 right-8 h-6 top-2", onClick: () => handleOnChangeInternal(multiple ? [] : null), disabled: disabled, "data-testid": "combobox-clear-button", noOutlineOnFocus: true, children: jsx(SvgX, { className: "size-4 stroke-gray-500 dark:stroke-gray-300" }) })), jsx(ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxs(ComboboxOptions, { anchor: { to: 'bottom', gap: 5 }, as: "div", modal: modalDropdown, className: buildClassName('w-[var(--input-width)] rounded-lg border border-gray-200 dark:border-white/5 bg-white dark:bg-gray-800 p-1 [--anchor-gap:var(--spacing-1)]', '[--anchor-max-height:20rem]', 'origin-top border transition duration-200 ease-[cubic-bezier(0.4, 0.0, 0.2, 1)] data-[closed]:translate-y-[-15%] data-[closed]:opacity-0', dropdownContainerClass), transition: true, "data-testid": "combobox-options", children: [multiple && showSelectAll && allOptions.length > 0 && (jsxs("div", { className: "pb-1 mb-1 border-b border-gray-200 dark:border-gray-700/80 px-3 pt-1 flex items-center justify-between", children: [jsx("button", { type: "button", onClick: handleToggleSelectAll, className: "text-xs font-semibold text-blue-600 dark:text-blue-400 hover:underline cursor-pointer", children: isAllSelected ? 'Deselect All' : 'Select All' }), jsxs("span", { className: "text-[11px] font-medium text-gray-400", children: [Array.isArray(selected) ? selected.length : 0, " of ", allOptions.length] })] })), optionsLoading ? (jsx(BodyText, { "data-testid": "options-loading", className: "flex items-center justify-center py-2 px-3 select-none", children: jsx(Loader, { size: "sm" }) })) : shouldShowTypeToSearch ? (jsx(BodyText, { className: "flex items-center justify-between py-2 px-3 select-none", children: "Type to search..." })) : (jsxs("div", { children: [filteredGroups
3961
+ }, onBlur: () => {
3962
+ if (allowFreeText && query.trim()) {
3963
+ handleFreeTextCommit(query.replace(/,/g, ''));
3964
+ }
3965
+ }, "data-testid": "combobox-input" }), jsx(ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxs("div", { className: "relative", ref: forwardedRef, children: [hasLeftGroup && (jsx("span", { className: buildClassName('absolute left-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500 z-10', currentSize.group), children: leftGroup })), jsx(ComboboxInput, { "aria-label": name, displayValue: (option) => (option ? getDisplayValue(option) : null), autoComplete: "off", placeholder: placeholder, onChange: (event) => setQuery(event.target.value), onKeyDown: (e) => {
3966
+ if (allowFreeText && e.key === 'Enter' && query.trim()) {
3967
+ e.preventDefault();
3968
+ handleFreeTextCommit(query);
3969
+ }
3970
+ }, onBlur: () => {
3971
+ if (allowFreeText && query.trim()) {
3972
+ handleFreeTextCommit(query);
3973
+ }
3974
+ }, onFocus: () => {
3975
+ setQuery('');
3976
+ }, className: buildClassName(baseInputClass, hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : ''), disabled: disabled, id: id, readOnly: !searchable, ref: inputRef, "data-testid": "combobox-input" }), allowClear && !isEmpty(normalizedSelected) && (jsx(Button, { size: "xs", iconOnly: true, "aria-label": "Clear selection", theme: "secondary", variant: "plain", className: "group absolute inset-y-0 right-8 h-6 top-2", onClick: () => handleOnChangeInternal(multiple ? [] : null), disabled: disabled, "data-testid": "combobox-clear-button", noOutlineOnFocus: true, children: jsx(SvgX, { className: "size-4 stroke-gray-500 dark:stroke-gray-300" }) })), jsx(ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxs(ComboboxOptions, { anchor: { to: 'bottom', gap: 5 }, as: "div", modal: modalDropdown, className: buildClassName('w-[var(--input-width)] rounded-lg border border-[var(--ui-border)] bg-white dark:bg-gray-800 p-1 shadow-lg max-h-80 overflow-y-auto z-50 [--anchor-gap:var(--spacing-1)]', '[--anchor-max-height:20rem]', 'origin-top border transition duration-200 ease-[cubic-bezier(0.4, 0.0, 0.2, 1)] data-[closed]:translate-y-[-15%] data-[closed]:opacity-0', dropdownContainerClass), transition: true, "data-testid": "combobox-options", children: [multiple && showSelectAll && allOptions.length > 0 && (jsxs("div", { className: "pb-1 mb-1 border-b border-[var(--ui-border-muted)] px-3 pt-1 flex items-center justify-between", children: [jsx("button", { type: "button", onClick: handleToggleSelectAll, className: "text-xs font-semibold text-blue-600 dark:text-blue-400 hover:underline cursor-pointer", children: isAllSelected ? 'Deselect All' : 'Select All' }), jsxs("span", { className: "text-[11px] font-medium text-gray-400", children: [Array.isArray(normalizedSelected) ? normalizedSelected.length : 0, " of", ' ', allOptions.length] })] })), optionsLoading ? (jsx(BodyText, { "data-testid": "options-loading", className: "flex items-center justify-center py-2 px-3 select-none", children: jsx(Loader, { size: "sm" }) })) : shouldShowTypeToSearch ? (jsx(BodyText, { className: "flex items-center justify-between py-2 px-3 select-none", children: "Type to search..." })) : (jsxs("div", { children: [allowFreeText &&
3977
+ query.trim() &&
3978
+ !allOptions.some((opt) => { var _a; return ((_a = getDisplayValue(opt)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === query.trim().toLowerCase(); }) && (jsx(ComboboxOption, { value: createFreeTextOption(query.trim()), className: "group flex items-center gap-2 rounded-lg py-1.5 px-3 select-none text-sm data-[focus]:bg-blue-50 dark:data-[focus]:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-medium cursor-pointer w-full", "data-testid": "freetext-option", children: jsxs("span", { children: ["Use \"", query.trim(), "\""] }) }, `freetext-${query.trim()}`)), filteredGroups
2276
3979
  ? filteredGroups.map((grp, gIdx) => (jsxs("div", { children: [jsx("div", { className: "text-[11px] font-bold uppercase tracking-wider text-gray-400 dark:text-gray-500 px-3 py-1 select-none", children: grp.group }), grp.options.map((option) => {
2277
3980
  const optVal = getValue(option);
2278
3981
  const isOptSelected = multiple
2279
- ? isArray(selected) && selected.some((s) => getValue(s) === optVal)
2280
- : selected && getValue(selected) === optVal;
2281
- return (jsx(ComboboxOption, { disabled: option.disabled, value: option, className: "group rounded-lg py-1.5 px-3 select-none data-[focus]:bg-black/3 dark:data-[focus]:bg-white/10 data-disabled:opacity-50 cursor-pointer data-disabled:pointer-events-none", children: renderOption ? (renderOption(option, Boolean(isOptSelected))) : (jsxs("div", { className: "flex items-center justify-between gap-2 dark:text-white group-data-[selected]:text-blue-600", children: [jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
3982
+ ? isArray(normalizedSelected) &&
3983
+ normalizedSelected.some((s) => getValue(s) === optVal)
3984
+ : normalizedSelected && getValue(normalizedSelected) === optVal;
3985
+ return (jsx(ComboboxOption, { disabled: option.disabled, value: option, className: "group rounded-lg py-1.5 px-3 select-none data-[focus]:bg-gray-100 dark:data-[focus]:bg-white/10 data-disabled:opacity-50 cursor-pointer data-disabled:pointer-events-none", children: renderOption ? (renderOption(option, Boolean(isOptSelected))) : (jsxs("div", { className: "flex items-center justify-between gap-2 text-gray-900 dark:text-white group-data-[selected]:text-blue-600", children: [jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
2282
3986
  })] }, gIdx)))
2283
3987
  : /* Render Standard Flat Options */
2284
3988
  filteredOptions.map((option) => {
2285
3989
  const optVal = getValue(option);
2286
3990
  const isOptSelected = multiple
2287
- ? isArray(selected) && selected.some((s) => getValue(s) === optVal)
2288
- : selected && getValue(selected) === optVal;
2289
- return (jsx(ComboboxOption, { disabled: option.disabled, value: option, className: "group rounded-lg py-1.5 px-3 select-none data-[focus]:bg-black/3 dark:data-[focus]:bg-white/10 data-disabled:opacity-50 cursor-pointer data-disabled:pointer-events-none", children: renderOption ? (renderOption(option, Boolean(isOptSelected))) : (jsxs("div", { className: "flex items-center justify-between gap-2 dark:text-white group-data-[selected]:text-blue-600", children: [jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
2290
- }), filteredOptions.length === 0 && !(filteredGroups === null || filteredGroups === void 0 ? void 0 : filteredGroups.length) && (jsx("div", { "data-testid": "no-result-found", className: "flex items-center gap-2 py-1.5 px-3 select-none text-gray-500 dark:text-gray-400", children: query ? (jsxs(Fragment, { children: ["No results found for ", jsx("span", { className: "font-semibold", children: query })] })) : (noOptionsText) })), allowAdd && (jsx(ComboboxOption, { value: query, className: "group rounded-lg py-1.5 px-3 cursor-pointer text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700", onClick: () => void handleAddAndSelect(query), children: jsxs("div", { className: "flex items-center gap-2", children: [jsx(SvgCirclePlus, { className: "size-4.5" }), jsxs(TextContent, { children: [addNewText, " \"", query, "\""] })] }) }))] }))] })] }), showErrorMessage && error && (jsx("div", { className: "mt-1", children: jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsx("div", { className: "mt-1", children: jsx(TextContent, { muted: true, small: true, children: helperText }) }))] }));
3991
+ ? isArray(normalizedSelected) &&
3992
+ normalizedSelected.some((s) => getValue(s) === optVal)
3993
+ : normalizedSelected && getValue(normalizedSelected) === optVal;
3994
+ return (jsx(ComboboxOption, { disabled: option.disabled, value: option, className: "group rounded-lg py-1.5 px-3 select-none data-[focus]:bg-gray-100 dark:data-[focus]:bg-white/10 data-disabled:opacity-50 cursor-pointer data-disabled:pointer-events-none", children: renderOption ? (renderOption(option, Boolean(isOptSelected))) : (jsxs("div", { className: "flex items-center justify-between gap-2 text-gray-900 dark:text-white group-data-[selected]:text-blue-600", children: [jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
3995
+ }), filteredOptions.length === 0 &&
3996
+ !(filteredGroups === null || filteredGroups === void 0 ? void 0 : filteredGroups.length) &&
3997
+ !allowFreeText &&
3998
+ !(allowAdd && query.trim()) && (jsxs("div", { "data-testid": "no-result-found", className: "flex items-center gap-2 py-1.5 px-3 select-none", children: [jsx(TextContent, { muted: true, small: true, children: noOptionsText }), jsx(TextContent, { strong: true, small: true, children: query })] })), !allowFreeText && allowAdd && Boolean(query.trim()) && (jsx(ComboboxOption, { value: query, className: "group rounded-lg py-1.5 px-3 cursor-pointer text-gray-700 dark:text-gray-300 data-[focus]:bg-gray-100 dark:data-[focus]:bg-gray-700", onClick: () => void handleAddAndSelect(query), children: jsxs("div", { className: "flex items-center gap-2", children: [jsx(SvgCirclePlus, { className: "size-4.5" }), jsxs(TextContent, { children: [addNewText, " \"", query, "\""] })] }) }, `add-${query.trim()}`))] }))] })] }), showErrorMessage && error && (jsx("div", { className: "mt-1", children: jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsx("div", { className: "mt-1", children: jsx(TextContent, { muted: true, small: true, children: helperText }) }))] }));
2291
3999
  });
2292
4000
  SelectBox.displayName = 'SelectBox';
2293
4001
 
@@ -2321,10 +4029,15 @@ Skeleton.displayName = 'Skeleton';
2321
4029
 
2322
4030
  const MinusIcon = ({ className }) => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": "true", children: jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) }));
2323
4031
  const PlusIcon = ({ className }) => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": "true", children: [jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
4032
+ const CONTAINER_SIZE_CLASS = {
4033
+ sm: 'h-8 text-xs',
4034
+ md: 'h-10 text-sm',
4035
+ lg: 'h-12 text-base',
4036
+ };
2324
4037
  const BUTTON_SIZE_CLASS = {
2325
- sm: 'size-7',
2326
- md: 'size-9',
2327
- lg: 'size-10',
4038
+ sm: 'w-7.5 h-full',
4039
+ md: 'w-9.5 h-full',
4040
+ lg: 'w-11 h-full',
2328
4041
  };
2329
4042
  const ICON_SIZE_CLASS = {
2330
4043
  sm: 'size-3.5',
@@ -2332,12 +4045,15 @@ const ICON_SIZE_CLASS = {
2332
4045
  lg: 'size-4.5',
2333
4046
  };
2334
4047
  const INPUT_TEXT_CLASS = {
2335
- sm: 'w-12 text-xs py-1',
2336
- md: 'w-16 text-sm py-1.5',
2337
- lg: 'w-20 text-base py-2',
4048
+ sm: 'w-12 text-xs',
4049
+ md: 'w-16 text-sm',
4050
+ lg: 'w-20 text-base',
2338
4051
  };
2339
4052
  const QuantityStepper = forwardRef((props, ref) => {
2340
- const { value, onChange, min = 0, max = 99999, step = 1, label, size = 'md', prefix, suffix, disabled = false, className, onFocus, ...restProps } = props;
4053
+ const { value, onChange, min = 0, max = 99999, step = 1, label, labelHint, helperText, error, showErrorMessage = true, size = 'md', prefix, suffix, disabled = false, className, onFocus, id: customId, ...restProps } = props;
4054
+ const autoId = useId();
4055
+ const stepperId = customId || `stepper-${autoId}`;
4056
+ const hasError = Boolean(error);
2341
4057
  const handleDecrement = () => {
2342
4058
  if (disabled)
2343
4059
  return;
@@ -2363,10 +4079,18 @@ const QuantityStepper = forwardRef((props, ref) => {
2363
4079
  };
2364
4080
  const isAtMin = disabled || value <= min;
2365
4081
  const isAtMax = disabled || value >= max;
2366
- return (jsxs("div", { className: buildClassName('flex flex-col gap-1 inline-flex', className), children: [label && (jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300", children: label })), jsxs("div", { className: buildClassName('inline-flex items-center rounded-lg border border-gray-300 bg-white dark:border-gray-600 dark:bg-gray-800 shadow-xs focus-within:ring-2 focus-within:ring-[var(--ui-primary-ring)] focus-within:border-[var(--ui-primary)] transition-all', disabled ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900' : ''), "data-testid": "quantity-stepper", children: [jsx("button", { type: "button", disabled: isAtMin, onClick: handleDecrement, tabIndex: -1, "aria-label": "Decrease quantity", className: buildClassName('flex items-center justify-center rounded-l-md text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 transition-colors', BUTTON_SIZE_CLASS[size], isAtMin ? 'opacity-30 hover:bg-transparent cursor-not-allowed' : 'cursor-pointer'), "data-testid": "stepper-decrement", children: jsx(MinusIcon, { className: ICON_SIZE_CLASS[size] }) }), prefix && jsx("span", { className: "pl-1 text-gray-400 dark:text-gray-500", children: prefix }), jsx("input", { ref: ref, type: "number", min: min, max: max, step: step, value: value === 0 ? '' : value, placeholder: "0", disabled: disabled, onFocus: (e) => {
4082
+ return (jsxs("div", { className: buildClassName('flex flex-col gap-1 inline-flex', className), children: [label && (jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsx(Label, { htmlFor: stepperId, className: disabled ? 'opacity-70 cursor-not-allowed' : '', children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs("div", { className: buildClassName('inline-flex items-center rounded-lg shadow-2xs transition-all duration-150', 'outline outline-1 -outline-offset-1', CONTAINER_SIZE_CLASS[size], hasError
4083
+ ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
4084
+ : 'outline-[var(--ui-border)]', disabled
4085
+ ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 outline-[var(--ui-border-muted)]'
4086
+ : 'bg-white dark:bg-gray-700', 'focus-within:outline-[var(--ui-focus-ring)] focus-within:outline-2 focus-within:-outline-offset-2'), "data-testid": "quantity-stepper", children: [jsx("button", { type: "button", disabled: isAtMin, onClick: handleDecrement, tabIndex: -1, "aria-label": "Decrease quantity", className: buildClassName('flex items-center justify-center rounded-l-lg text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-white transition-colors shrink-0', BUTTON_SIZE_CLASS[size], isAtMin
4087
+ ? 'opacity-30 hover:bg-transparent cursor-not-allowed'
4088
+ : 'cursor-pointer hover:bg-gray-100/80 dark:hover:bg-gray-600/60'), "data-testid": "stepper-decrement", children: jsx(MinusIcon, { className: ICON_SIZE_CLASS[size] }) }), prefix && (jsx("span", { className: "pl-1 text-gray-400 dark:text-gray-400 select-none text-xs shrink-0", children: prefix })), jsx("input", { ref: ref, id: stepperId, type: "number", min: min, max: max, step: step, value: value === 0 ? '' : value, placeholder: "0", disabled: disabled, onFocus: (e) => {
2367
4089
  e.target.select();
2368
4090
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(e);
2369
- }, onChange: handleInputChange, className: buildClassName('text-center font-semibold text-gray-900 dark:text-white bg-transparent focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none', INPUT_TEXT_CLASS[size]), "data-testid": "stepper-input", ...restProps }), suffix && jsx("span", { className: "pr-1 text-xs text-gray-500 dark:text-gray-400", children: suffix }), jsx("button", { type: "button", disabled: isAtMax, onClick: handleIncrement, tabIndex: -1, "aria-label": "Increase quantity", className: buildClassName('flex items-center justify-center rounded-r-md text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 transition-colors', BUTTON_SIZE_CLASS[size], isAtMax ? 'opacity-30 hover:bg-transparent cursor-not-allowed' : 'cursor-pointer'), "data-testid": "stepper-increment", children: jsx(PlusIcon, { className: ICON_SIZE_CLASS[size] }) })] })] }));
4091
+ }, onChange: handleInputChange, className: buildClassName('text-center font-semibold text-gray-900 dark:text-white bg-transparent focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none', INPUT_TEXT_CLASS[size]), "data-testid": "stepper-input", ...restProps }), suffix && (jsx("span", { className: "pr-1 text-gray-500 dark:text-gray-400 select-none text-xs shrink-0", children: suffix })), jsx("button", { type: "button", disabled: isAtMax, onClick: handleIncrement, tabIndex: -1, "aria-label": "Increase quantity", className: buildClassName('flex items-center justify-center rounded-r-lg text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-white transition-colors shrink-0', BUTTON_SIZE_CLASS[size], isAtMax
4092
+ ? 'opacity-30 hover:bg-transparent cursor-not-allowed'
4093
+ : 'cursor-pointer hover:bg-gray-100/80 dark:hover:bg-gray-600/60'), "data-testid": "stepper-increment", children: jsx(PlusIcon, { className: ICON_SIZE_CLASS[size] }) })] }), (showErrorMessage && error) || helperText ? (jsx("div", { className: "flex items-center justify-between gap-2 mt-0.5", children: showErrorMessage && error ? (jsx(TextContent, { xsmall: true, className: "text-red-500 dark:text-red-400 font-medium", children: error })) : helperText ? (jsx(TextContent, { xsmall: true, muted: true, children: helperText })) : null })) : null] }));
2370
4094
  });
2371
4095
  QuantityStepper.displayName = 'QuantityStepper';
2372
4096
 
@@ -2412,7 +4136,7 @@ const SegmentedControl = forwardRef((props, ref) => {
2412
4136
  onChange(enabledOptions[enabledOptions.length - 1].value);
2413
4137
  }
2414
4138
  };
2415
- return (jsx("div", { ref: ref, role: "tablist", "aria-orientation": "horizontal", className: buildClassName('inline-flex items-center border border-gray-200 bg-gray-100/80 dark:border-gray-700 dark:bg-gray-800/80', SIZE_CONTAINER_CLASS[size], fullWidth ? 'w-full flex' : '', disabled ? 'opacity-60 cursor-not-allowed' : '', className), "data-testid": "segmented-control", ...restProps, children: options.map((option, index) => {
4139
+ return (jsx("div", { ref: ref, role: "tablist", "aria-orientation": "horizontal", className: buildClassName('inline-flex items-center border border-[var(--ui-border)] bg-gray-100/80 dark:bg-gray-800/80', SIZE_CONTAINER_CLASS[size], fullWidth ? 'w-full flex' : '', disabled ? 'opacity-60 cursor-not-allowed' : '', className), "data-testid": "segmented-control", ...restProps, children: options.map((option, index) => {
2416
4140
  const isSelected = value === option.value;
2417
4141
  const isOptionDisabled = disabled || option.disabled;
2418
4142
  return (jsxs("button", { type: "button", role: "tab", "aria-selected": isSelected, "aria-disabled": isOptionDisabled, tabIndex: isSelected && !isOptionDisabled ? 0 : -1, disabled: isOptionDisabled, title: option.title, onClick: () => {
@@ -2473,7 +4197,7 @@ const StickyActionBar = forwardRef((props, ref) => {
2473
4197
  : position === 'sticky'
2474
4198
  ? 'sticky bottom-0 z-30'
2475
4199
  : 'relative z-10';
2476
- return (jsxs(Fragment, { children: [jsx("div", { ref: ref, className: buildClassName(positionClass, 'border-t border-gray-200/80 bg-white/90 p-3.5 backdrop-blur-md shadow-lg dark:border-gray-800 dark:bg-gray-900/90 transition-all', className), "data-testid": "sticky-action-bar", ...restProps, children: jsxs("div", { className: buildClassName('mx-auto flex items-center justify-between gap-3', containerMaxWidth), children: [summaryContent && (jsx("div", { className: "flex items-center gap-2", children: drawerContent ? (jsxs("button", { type: "button", onClick: () => setIsDrawerOpen(true), className: "flex items-center gap-2 text-left transition-opacity hover:opacity-80 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-primary-ring)] rounded-lg p-1 -m-1", "aria-label": "Expand summary details", "data-testid": "summary-trigger", children: [jsx("div", { children: summaryContent }), jsx(ChevronUpIcon, { className: "size-4 text-[var(--ui-primary)] dark:text-blue-400 shrink-0" })] })) : (jsx("div", { children: summaryContent })) })), actionsContent && (jsx("div", { className: "flex items-center gap-2 shrink-0 ml-auto", "data-testid": "actions-stack", children: actionsContent }))] }) }), drawerContent && (jsx(Drawer, { isOpen: isDrawerOpen, onClose: () => setIsDrawerOpen(false), align: "bottom", size: "full", title: drawerTitle, showBackButton: true, contentClass: "px-4 pb-6 max-h-[calc(100svh-6rem)] overflow-y-auto", children: drawerContent }))] }));
4200
+ return (jsxs(Fragment, { children: [jsx("div", { ref: ref, className: buildClassName(positionClass, 'border-t border-[var(--ui-border)] bg-white/90 p-3.5 backdrop-blur-md shadow-lg dark:bg-gray-900/90 transition-all', className), "data-testid": "sticky-action-bar", ...restProps, children: jsxs("div", { className: buildClassName('mx-auto flex items-center justify-between gap-3', containerMaxWidth), children: [summaryContent && (jsx("div", { className: "flex items-center gap-2", children: drawerContent ? (jsxs("button", { type: "button", onClick: () => setIsDrawerOpen(true), className: "flex items-center gap-2 text-left transition-opacity hover:opacity-80 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-primary-ring)] rounded-lg p-1 -m-1", "aria-label": "Expand summary details", "data-testid": "summary-trigger", children: [jsx("div", { children: summaryContent }), jsx(ChevronUpIcon, { className: "size-4 text-[var(--ui-primary)] dark:text-blue-400 shrink-0" })] })) : (jsx("div", { children: summaryContent })) })), actionsContent && (jsx("div", { className: "flex items-center gap-2 shrink-0 ml-auto", "data-testid": "actions-stack", children: actionsContent }))] }) }), drawerContent && (jsx(Drawer, { isOpen: isDrawerOpen, onClose: () => setIsDrawerOpen(false), align: "bottom", size: "full", title: drawerTitle, showBackButton: true, contentClass: "px-4 pb-6 max-h-[calc(100svh-6rem)] overflow-y-auto", children: drawerContent }))] }));
2477
4201
  });
2478
4202
  StickyActionBar.displayName = 'StickyActionBar';
2479
4203
 
@@ -2503,7 +4227,7 @@ function buildTabClass({ selected, variant, stretch, isVertical, tabClass, }) {
2503
4227
  variantClass = isVertical
2504
4228
  ? buildClassName('px-3 py-2 w-full text-left border-l-2', selected
2505
4229
  ? 'border-[var(--ui-primary)] text-gray-900 dark:text-white'
2506
- : 'border-transparent text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600')
4230
+ : 'border-transparent text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:border-[var(--ui-border)]')
2507
4231
  : buildClassName('px-3 py-1.5 relative text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white', selected &&
2508
4232
  'text-gray-900 dark:text-white after:absolute after:z-10 after:left-0 after:right-0 after:-bottom-1 after:h-0.5 after:bg-[var(--ui-primary)]');
2509
4233
  break;
@@ -2521,6 +4245,89 @@ function buildTabClass({ selected, variant, stretch, isVertical, tabClass, }) {
2521
4245
  return buildClassName(base, variantClass, tabClass);
2522
4246
  }
2523
4247
 
4248
+ function SwipeableTabs({ items, activeId: externalActiveId, defaultActiveId, onChange, swipeable = true, threshold = 50, headerVariant = 'default', containerClass = '', headerClass = '', contentClass = '', }) {
4249
+ var _a;
4250
+ const [internalActiveId, setInternalActiveId] = useState(defaultActiveId || ((_a = items[0]) === null || _a === void 0 ? void 0 : _a.id) || '');
4251
+ const activeId = externalActiveId !== undefined ? externalActiveId : internalActiveId;
4252
+ const activeIndex = Math.max(0, items.findIndex((item) => item.id === activeId));
4253
+ const touchStartX = useRef(0);
4254
+ const touchStartY = useRef(0);
4255
+ const touchDeltaX = useRef(0);
4256
+ const isSwipingHorizontal = useRef(null);
4257
+ const handleTabChange = (item) => {
4258
+ if (item.disabled)
4259
+ return;
4260
+ setInternalActiveId(item.id);
4261
+ onChange === null || onChange === void 0 ? void 0 : onChange(item.id);
4262
+ };
4263
+ const handleTouchStart = (e) => {
4264
+ if (!swipeable)
4265
+ return;
4266
+ touchStartX.current = e.touches[0].clientX;
4267
+ touchStartY.current = e.touches[0].clientY;
4268
+ touchDeltaX.current = 0;
4269
+ isSwipingHorizontal.current = null;
4270
+ };
4271
+ const handleTouchMove = (e) => {
4272
+ if (!swipeable)
4273
+ return;
4274
+ const currentX = e.touches[0].clientX;
4275
+ const currentY = e.touches[0].clientY;
4276
+ const deltaX = currentX - touchStartX.current;
4277
+ const deltaY = currentY - touchStartY.current;
4278
+ if (isSwipingHorizontal.current === null) {
4279
+ if (Math.abs(deltaX) > 8 || Math.abs(deltaY) > 8) {
4280
+ isSwipingHorizontal.current = Math.abs(deltaX) > Math.abs(deltaY);
4281
+ }
4282
+ }
4283
+ if (isSwipingHorizontal.current) {
4284
+ touchDeltaX.current = deltaX;
4285
+ }
4286
+ };
4287
+ const handleTouchEnd = () => {
4288
+ if (!swipeable || !isSwipingHorizontal.current)
4289
+ return;
4290
+ const deltaX = touchDeltaX.current;
4291
+ if (Math.abs(deltaX) >= threshold) {
4292
+ if (deltaX < 0 && activeIndex < items.length - 1) {
4293
+ // Swiped Left -> Go to Next Tab
4294
+ const nextItem = items[activeIndex + 1];
4295
+ if (nextItem && !nextItem.disabled) {
4296
+ handleTabChange(nextItem);
4297
+ }
4298
+ }
4299
+ else if (deltaX > 0 && activeIndex > 0) {
4300
+ // Swiped Right -> Go to Previous Tab
4301
+ const prevItem = items[activeIndex - 1];
4302
+ if (prevItem && !prevItem.disabled) {
4303
+ handleTabChange(prevItem);
4304
+ }
4305
+ }
4306
+ }
4307
+ touchDeltaX.current = 0;
4308
+ isSwipingHorizontal.current = null;
4309
+ };
4310
+ return (jsxs("div", { className: buildClassName('w-full flex flex-col', containerClass), "data-testid": "swipeable-tabs", children: [jsx("div", { className: buildClassName('w-full flex items-center gap-1 border-b border-[var(--ui-border)] overflow-x-auto no-scrollbar select-none', headerVariant === 'segmented' &&
4311
+ 'p-1 bg-gray-100 dark:bg-gray-800/80 rounded-2xl border-none gap-0', headerClass), "data-testid": "swipeable-tabs-header", children: items.map((item) => {
4312
+ const isActive = item.id === activeId;
4313
+ if (headerVariant === 'segmented') {
4314
+ return (jsxs("button", { type: "button", disabled: item.disabled, onClick: () => handleTabChange(item), className: buildClassName('flex-1 flex items-center justify-center gap-1.5 py-1.5 px-3 rounded-xl text-xs font-semibold transition-all duration-150 cursor-pointer', item.disabled && 'opacity-40 cursor-not-allowed pointer-events-none', isActive
4315
+ ? 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow-xs'
4316
+ : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white'), "data-testid": `swipeable-tab-btn-${item.id}`, children: [item.icon && jsx("span", { className: "text-sm", children: item.icon }), jsx("span", { children: item.label }), item.badge !== undefined && (jsx("span", { className: "px-1.5 py-0.5 text-[10px] rounded-full bg-blue-100 dark:bg-blue-950 text-blue-600 dark:text-blue-400 font-bold", children: item.badge }))] }, item.id));
4317
+ }
4318
+ if (headerVariant === 'pills') {
4319
+ return (jsxs("button", { type: "button", disabled: item.disabled, onClick: () => handleTabChange(item), className: buildClassName('flex items-center justify-center gap-1.5 py-1.5 px-3.5 rounded-full text-xs font-semibold transition-all duration-150 cursor-pointer whitespace-nowrap', item.disabled && 'opacity-40 cursor-not-allowed pointer-events-none', isActive
4320
+ ? 'bg-blue-600 text-white shadow-xs'
4321
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700'), "data-testid": `swipeable-tab-btn-${item.id}`, children: [item.icon && jsx("span", { className: "text-sm", children: item.icon }), jsx("span", { children: item.label }), item.badge !== undefined && (jsx("span", { className: "px-1.5 py-0.5 text-[10px] rounded-full bg-white/20 text-current font-bold", children: item.badge }))] }, item.id));
4322
+ }
4323
+ // Default Underline Tab Header
4324
+ return (jsxs("button", { type: "button", disabled: item.disabled, onClick: () => handleTabChange(item), className: buildClassName('flex items-center justify-center gap-1.5 py-2.5 px-4 text-xs font-semibold transition-all duration-150 cursor-pointer relative whitespace-nowrap border-b-2 -mb-px', item.disabled && 'opacity-40 cursor-not-allowed pointer-events-none', isActive
4325
+ ? 'border-blue-600 dark:border-blue-400 text-blue-600 dark:text-blue-400'
4326
+ : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white'), "data-testid": `swipeable-tab-btn-${item.id}`, children: [item.icon && jsx("span", { className: "text-sm", children: item.icon }), jsx("span", { children: item.label }), item.badge !== undefined && (jsx("span", { className: "px-1.5 py-0.5 text-[10px] rounded-full bg-blue-100 dark:bg-blue-950 text-blue-600 dark:text-blue-400 font-bold", children: item.badge }))] }, item.id));
4327
+ }) }), jsx("div", { className: buildClassName('w-full overflow-hidden relative touch-pan-y', contentClass), onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, "data-testid": "swipeable-tabs-viewport", children: jsx("div", { className: "flex w-full transition-transform duration-300 ease-out", style: { transform: `translateX(-${activeIndex * 100}%)` }, "data-testid": "swipeable-tabs-track", children: items.map((item) => (jsx("div", { className: "w-full shrink-0 min-w-full", "data-testid": `swipeable-tab-panel-${item.id}`, children: item.content }, item.id))) }) })] }));
4328
+ }
4329
+ SwipeableTabs.displayName = 'SwipeableTabs';
4330
+
2524
4331
  const sizeClasses = {
2525
4332
  sm: {
2526
4333
  textarea: 'px-2.5 py-1.5 text-xs leading-5 min-h-[60px]',
@@ -2568,7 +4375,7 @@ const Textarea = forwardRef((props, ref) => {
2568
4375
  const currentSize = sizeClasses[size] || sizeClasses.md;
2569
4376
  return (jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxs("div", { className: "relative", children: [hasLeftGroup && (jsx("span", { className: "absolute top-2.5 left-3 flex items-center justify-center text-gray-400 dark:text-gray-500", children: leftGroup })), jsx("textarea", { ref: innerRef, autoComplete: "off", ...inputProps, value: value, defaultValue: defaultValue, onChange: handleTextareaChange, maxLength: maxLength, name: name, id: id, className: buildClassName('transition-all duration-150', 'block w-full rounded-lg bg-white', currentSize.textarea, autoSize ? 'resize-none overflow-hidden' : resizeClasses[resize], 'text-gray-900 outline outline-1 -outline-offset-1', hasError
2570
4377
  ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
2571
- : 'outline-gray-300 dark:outline-gray-600', 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', 'dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 placeholder:text-gray-400 dark:text-white', 'disabled:pointer-events-none disabled:bg-gray-100 disabled:outline-gray-200', 'dark:disabled:bg-gray-800 dark:disabled:text-gray-600 dark:disabled:placeholder-gray-600 dark:disabled:outline-gray-700', hasRightGroup ? 'pe-10' : '', hasLeftGroup ? 'ps-10' : '', className) }), hasRightGroup && (jsx("span", { className: "absolute end-3 top-2.5 flex items-center justify-center text-gray-400 dark:text-gray-500", children: rightGroup }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
4378
+ : 'outline-[var(--ui-border)]', 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', 'dark:bg-gray-700 dark:placeholder-gray-400 placeholder:text-gray-400 dark:text-white', 'disabled:pointer-events-none disabled:bg-gray-100 disabled:outline-[var(--ui-border-muted)]', 'dark:disabled:bg-gray-800 dark:disabled:text-gray-600 dark:disabled:placeholder-gray-600 dark:disabled:outline-[var(--ui-border-muted)]', hasRightGroup ? 'pe-10' : '', hasLeftGroup ? 'ps-10' : '', className) }), hasRightGroup && (jsx("span", { className: "absolute end-3 top-2.5 flex items-center justify-center text-gray-400 dark:text-gray-500", children: rightGroup }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
2572
4379
  ? 'text-red-500 font-semibold'
2573
4380
  : 'text-gray-400 dark:text-gray-500'), children: [charLength, maxLength ? ` / ${maxLength}` : ''] }))] })) : null] }));
2574
4381
  });
@@ -2603,10 +4410,10 @@ const progressBarColorMap = {
2603
4410
  };
2604
4411
  const variantStyleMap = {
2605
4412
  accent: {
2606
- success: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-success)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-gray-200/80 dark:border-gray-800/80',
2607
- error: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-danger)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-gray-200/80 dark:border-gray-800/80',
2608
- info: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-info)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-gray-200/80 dark:border-gray-800/80',
2609
- warning: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-warning)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-gray-200/80 dark:border-gray-800/80',
4413
+ success: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-success)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-[var(--ui-border)]',
4414
+ error: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-danger)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-[var(--ui-border)]',
4415
+ info: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-info)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-[var(--ui-border)]',
4416
+ warning: 'bg-white dark:bg-gray-900 border-l-4 border-[var(--ui-warning)] text-gray-900 dark:text-gray-100 shadow-lg border-y border-r border-[var(--ui-border)]',
2610
4417
  },
2611
4418
  filled: {
2612
4419
  success: 'bg-[var(--ui-success)] text-white shadow-lg',
@@ -2946,7 +4753,10 @@ const useIsMobile = () => {
2946
4753
  useEffect(() => {
2947
4754
  const detect = () => {
2948
4755
  const width = window.innerWidth;
2949
- const isTouch = navigator.maxTouchPoints > 1 || window.matchMedia('(pointer: coarse)').matches;
4756
+ const isTouch = (typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1) ||
4757
+ (typeof window !== 'undefined' &&
4758
+ typeof window.matchMedia === 'function' &&
4759
+ window.matchMedia('(pointer: coarse)').matches);
2950
4760
  setIsMobile(width < 600 && isTouch);
2951
4761
  };
2952
4762
  detect();
@@ -2977,5 +4787,5 @@ const useIsTabletOrMobile = () => {
2977
4787
  return isMobile || isTablet;
2978
4788
  };
2979
4789
 
2980
- export { Accordion, Alert, Badge, Banner, BodyText, Breadcrumb, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardMedia, CardTitle, Checkbox, CheckboxGroup, DOTS, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, HeadingText, Input, Label, Loader, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, QuantityStepper, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SegmentedControl, SelectBox, Skeleton, SortIconMap, StatusPill, StickyActionBar, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, buildClassName, buildInputClass, evaluatePasswordStrength, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useRowSelection, useToast };
4790
+ export { Accordion, ActionSheet, Alert, Badge, Banner, BodyText, BottomNavigation, Breadcrumb, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardMedia, CardTitle, Checkbox, CheckboxGroup, DOTS, DataList, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, Flex, FlexItem, FloatingActionButton, Grid, GridCol, HeadingText, Input, Label, Loader, MobileHeader, MobilePicker, MobileStepper, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, PinInput, PullToRefresh, QuantityStepper, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SegmentedControl, SelectBox, Skeleton, SortIconMap, StatusPill, StickyActionBar, SwipeableRow, SwipeableTabs, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, WheelPicker, buildClassName, buildInputClass, evaluatePasswordStrength, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useRowSelection, useToast };
2981
4791
  //# sourceMappingURL=react-tailwind.es.js.map