@pk-design/react-tailwind 1.6.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -27,10 +27,10 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
27
27
 
28
28
  const buildClassName = (...classes) => tailwindMerge.twMerge(classes.filter(Boolean));
29
29
 
30
- var _path$i;
31
- 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); }
30
+ var _path$j;
31
+ 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); }
32
32
  var SvgChevronDown = function SvgChevronDown(props) {
33
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$i({
33
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$j({
34
34
  xmlns: "http://www.w3.org/2000/svg",
35
35
  width: 24,
36
36
  height: 24,
@@ -41,19 +41,19 @@ var SvgChevronDown = function SvgChevronDown(props) {
41
41
  strokeWidth: 2,
42
42
  className: "lucide lucide-chevron-down-icon lucide-chevron-down",
43
43
  viewBox: "0 0 24 24"
44
- }, props), _path$i || (_path$i = /*#__PURE__*/React__namespace.createElement("path", {
44
+ }, props), _path$j || (_path$j = /*#__PURE__*/React__namespace.createElement("path", {
45
45
  d: "m6 9 6 6 6-6"
46
46
  })));
47
47
  };
48
48
 
49
49
  const CONTAINER_CLASS = {
50
- 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',
50
+ bordered: 'rounded-lg border border-[var(--ui-border)] divide-y divide-[var(--ui-border)] bg-white dark:bg-gray-800 overflow-hidden',
51
51
  separated: 'space-y-2',
52
- plain: 'divide-y divide-gray-200 dark:divide-white/10',
52
+ plain: 'divide-y divide-[var(--ui-border)]',
53
53
  };
54
54
  const ITEM_CLASS = {
55
55
  bordered: '',
56
- separated: 'rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-gray-800 overflow-hidden',
56
+ separated: 'rounded-lg border border-[var(--ui-border)] bg-white dark:bg-gray-800 overflow-hidden',
57
57
  plain: '',
58
58
  };
59
59
  const HEADER_CLASS = 'flex w-full items-center justify-between gap-2 py-3 px-4 text-left text-sm font-medium ' +
@@ -98,115 +98,6 @@ const Accordion = ({ items, type = 'single', variant = 'bordered', collapsible =
98
98
  };
99
99
  Accordion.displayName = 'Accordion';
100
100
 
101
- var _path$h, _path2;
102
- 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); }
103
- var SvgBadgeCheck = function SvgBadgeCheck(props) {
104
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$h({
105
- xmlns: "http://www.w3.org/2000/svg",
106
- width: 24,
107
- height: 24,
108
- fill: "none",
109
- stroke: "currentColor",
110
- strokeLinecap: "round",
111
- strokeLinejoin: "round",
112
- strokeWidth: 2,
113
- className: "lucide lucide-badge-check-icon lucide-badge-check",
114
- viewBox: "0 0 24 24"
115
- }, props), _path$h || (_path$h = /*#__PURE__*/React__namespace.createElement("path", {
116
- 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"
117
- })), _path2 || (_path2 = /*#__PURE__*/React__namespace.createElement("path", {
118
- d: "m9 12 2 2 4-4"
119
- })));
120
- };
121
-
122
- var _circle$4, _path$g;
123
- 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); }
124
- var SvgCircleX = function SvgCircleX(props) {
125
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$g({
126
- xmlns: "http://www.w3.org/2000/svg",
127
- width: 24,
128
- height: 24,
129
- fill: "none",
130
- stroke: "currentColor",
131
- strokeLinecap: "round",
132
- strokeLinejoin: "round",
133
- strokeWidth: 2,
134
- className: "lucide lucide-circle-x-icon lucide-circle-x",
135
- viewBox: "0 0 24 24"
136
- }, props), _circle$4 || (_circle$4 = /*#__PURE__*/React__namespace.createElement("circle", {
137
- cx: 12,
138
- cy: 12,
139
- r: 10
140
- })), _path$g || (_path$g = /*#__PURE__*/React__namespace.createElement("path", {
141
- d: "m15 9-6 6M9 9l6 6"
142
- })));
143
- };
144
-
145
- var _circle$3, _path$f;
146
- 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); }
147
- var SvgCircleAlert = function SvgCircleAlert(props) {
148
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$f({
149
- xmlns: "http://www.w3.org/2000/svg",
150
- width: 24,
151
- height: 24,
152
- fill: "none",
153
- stroke: "currentColor",
154
- strokeLinecap: "round",
155
- strokeLinejoin: "round",
156
- strokeWidth: 2,
157
- className: "lucide lucide-circle-alert-icon lucide-circle-alert",
158
- viewBox: "0 0 24 24"
159
- }, props), _circle$3 || (_circle$3 = /*#__PURE__*/React__namespace.createElement("circle", {
160
- cx: 12,
161
- cy: 12,
162
- r: 10
163
- })), _path$f || (_path$f = /*#__PURE__*/React__namespace.createElement("path", {
164
- d: "M12 8v4M12 16h.01"
165
- })));
166
- };
167
-
168
- var _circle$2, _path$e;
169
- 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); }
170
- var SvgInfo = function SvgInfo(props) {
171
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$e({
172
- xmlns: "http://www.w3.org/2000/svg",
173
- width: 24,
174
- height: 24,
175
- fill: "none",
176
- stroke: "currentColor",
177
- strokeLinecap: "round",
178
- strokeLinejoin: "round",
179
- strokeWidth: 2,
180
- className: "lucide lucide-info-icon lucide-info",
181
- viewBox: "0 0 24 24"
182
- }, props), _circle$2 || (_circle$2 = /*#__PURE__*/React__namespace.createElement("circle", {
183
- cx: 12,
184
- cy: 12,
185
- r: 10
186
- })), _path$e || (_path$e = /*#__PURE__*/React__namespace.createElement("path", {
187
- d: "M12 16v-4M12 8h.01"
188
- })));
189
- };
190
-
191
- var _path$d;
192
- 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); }
193
- var SvgX = function SvgX(props) {
194
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$d({
195
- xmlns: "http://www.w3.org/2000/svg",
196
- width: 24,
197
- height: 24,
198
- fill: "none",
199
- stroke: "currentColor",
200
- strokeLinecap: "round",
201
- strokeLinejoin: "round",
202
- strokeWidth: 2,
203
- className: "lucide lucide-x-icon lucide-x",
204
- viewBox: "0 0 24 24"
205
- }, props), _path$d || (_path$d = /*#__PURE__*/React__namespace.createElement("path", {
206
- d: "M18 6 6 18M6 6l12 12"
207
- })));
208
- };
209
-
210
101
  const loaderSizeMap = {
211
102
  xs: 'size-4',
212
103
  sm: 'size-6',
@@ -273,8 +164,8 @@ const THEMED_BTN_CLASS = {
273
164
  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)]',
274
165
  },
275
166
  secondary: {
276
- 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',
277
- 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',
167
+ 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',
168
+ 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)]',
278
169
  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',
279
170
  },
280
171
  success: {
@@ -366,52 +257,132 @@ const Button = React.forwardRef(({ as, type, ...props }, ref) => {
366
257
  });
367
258
  Button.displayName = 'Button';
368
259
 
369
- const AlertTypeIconMap = {
370
- success: SvgBadgeCheck,
371
- danger: SvgCircleX,
372
- warning: SvgCircleAlert,
373
- info: SvgInfo,
260
+ var _path$i;
261
+ 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); }
262
+ var SvgChevronLeft = function SvgChevronLeft(props) {
263
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$i({
264
+ xmlns: "http://www.w3.org/2000/svg",
265
+ width: 24,
266
+ height: 24,
267
+ fill: "none",
268
+ stroke: "currentColor",
269
+ strokeLinecap: "round",
270
+ strokeLinejoin: "round",
271
+ strokeWidth: 2,
272
+ className: "lucide lucide-chevron-left-icon lucide-chevron-left",
273
+ viewBox: "0 0 24 24"
274
+ }, props), _path$i || (_path$i = /*#__PURE__*/React__namespace.createElement("path", {
275
+ d: "m15 18-6-6 6-6"
276
+ })));
374
277
  };
375
- const TypeClassMap$1 = {
376
- success: 'bg-[var(--ui-success-light)] ring-[var(--ui-success-ring-subtle)] text-[var(--ui-success-text)]',
377
- danger: 'bg-[var(--ui-danger-light)] ring-[var(--ui-danger-ring-subtle)] text-[var(--ui-danger-text)]',
378
- warning: 'bg-[var(--ui-warning-light)] ring-[var(--ui-warning-ring-subtle)] text-[var(--ui-warning-text)]',
379
- info: 'bg-[var(--ui-info-light)] ring-[var(--ui-info-ring-subtle)] text-[var(--ui-info-text)]',
278
+
279
+ var _path$h;
280
+ 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); }
281
+ var SvgX = function SvgX(props) {
282
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$h({
283
+ xmlns: "http://www.w3.org/2000/svg",
284
+ width: 24,
285
+ height: 24,
286
+ fill: "none",
287
+ stroke: "currentColor",
288
+ strokeLinecap: "round",
289
+ strokeLinejoin: "round",
290
+ strokeWidth: 2,
291
+ className: "lucide lucide-x-icon lucide-x",
292
+ viewBox: "0 0 24 24"
293
+ }, props), _path$h || (_path$h = /*#__PURE__*/React__namespace.createElement("path", {
294
+ d: "M18 6 6 18M6 6l12 12"
295
+ })));
380
296
  };
381
- const Alert = React.forwardRef((props, ref) => {
382
- const { type = 'info', className, message, children, removable = false, onRemove, icon, title, ...restProps } = props;
383
- const DefaultIcon = AlertTypeIconMap[type] || SvgInfo;
384
- const iconNode = icon !== undefined ? (icon) : (jsxRuntime.jsx(DefaultIcon, { className: "size-5 shrink-0", "data-testid": `alert-${type}-icon` }));
385
- return (jsxRuntime.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: [jsxRuntime.jsxs("span", { className: "inline-flex items-start gap-2 min-w-0", children: [iconNode && jsxRuntime.jsx("span", { className: "shrink-0 inline-flex mt-0.5", children: iconNode }), jsxRuntime.jsxs("span", { className: "inline-flex flex-col gap-0.5 min-w-0", children: [title && jsxRuntime.jsx("span", { className: "font-semibold", children: title }), jsxRuntime.jsx("span", { className: "inline-flex items-center", children: message !== null && message !== void 0 ? message : children })] })] }), removable && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4.5", "data-testid": "alert-remove-icon" }) }))] }));
386
- });
387
- Alert.displayName = 'Alert';
388
297
 
389
- const ThemeClassMap = {
390
- success: 'bg-[var(--ui-success-light)] text-[var(--ui-success-text)] ring-[var(--ui-success-ring-subtle)]',
391
- danger: 'bg-[var(--ui-danger-light)] text-[var(--ui-danger-text)] ring-[var(--ui-danger-ring-subtle)]',
392
- warning: 'bg-[var(--ui-warning-light)] text-[var(--ui-warning-text)] ring-[var(--ui-warning-ring-subtle)]',
393
- info: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
394
- secondary: 'bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 ring-[var(--ui-secondary-ring-subtle)]',
298
+ const alignmentMap = {
299
+ center: 'items-center justify-center h-full',
300
+ start: 'justify-start h-full',
301
+ end: 'justify-end h-full',
302
+ top: 'items-start justify-center w-full',
303
+ bottom: 'items-end justify-center h-full',
395
304
  };
396
- const SIZE_CLASS$1 = {
397
- sm: 'text-xs py-0.5 px-2',
398
- md: 'text-xs py-1 px-3',
305
+ const panelAlignmentMap = {
306
+ center: 'data-[closed]:scale-95 rounded-2xl',
307
+ start: 'data-[closed]:-translate-x-1/2 rounded-r-2xl',
308
+ end: 'data-[closed]:translate-x-1/2 rounded-l-2xl',
309
+ top: 'data-[closed]:-translate-y-1/2 rounded-b-2xl',
310
+ bottom: 'data-[closed]:translate-y-full rounded-t-2xl md:rounded-t-3xl max-h-[88vh] max-h-[88dvh]',
399
311
  };
400
- const Badge = React.forwardRef((props, ref) => {
401
- const { theme = 'info', className, children, removable = false, rounded = false, onRemove, size = 'md', icon, ...restProps } = props;
402
- return (jsxRuntime.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 && jsxRuntime.jsx("span", { className: "shrink-0 inline-flex", children: icon }), children, removable && (jsxRuntime.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) => {
403
- if (e.key === 'Enter' || e.key === ' ') {
404
- e.preventDefault();
405
- onRemove === null || onRemove === void 0 ? void 0 : onRemove();
406
- }
407
- } }))] }));
408
- });
409
- Badge.displayName = 'Badge';
312
+ const panelSizeMap = {
313
+ xs: 'max-w-xs',
314
+ sm: 'max-w-sm',
315
+ md: 'max-w-md',
316
+ lg: 'max-w-lg',
317
+ xl: 'max-w-xl',
318
+ '2xl': 'max-w-2xl',
319
+ full: 'w-full',
320
+ };
321
+ 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, }) => {
322
+ const showTitleSection = Boolean(title || description || showBackButton || showCloseButton);
323
+ const shouldShowDragHandle = dragHandle !== null && dragHandle !== void 0 ? dragHandle : align === 'bottom';
324
+ const [viewportHeight, setViewportHeight] = React.useState(null);
325
+ React.useEffect(() => {
326
+ if (!isOpen) {
327
+ setViewportHeight(null);
328
+ return;
329
+ }
330
+ const updateHeight = () => {
331
+ if (typeof window !== 'undefined' && window.visualViewport) {
332
+ setViewportHeight(window.visualViewport.height);
333
+ }
334
+ };
335
+ updateHeight();
336
+ const vv = typeof window !== 'undefined' ? window.visualViewport : null;
337
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('resize', updateHeight);
338
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('scroll', updateHeight);
339
+ return () => {
340
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('resize', updateHeight);
341
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('scroll', updateHeight);
342
+ };
343
+ }, [isOpen]);
344
+ const handleDialogClose = () => {
345
+ if (closeOnOutsideClick) {
346
+ onClose === null || onClose === void 0 ? void 0 : onClose();
347
+ }
348
+ };
349
+ return (jsxRuntime.jsxs(react.Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: handleDialogClose, transition: true, children: [backdrop && (jsxRuntime.jsx(react.DialogBackdrop, { className: "fixed inset-0 bg-black/40 backdrop-blur-xs transition-opacity duration-200" })), jsxRuntime.jsx("div", { className: "fixed left-0 top-0 w-full", style: { height: viewportHeight ? `${viewportHeight}px` : '100dvh' }, children: jsxRuntime.jsx("div", { className: buildClassName('flex', alignmentMap[align]), children: jsxRuntime.jsxs(react.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 && (jsxRuntime.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 && (jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [showBackButton && (jsxRuntime.jsx(Button, { iconOnly: true, "aria-label": "Back", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, children: jsxRuntime.jsx(SvgChevronLeft, { className: "size-4" }) })), title && (jsxRuntime.jsx(react.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 && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4" }) }))] }), description && (jsxRuntime.jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal truncate', descriptionClass), children: description }))] })), jsxRuntime.jsx("div", { className: buildClassName('flex-1 p-4 md:p-6 space-y-4 min-w-0', contentClass), children: children }), footer && (jsxRuntime.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 }))] }) }) })] }));
350
+ };
351
+ Drawer.displayName = 'Drawer';
410
352
 
411
- var _path$c;
412
- 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); }
413
- var SvgTriangleAlert = function SvgTriangleAlert(props) {
414
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$c({
353
+ function ActionSheet({ isOpen, onClose, title, description, actions, showCancelButton = true, cancelLabel = 'Cancel', onCancel, closeOnBackdropClick = true, dragHandle = true, panelClass = '', containerClass = '', }) {
354
+ const handleItemClick = (action) => {
355
+ var _a;
356
+ if (action.disabled)
357
+ return;
358
+ (_a = action.onClick) === null || _a === void 0 ? void 0 : _a.call(action);
359
+ onClose();
360
+ };
361
+ const handleCancelClick = () => {
362
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
363
+ onClose();
364
+ };
365
+ return (jsxRuntime.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: jsxRuntime.jsxs("div", { className: buildClassName('space-y-4 py-1', containerClass), "data-testid": "action-sheet", children: [(title || description) && (jsxRuntime.jsxs("div", { className: "text-center px-4 pb-2 border-b border-[var(--ui-border-muted)]", children: [title && (jsxRuntime.jsx("h3", { className: "text-sm font-bold text-gray-900 dark:text-white truncate", children: title })), description && (jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate", children: description }))] })), jsxRuntime.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) => {
366
+ const isDanger = action.theme === 'danger';
367
+ const isPrimary = action.theme === 'primary';
368
+ return (jsxRuntime.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 &&
369
+ (isDanger
370
+ ? 'hover:bg-red-50 dark:hover:bg-red-950/40 text-red-600 dark:text-red-400 font-semibold'
371
+ : isPrimary
372
+ ? 'hover:bg-blue-50 dark:hover:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
373
+ : '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 && (jsxRuntime.jsx("span", { className: buildClassName('shrink-0 text-base transition-colors', isDanger
374
+ ? 'text-red-500 dark:text-red-400'
375
+ : isPrimary
376
+ ? 'text-blue-500 dark:text-blue-400'
377
+ : 'text-gray-500 dark:text-gray-400 group-hover:text-gray-700 dark:group-hover:text-gray-200'), children: action.icon })), jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [jsxRuntime.jsx("div", { className: "text-sm truncate", children: action.label }), action.description && (jsxRuntime.jsx("div", { className: "text-xs text-gray-400 dark:text-gray-500 truncate font-normal mt-0.5", children: action.description }))] })] }, action.id));
378
+ }) }), showCancelButton && (jsxRuntime.jsx("div", { className: "pt-1", children: jsxRuntime.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 }) }))] }) }));
379
+ }
380
+ ActionSheet.displayName = 'ActionSheet';
381
+
382
+ var _path$g, _path2;
383
+ 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); }
384
+ var SvgBadgeCheck = function SvgBadgeCheck(props) {
385
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$g({
415
386
  xmlns: "http://www.w3.org/2000/svg",
416
387
  width: 24,
417
388
  height: 24,
@@ -420,17 +391,19 @@ var SvgTriangleAlert = function SvgTriangleAlert(props) {
420
391
  strokeLinecap: "round",
421
392
  strokeLinejoin: "round",
422
393
  strokeWidth: 2,
423
- className: "lucide lucide-triangle-alert-icon lucide-triangle-alert",
394
+ className: "lucide lucide-badge-check-icon lucide-badge-check",
424
395
  viewBox: "0 0 24 24"
425
- }, props), _path$c || (_path$c = /*#__PURE__*/React__namespace.createElement("path", {
426
- 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"
396
+ }, props), _path$g || (_path$g = /*#__PURE__*/React__namespace.createElement("path", {
397
+ 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"
398
+ })), _path2 || (_path2 = /*#__PURE__*/React__namespace.createElement("path", {
399
+ d: "m9 12 2 2 4-4"
427
400
  })));
428
401
  };
429
402
 
430
- var _circle$1, _path$b;
431
- 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); }
432
- var SvgCircleCheck = function SvgCircleCheck(props) {
433
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$b({
403
+ var _circle$5, _path$f;
404
+ 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); }
405
+ var SvgCircleX = function SvgCircleX(props) {
406
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$f({
434
407
  xmlns: "http://www.w3.org/2000/svg",
435
408
  width: 24,
436
409
  height: 24,
@@ -439,28 +412,159 @@ var SvgCircleCheck = function SvgCircleCheck(props) {
439
412
  strokeLinecap: "round",
440
413
  strokeLinejoin: "round",
441
414
  strokeWidth: 2,
442
- className: "lucide lucide-circle-check-icon lucide-circle-check",
415
+ className: "lucide lucide-circle-x-icon lucide-circle-x",
443
416
  viewBox: "0 0 24 24"
444
- }, props), _circle$1 || (_circle$1 = /*#__PURE__*/React__namespace.createElement("circle", {
417
+ }, props), _circle$5 || (_circle$5 = /*#__PURE__*/React__namespace.createElement("circle", {
445
418
  cx: 12,
446
419
  cy: 12,
447
420
  r: 10
448
- })), _path$b || (_path$b = /*#__PURE__*/React__namespace.createElement("path", {
449
- d: "m9 12 2 2 4-4"
421
+ })), _path$f || (_path$f = /*#__PURE__*/React__namespace.createElement("path", {
422
+ d: "m15 9-6 6M9 9l6 6"
450
423
  })));
451
424
  };
452
425
 
453
- const sizeMap = {
454
- xs: 'size-4',
455
- sm: 'size-5',
456
- md: 'size-6',
457
- lg: 'size-8',
458
- xl: 'size-10',
459
- };
460
- const IconMap = {
461
- info: SvgInfo,
462
- error: SvgCircleX,
463
- success: SvgCircleCheck,
426
+ var _circle$4, _path$e;
427
+ 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); }
428
+ var SvgCircleAlert = function SvgCircleAlert(props) {
429
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$e({
430
+ xmlns: "http://www.w3.org/2000/svg",
431
+ width: 24,
432
+ height: 24,
433
+ fill: "none",
434
+ stroke: "currentColor",
435
+ strokeLinecap: "round",
436
+ strokeLinejoin: "round",
437
+ strokeWidth: 2,
438
+ className: "lucide lucide-circle-alert-icon lucide-circle-alert",
439
+ viewBox: "0 0 24 24"
440
+ }, props), _circle$4 || (_circle$4 = /*#__PURE__*/React__namespace.createElement("circle", {
441
+ cx: 12,
442
+ cy: 12,
443
+ r: 10
444
+ })), _path$e || (_path$e = /*#__PURE__*/React__namespace.createElement("path", {
445
+ d: "M12 8v4M12 16h.01"
446
+ })));
447
+ };
448
+
449
+ var _circle$3, _path$d;
450
+ 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); }
451
+ var SvgInfo = function SvgInfo(props) {
452
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$d({
453
+ xmlns: "http://www.w3.org/2000/svg",
454
+ width: 24,
455
+ height: 24,
456
+ fill: "none",
457
+ stroke: "currentColor",
458
+ strokeLinecap: "round",
459
+ strokeLinejoin: "round",
460
+ strokeWidth: 2,
461
+ className: "lucide lucide-info-icon lucide-info",
462
+ viewBox: "0 0 24 24"
463
+ }, props), _circle$3 || (_circle$3 = /*#__PURE__*/React__namespace.createElement("circle", {
464
+ cx: 12,
465
+ cy: 12,
466
+ r: 10
467
+ })), _path$d || (_path$d = /*#__PURE__*/React__namespace.createElement("path", {
468
+ d: "M12 16v-4M12 8h.01"
469
+ })));
470
+ };
471
+
472
+ const AlertTypeIconMap = {
473
+ success: SvgBadgeCheck,
474
+ danger: SvgCircleX,
475
+ warning: SvgCircleAlert,
476
+ info: SvgInfo,
477
+ };
478
+ const TypeClassMap$1 = {
479
+ success: 'bg-[var(--ui-success-light)] ring-[var(--ui-success-ring-subtle)] text-[var(--ui-success-text)]',
480
+ danger: 'bg-[var(--ui-danger-light)] ring-[var(--ui-danger-ring-subtle)] text-[var(--ui-danger-text)]',
481
+ warning: 'bg-[var(--ui-warning-light)] ring-[var(--ui-warning-ring-subtle)] text-[var(--ui-warning-text)]',
482
+ info: 'bg-[var(--ui-info-light)] ring-[var(--ui-info-ring-subtle)] text-[var(--ui-info-text)]',
483
+ };
484
+ const Alert = React.forwardRef((props, ref) => {
485
+ const { type = 'info', className, message, children, removable = false, onRemove, icon, title, ...restProps } = props;
486
+ const DefaultIcon = AlertTypeIconMap[type] || SvgInfo;
487
+ const iconNode = icon !== undefined ? (icon) : (jsxRuntime.jsx(DefaultIcon, { className: "size-5 shrink-0", "data-testid": `alert-${type}-icon` }));
488
+ return (jsxRuntime.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: [jsxRuntime.jsxs("span", { className: "inline-flex items-start gap-2 min-w-0", children: [iconNode && jsxRuntime.jsx("span", { className: "shrink-0 inline-flex mt-0.5", children: iconNode }), jsxRuntime.jsxs("span", { className: "inline-flex flex-col gap-0.5 min-w-0", children: [title && jsxRuntime.jsx("span", { className: "font-semibold", children: title }), jsxRuntime.jsx("span", { className: "inline-flex items-center", children: message !== null && message !== void 0 ? message : children })] })] }), removable && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4.5", "data-testid": "alert-remove-icon" }) }))] }));
489
+ });
490
+ Alert.displayName = 'Alert';
491
+
492
+ const ThemeClassMap = {
493
+ success: 'bg-[var(--ui-success-light)] text-[var(--ui-success-text)] ring-[var(--ui-success-ring-subtle)]',
494
+ danger: 'bg-[var(--ui-danger-light)] text-[var(--ui-danger-text)] ring-[var(--ui-danger-ring-subtle)]',
495
+ warning: 'bg-[var(--ui-warning-light)] text-[var(--ui-warning-text)] ring-[var(--ui-warning-ring-subtle)]',
496
+ info: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
497
+ primary: 'bg-[var(--ui-info-light)] text-[var(--ui-info-text)] ring-[var(--ui-info-ring-subtle)]',
498
+ secondary: 'bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 ring-[var(--ui-secondary-ring-subtle)]',
499
+ };
500
+ const SIZE_CLASS$1 = {
501
+ sm: 'text-xs py-0.5 px-2',
502
+ md: 'text-xs py-1 px-3',
503
+ };
504
+ const Badge = React.forwardRef((props, ref) => {
505
+ const { theme = 'info', className, children, removable = false, rounded = false, onRemove, size = 'md', icon, ...restProps } = props;
506
+ return (jsxRuntime.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 && jsxRuntime.jsx("span", { className: "shrink-0 inline-flex", children: icon }), children, removable && (jsxRuntime.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) => {
507
+ if (e.key === 'Enter' || e.key === ' ') {
508
+ e.preventDefault();
509
+ onRemove === null || onRemove === void 0 ? void 0 : onRemove();
510
+ }
511
+ } }))] }));
512
+ });
513
+ Badge.displayName = 'Badge';
514
+
515
+ var _path$c;
516
+ 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); }
517
+ var SvgTriangleAlert = function SvgTriangleAlert(props) {
518
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$c({
519
+ xmlns: "http://www.w3.org/2000/svg",
520
+ width: 24,
521
+ height: 24,
522
+ fill: "none",
523
+ stroke: "currentColor",
524
+ strokeLinecap: "round",
525
+ strokeLinejoin: "round",
526
+ strokeWidth: 2,
527
+ className: "lucide lucide-triangle-alert-icon lucide-triangle-alert",
528
+ viewBox: "0 0 24 24"
529
+ }, props), _path$c || (_path$c = /*#__PURE__*/React__namespace.createElement("path", {
530
+ 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"
531
+ })));
532
+ };
533
+
534
+ var _circle$2, _path$b;
535
+ 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); }
536
+ var SvgCircleCheck = function SvgCircleCheck(props) {
537
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$b({
538
+ xmlns: "http://www.w3.org/2000/svg",
539
+ width: 24,
540
+ height: 24,
541
+ fill: "none",
542
+ stroke: "currentColor",
543
+ strokeLinecap: "round",
544
+ strokeLinejoin: "round",
545
+ strokeWidth: 2,
546
+ className: "lucide lucide-circle-check-icon lucide-circle-check",
547
+ viewBox: "0 0 24 24"
548
+ }, props), _circle$2 || (_circle$2 = /*#__PURE__*/React__namespace.createElement("circle", {
549
+ cx: 12,
550
+ cy: 12,
551
+ r: 10
552
+ })), _path$b || (_path$b = /*#__PURE__*/React__namespace.createElement("path", {
553
+ d: "m9 12 2 2 4-4"
554
+ })));
555
+ };
556
+
557
+ const sizeMap = {
558
+ xs: 'size-4',
559
+ sm: 'size-5',
560
+ md: 'size-6',
561
+ lg: 'size-8',
562
+ xl: 'size-10',
563
+ };
564
+ const IconMap = {
565
+ info: SvgInfo,
566
+ error: SvgCircleX,
567
+ success: SvgCircleCheck,
464
568
  warning: SvgTriangleAlert,
465
569
  };
466
570
  const TypeClassMap = {
@@ -529,6 +633,51 @@ const BodyText = React.forwardRef((props, ref) => {
529
633
  });
530
634
  BodyText.displayName = 'BodyText';
531
635
 
636
+ function BottomNavigation({ items, activeId, onChange, fixed = true, showLabels = 'always', theme = 'light', activeIndicatorStyle = 'line', containerClass = '', itemClass = '', }) {
637
+ const handleTabClick = (item) => {
638
+ var _a;
639
+ if (item.disabled)
640
+ return;
641
+ (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item);
642
+ onChange(item.id);
643
+ };
644
+ const themeStyles = {
645
+ light: 'bg-white dark:bg-gray-900 border-t border-[var(--ui-border)] text-gray-600 dark:text-gray-400',
646
+ dark: 'bg-gray-900 text-gray-400 border-t border-gray-800',
647
+ primary: 'bg-blue-600 text-blue-100 border-t border-blue-700',
648
+ }[theme];
649
+ return (jsxRuntime.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) => {
650
+ const isActive = item.id === activeId;
651
+ const showLabelText = showLabels === 'always' || (showLabels === 'active' && isActive);
652
+ const activeItemColor = {
653
+ light: 'text-blue-600 dark:text-blue-400 font-bold',
654
+ dark: 'text-white font-bold',
655
+ primary: 'text-white font-bold',
656
+ }[theme];
657
+ const inactiveItemColor = {
658
+ light: 'text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 font-medium',
659
+ dark: 'text-gray-400 hover:text-gray-200 font-medium',
660
+ primary: 'text-blue-200 hover:text-white font-medium',
661
+ }[theme];
662
+ const pillActiveStyles = {
663
+ light: 'bg-blue-100 dark:bg-blue-950/80 text-blue-600 dark:text-blue-400 shadow-xs scale-105',
664
+ dark: 'bg-gray-800 text-white ring-1 ring-gray-700 shadow-xs scale-105',
665
+ primary: 'bg-white/25 text-white shadow-xs scale-105',
666
+ }[theme];
667
+ const badgeColor = {
668
+ danger: 'bg-red-500 text-white',
669
+ info: 'bg-blue-500 text-white',
670
+ success: 'bg-emerald-500 text-white',
671
+ }[item.badgeVariant || 'danger'];
672
+ return (jsxRuntime.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 && (jsxRuntime.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') })), jsxRuntime.jsxs("div", { className: buildClassName('relative inline-flex items-center justify-center transition-all duration-200', activeIndicatorStyle === 'pill'
673
+ ? buildClassName('px-4 py-1 rounded-full', isActive
674
+ ? pillActiveStyles
675
+ : 'group-hover:bg-gray-100/50 dark:group-hover:bg-gray-800/40')
676
+ : 'px-1 py-0.5'), children: [jsxRuntime.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 && (jsxRuntime.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 && (jsxRuntime.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 && (jsxRuntime.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));
677
+ }) }));
678
+ }
679
+ BottomNavigation.displayName = 'BottomNavigation';
680
+
532
681
  var _path$a;
533
682
  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); }
534
683
  var SvgSlash = function SvgSlash(props) {
@@ -684,10 +833,10 @@ const ButtonGroup = ({ children, orientation = 'horizontal', theme = 'secondary'
684
833
  (isVertical
685
834
  ? resolvedTheme === 'primary' || resolvedTheme === 'danger'
686
835
  ? 'border-t border-white/25 dark:border-white/20'
687
- : 'border-t border-gray-300/70 dark:border-gray-700/70'
836
+ : 'border-t border-[var(--ui-border)]'
688
837
  : resolvedTheme === 'primary' || resolvedTheme === 'danger'
689
838
  ? 'border-l border-white/25 dark:border-white/20'
690
- : 'border-l border-gray-300/70 dark:border-gray-700/70'),
839
+ : 'border-l border-[var(--ui-border)]'),
691
840
  ], fullWidth && 'flex-1'),
692
841
  });
693
842
  }) }));
@@ -708,27 +857,33 @@ const ASPECT_RATIO_CLASS = {
708
857
  video: 'aspect-video',
709
858
  wide: 'aspect-[21/9]',
710
859
  };
860
+ function ChevronRightIcon$1({ className = 'size-4' }) {
861
+ return (jsxRuntime.jsx("svg", { className: className, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) }));
862
+ }
711
863
  const Card = React.forwardRef(({ as, ...props }, ref) => {
712
- const { variant = 'outlined', radius = 'xl', hoverable = false, clickable = false, selected = false, bordered = true, compact = false, zeroPadding = false, ...rest } = props;
864
+ 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;
713
865
  const Component = as || 'div';
714
866
  const { className, ...cleanRest } = rest;
867
+ const isClickable = clickable || Boolean(onClick);
715
868
  const isOutlined = variant === 'outlined' && bordered;
716
869
  const isElevated = variant === 'elevated';
717
870
  const isFilled = variant === 'filled';
718
871
  const isGhost = variant === 'ghost';
719
- 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',
872
+ 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',
720
873
  // Surface variants
721
874
  isOutlined && 'bg-white dark:bg-gray-900 border border-[var(--ui-border)]', isElevated &&
722
- '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',
723
- // Hoverable & Clickable states
724
- 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);
725
- return jsxRuntime.jsx(Component, { ref: ref, className: classes, ...cleanRest });
875
+ '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',
876
+ // Hoverable & Clickable mobile/web touch states
877
+ hoverable && 'hover:bg-gray-100/80 dark:hover:bg-gray-800/80', isClickable &&
878
+ '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);
879
+ const hasHeaderRow = title || subtitle || leading || trailing || badge || showChevron;
880
+ return (jsxRuntime.jsxs(Component, { ref: ref, className: classes, onClick: onClick, ...cleanRest, children: [hasHeaderRow && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center gap-3 w-full min-w-0', children && 'mb-3'), children: [leading && jsxRuntime.jsx("div", { className: "shrink-0 flex items-center justify-center", children: leading }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 text-left", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [title && (jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: title })), badge] }), subtitle && (jsxRuntime.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate", children: subtitle }))] }), (trailing || showChevron) && (jsxRuntime.jsxs("div", { className: "shrink-0 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400", children: [trailing, showChevron && jsxRuntime.jsx(ChevronRightIcon$1, { className: "size-4 text-gray-400" })] }))] })), children] }));
726
881
  });
727
- const CardHeader = ({ className, bordered = false, children, ...props }) => (jsxRuntime.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 }));
882
+ const CardHeader = ({ className, bordered = false, children, ...props }) => (jsxRuntime.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 }));
728
883
  const CardTitle = ({ className, as: Component = 'h3', children, ...props }) => (jsxRuntime.jsx(Component, { className: buildClassName('text-lg font-semibold text-gray-900 dark:text-white tracking-tight', className), ...props, children: children }));
729
884
  const CardDescription = ({ className, children, ...props }) => (jsxRuntime.jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal mt-1', className), ...props, children: children }));
730
885
  const CardContent = ({ className, children, ...props }) => (jsxRuntime.jsx("div", { className: buildClassName('space-y-3', className), ...props, children: children }));
731
- const CardFooter = ({ className, bordered = false, children, ...props }) => (jsxRuntime.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 }));
886
+ const CardFooter = ({ className, bordered = false, children, ...props }) => (jsxRuntime.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 }));
732
887
  const CardMedia = ({ className, aspectRatio = 'video', alt = '', ...props }) => (jsxRuntime.jsx("div", { className: buildClassName('overflow-hidden -mx-5 -mt-5 mb-4 sm:-mx-6 sm:-mt-6', className), children: jsxRuntime.jsx("img", { alt: alt, className: buildClassName('w-full object-cover', ASPECT_RATIO_CLASS[aspectRatio] || ASPECT_RATIO_CLASS.video), ...props }) }));
733
888
  Card.Header = CardHeader;
734
889
  Card.Title = CardTitle;
@@ -748,19 +903,19 @@ Label.displayName = 'Label';
748
903
  const sizeStyles = {
749
904
  sm: {
750
905
  box: 'size-3.5',
751
- svg: 'h-2.5 w-2.5',
906
+ svg: 'size-2.75',
752
907
  text: 'text-xs',
753
908
  subtext: 'text-[11px]',
754
909
  },
755
910
  md: {
756
911
  box: 'size-4.5',
757
- svg: 'h-3.25 w-3.25',
912
+ svg: 'size-3.5',
758
913
  text: 'text-sm',
759
914
  subtext: 'text-xs',
760
915
  },
761
916
  lg: {
762
917
  box: 'size-5.5',
763
- svg: 'h-4 w-4',
918
+ svg: 'size-4.25',
764
919
  text: 'text-base',
765
920
  subtext: 'text-sm',
766
921
  },
@@ -781,19 +936,19 @@ const Checkbox = React.forwardRef((props, ref) => {
781
936
  const isCard = variant === 'card';
782
937
  return (jsxRuntime.jsxs("div", { className: buildClassName(wrapperClass), children: [jsxRuntime.jsx("div", { className: buildClassName(isCard
783
938
  ? 'rounded-xl border p-3.5 transition-all duration-150 relative'
784
- : 'flex items-start', isCard &&
939
+ : 'flex items-center', isCard &&
785
940
  (disabled
786
- ? 'border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/40 opacity-70'
941
+ ? 'border-[var(--ui-border-muted)] bg-gray-50/50 dark:bg-gray-900/40 opacity-70'
787
942
  : checked || indeterminate
788
943
  ? 'border-blue-500/80 bg-blue-50/30 dark:bg-blue-950/20 dark:border-blue-500/60 shadow-xs'
789
- : '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: jsxRuntime.jsxs("label", { htmlFor: checkboxId, className: buildClassName('inline-flex items-start relative select-none w-full', disabled ? 'cursor-not-allowed opacity-70' : 'cursor-pointer'), children: [jsxRuntime.jsxs("div", { className: "relative inline-flex items-center shrink-0 pt-0.5", children: [jsxRuntime.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
790
- ? 'border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 pointer-events-none'
791
- : '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 &&
792
- '!bg-blue-600 !border-blue-600 dark:!bg-blue-600 dark:!border-blue-600', className) }), !indeterminate && (jsxRuntime.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
944
+ : 'border-[var(--ui-border)] bg-white dark:bg-gray-900 hover:border-gray-300 dark:hover:border-gray-700 shadow-2xs'), containerClass), children: jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "relative inline-flex items-center justify-center shrink-0", children: [jsxRuntime.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
945
+ ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'
946
+ : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500', indeterminate &&
947
+ '!bg-blue-600 !border-blue-600 dark:!bg-blue-600 dark:!border-blue-600', className) }), !indeterminate && (jsxRuntime.jsx("span", { className: buildClassName('absolute inset-0 flex items-center justify-center text-white pointer-events-none transition-opacity', checked !== undefined
793
948
  ? checked
794
949
  ? 'opacity-100'
795
950
  : 'opacity-0'
796
- : 'opacity-0 peer-checked:opacity-100'), children: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", stroke: "currentColor", strokeWidth: "1", children: jsxRuntime.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 && (jsxRuntime.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: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M4 10a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1z", clipRule: "evenodd" }) }) }))] }), (label || description) && (jsxRuntime.jsxs("div", { className: "ml-2.5 flex flex-col justify-center min-w-0 flex-1", children: [label && (jsxRuntime.jsx(Label, { htmlFor: checkboxId, className: buildClassName(disabled
951
+ : 'opacity-0 peer-checked:opacity-100'), children: jsxRuntime.jsx("svg", { className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntime.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 && (jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center text-white pointer-events-none opacity-100 z-10", children: jsxRuntime.jsx("svg", { className: currentSize.svg, viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M4 10a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1z", clipRule: "evenodd" }) }) }))] }), (label || description) && (jsxRuntime.jsxs("div", { className: "ml-2.5 flex flex-col justify-center min-w-0 flex-1", children: [label && (jsxRuntime.jsx(Label, { htmlFor: checkboxId, className: buildClassName(disabled
797
952
  ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'
798
953
  : 'cursor-pointer text-gray-800 dark:text-gray-200 font-medium', currentSize.text, labelClass), children: label })), description && (jsxRuntime.jsx("span", { className: buildClassName('mt-0.5 text-gray-500 dark:text-gray-400 font-normal leading-normal', currentSize.subtext), children: description }))] }))] }) }), (error || helperText) && (jsxRuntime.jsx("div", { className: "mt-1.5 ml-0.5", children: error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) }))] }));
799
954
  });
@@ -862,7 +1017,7 @@ const CheckboxGroup = (props) => {
862
1017
  : inline
863
1018
  ? 'flex flex-wrap gap-3'
864
1019
  : 'flex flex-col gap-3';
865
- return (jsxRuntime.jsxs("div", { className: buildClassName('mb-3 space-y-3', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, children: label }), labelHint && (jsxRuntime.jsx(BodyText, { muted: true, small: true, children: labelHint }))] })), showSelectAll && items.length > 0 && (jsxRuntime.jsx("div", { className: "pb-1 border-b border-gray-200 dark:border-gray-800", children: jsxRuntime.jsx(Checkbox, { id: `${groupId}-select-all`, label: selectAllLabel, size: size, variant: variant, checked: allSelected, indeterminate: isIndeterminate, disabled: disabled || enabledItems.length === 0, onChange: handleSelectAllChange }) })), jsxRuntime.jsx("div", { className: layoutClass, children: items.map((item, index) => {
1020
+ return (jsxRuntime.jsxs("div", { className: buildClassName('mb-3 space-y-3', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, children: label }), labelHint && (jsxRuntime.jsx(BodyText, { muted: true, small: true, children: labelHint }))] })), showSelectAll && items.length > 0 && (jsxRuntime.jsx("div", { className: "pb-1 border-b border-[var(--ui-border)]", children: jsxRuntime.jsx(Checkbox, { id: `${groupId}-select-all`, label: selectAllLabel, size: size, variant: variant, checked: allSelected, indeterminate: isIndeterminate, disabled: disabled || enabledItems.length === 0, onChange: handleSelectAllChange }) })), jsxRuntime.jsx("div", { className: layoutClass, children: items.map((item, index) => {
866
1021
  const key = typeof item.value === 'string' || typeof item.value === 'number' ? item.value : index;
867
1022
  return (jsxRuntime.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));
868
1023
  }) }), (error || helperText) && (jsxRuntime.jsx("div", { className: "mt-1.5 ml-0.5", children: error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) }))] }));
@@ -942,27 +1097,8 @@ const usePagination = ({ totalPages, currentPage, siblingCount = 1, // number of
942
1097
 
943
1098
  var _path$9;
944
1099
  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); }
945
- var SvgChevronLeft = function SvgChevronLeft(props) {
946
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$9({
947
- xmlns: "http://www.w3.org/2000/svg",
948
- width: 24,
949
- height: 24,
950
- fill: "none",
951
- stroke: "currentColor",
952
- strokeLinecap: "round",
953
- strokeLinejoin: "round",
954
- strokeWidth: 2,
955
- className: "lucide lucide-chevron-left-icon lucide-chevron-left",
956
- viewBox: "0 0 24 24"
957
- }, props), _path$9 || (_path$9 = /*#__PURE__*/React__namespace.createElement("path", {
958
- d: "m15 18-6-6 6-6"
959
- })));
960
- };
961
-
962
- var _path$8;
963
- 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); }
964
1100
  var SvgChevronRight = function SvgChevronRight(props) {
965
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$8({
1101
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$9({
966
1102
  xmlns: "http://www.w3.org/2000/svg",
967
1103
  width: 24,
968
1104
  height: 24,
@@ -973,7 +1109,7 @@ var SvgChevronRight = function SvgChevronRight(props) {
973
1109
  strokeWidth: 2,
974
1110
  className: "lucide lucide-chevron-right-icon lucide-chevron-right",
975
1111
  viewBox: "0 0 24 24"
976
- }, props), _path$8 || (_path$8 = /*#__PURE__*/React__namespace.createElement("path", {
1112
+ }, props), _path$9 || (_path$9 = /*#__PURE__*/React__namespace.createElement("path", {
977
1113
  d: "m9 18 6-6-6-6"
978
1114
  })));
979
1115
  };
@@ -1095,10 +1231,10 @@ const useRowSelection = ({ items, getKey, selectedRowKeys, defaultSelectedRowKey
1095
1231
  };
1096
1232
  };
1097
1233
 
1098
- var _path$7;
1099
- 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); }
1234
+ var _path$8;
1235
+ 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); }
1100
1236
  var SvgArrowDownWideNarrow = function SvgArrowDownWideNarrow(props) {
1101
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$7({
1237
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$8({
1102
1238
  xmlns: "http://www.w3.org/2000/svg",
1103
1239
  width: 24,
1104
1240
  height: 24,
@@ -1109,15 +1245,15 @@ var SvgArrowDownWideNarrow = function SvgArrowDownWideNarrow(props) {
1109
1245
  strokeWidth: 2,
1110
1246
  className: "lucide lucide-arrow-down-wide-narrow-icon lucide-arrow-down-wide-narrow",
1111
1247
  viewBox: "0 0 24 24"
1112
- }, props), _path$7 || (_path$7 = /*#__PURE__*/React__namespace.createElement("path", {
1248
+ }, props), _path$8 || (_path$8 = /*#__PURE__*/React__namespace.createElement("path", {
1113
1249
  d: "m3 16 4 4 4-4M7 20V4M11 4h10M11 8h7M11 12h4"
1114
1250
  })));
1115
1251
  };
1116
1252
 
1117
- var _path$6;
1118
- 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); }
1253
+ var _path$7;
1254
+ 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); }
1119
1255
  var SvgArrowDownNarrowWide = function SvgArrowDownNarrowWide(props) {
1120
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$6({
1256
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$7({
1121
1257
  xmlns: "http://www.w3.org/2000/svg",
1122
1258
  width: 24,
1123
1259
  height: 24,
@@ -1128,15 +1264,15 @@ var SvgArrowDownNarrowWide = function SvgArrowDownNarrowWide(props) {
1128
1264
  strokeWidth: 2,
1129
1265
  className: "lucide lucide-arrow-down-narrow-wide-icon lucide-arrow-down-narrow-wide",
1130
1266
  viewBox: "0 0 24 24"
1131
- }, props), _path$6 || (_path$6 = /*#__PURE__*/React__namespace.createElement("path", {
1267
+ }, props), _path$7 || (_path$7 = /*#__PURE__*/React__namespace.createElement("path", {
1132
1268
  d: "m3 16 4 4 4-4M7 20V4M11 4h4M11 8h7M11 12h10"
1133
1269
  })));
1134
1270
  };
1135
1271
 
1136
- var _path$5;
1137
- 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); }
1272
+ var _path$6;
1273
+ 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); }
1138
1274
  var SvgArrowDownAz = function SvgArrowDownAz(props) {
1139
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$5({
1275
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$6({
1140
1276
  xmlns: "http://www.w3.org/2000/svg",
1141
1277
  width: 24,
1142
1278
  height: 24,
@@ -1147,15 +1283,15 @@ var SvgArrowDownAz = function SvgArrowDownAz(props) {
1147
1283
  strokeWidth: 2,
1148
1284
  className: "lucide lucide-arrow-down-az-icon lucide-arrow-down-a-z",
1149
1285
  viewBox: "0 0 24 24"
1150
- }, props), _path$5 || (_path$5 = /*#__PURE__*/React__namespace.createElement("path", {
1286
+ }, props), _path$6 || (_path$6 = /*#__PURE__*/React__namespace.createElement("path", {
1151
1287
  d: "m3 16 4 4 4-4M7 20V4M20 8h-5M15 10V6.5a2.5 2.5 0 0 1 5 0V10M15 14h5l-5 6h5"
1152
1288
  })));
1153
1289
  };
1154
1290
 
1155
- var _path$4;
1156
- 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); }
1291
+ var _path$5;
1292
+ 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); }
1157
1293
  var SvgArrowDownZa = function SvgArrowDownZa(props) {
1158
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$4({
1294
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$5({
1159
1295
  xmlns: "http://www.w3.org/2000/svg",
1160
1296
  width: 24,
1161
1297
  height: 24,
@@ -1166,15 +1302,15 @@ var SvgArrowDownZa = function SvgArrowDownZa(props) {
1166
1302
  strokeWidth: 2,
1167
1303
  className: "lucide lucide-arrow-down-za-icon lucide-arrow-down-z-a",
1168
1304
  viewBox: "0 0 24 24"
1169
- }, props), _path$4 || (_path$4 = /*#__PURE__*/React__namespace.createElement("path", {
1305
+ }, props), _path$5 || (_path$5 = /*#__PURE__*/React__namespace.createElement("path", {
1170
1306
  d: "m3 16 4 4 4-4M7 4v16M15 4h5l-5 6h5M15 20v-3.5a2.5 2.5 0 0 1 5 0V20M20 18h-5"
1171
1307
  })));
1172
1308
  };
1173
1309
 
1174
- var _path$3;
1175
- 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); }
1310
+ var _path$4;
1311
+ 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); }
1176
1312
  var SvgArrowUpDown = function SvgArrowUpDown(props) {
1177
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$3({
1313
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$4({
1178
1314
  xmlns: "http://www.w3.org/2000/svg",
1179
1315
  width: 24,
1180
1316
  height: 24,
@@ -1185,7 +1321,7 @@ var SvgArrowUpDown = function SvgArrowUpDown(props) {
1185
1321
  strokeWidth: 2,
1186
1322
  className: "lucide lucide-arrow-up-down-icon lucide-arrow-up-down",
1187
1323
  viewBox: "0 0 24 24"
1188
- }, props), _path$3 || (_path$3 = /*#__PURE__*/React__namespace.createElement("path", {
1324
+ }, props), _path$4 || (_path$4 = /*#__PURE__*/React__namespace.createElement("path", {
1189
1325
  d: "m21 16-4 4-4-4M17 20V4M3 8l4-4 4 4M7 4v16"
1190
1326
  })));
1191
1327
  };
@@ -1227,7 +1363,7 @@ const autoSortItems = (items, column, sort) => {
1227
1363
  return 0;
1228
1364
  });
1229
1365
  };
1230
- 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, }) {
1366
+ 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, }) {
1231
1367
  const internalSorting = React.useRef({});
1232
1368
  const [sortedItems, setSortedItems] = React.useState(items);
1233
1369
  React.useEffect(() => {
@@ -1272,12 +1408,13 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
1272
1408
  });
1273
1409
  const densityCellClass = DENSITY_CELL_CLASS$2[density];
1274
1410
  const colSize = columns.length + (selectable ? 1 : 0);
1275
- return (jsxRuntime.jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsxRuntime.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: jsxRuntime.jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxRuntime.jsxs(TableHead, { className: headClass, children: [selectable && (jsxRuntime.jsx(TableHeaderCell, { className: buildClassName('bg-gray-50 dark:bg-gray-800 w-px', densityCellClass), children: jsxRuntime.jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1411
+ const wrapperHasOverflow = /\boverflow-(x-|y-)?(auto|hidden|scroll|visible|clip)\b/.test(wrapperClass);
1412
+ return (jsxRuntime.jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsxRuntime.jsx("div", { className: buildClassName(!wrapperHasOverflow && 'overflow-x-auto', 'rounded-lg border border-[var(--ui-border)]', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxRuntime.jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxRuntime.jsxs(TableHead, { className: headClass, children: [selectable && (jsxRuntime.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: jsxRuntime.jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1276
1413
  if (el)
1277
1414
  el.indeterminate = someSelected;
1278
- }, onChange: toggleAll }) })), columns.map((column) => (jsxRuntime.jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
1279
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1280
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxRuntime.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: [jsxRuntime.jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsxRuntime.jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsxRuntime.jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
1415
+ }, onChange: toggleAll }) })), columns.map((column) => (jsxRuntime.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' &&
1416
+ 'sticky left-0 z-30 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1417
+ 'sticky right-0 z-30 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxRuntime.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: [jsxRuntime.jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsxRuntime.jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsxRuntime.jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
1281
1418
  const key = getKey(item, idx);
1282
1419
  const rowSelectable = !isRowSelectable || isRowSelectable(item);
1283
1420
  return (jsxRuntime.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 && (jsxRuntime.jsx(TableCell, { className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40'), children: jsxRuntime.jsx("span", { onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx(Checkbox, { "aria-label": "Select row", checked: isSelected(key), disabled: !rowSelectable, onChange: () => toggleRow(key) }) }) })), columns.map((column) => {
@@ -1288,7 +1425,7 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
1288
1425
  ? column.render(item)
1289
1426
  : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
1290
1427
  })] }, key));
1291
- })) }), footerRow && jsxRuntime.jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsxRuntime.jsx(Pagination, { ...pagination, className: buildClassName('rounded-b-lg border-t border-[var(--ui-border)]', paginationContainerClass), onChange: setPagination }))] }));
1428
+ })) }), footerRow && jsxRuntime.jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsxRuntime.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 }))] }));
1292
1429
  }
1293
1430
  DataTable.displayName = 'DataTable';
1294
1431
 
@@ -1403,8 +1540,8 @@ const DetailedInformation = React.forwardRef((props, ref) => {
1403
1540
  const isMultiColumn = columns > 1;
1404
1541
  return (jsxRuntime.jsxs("div", { ref: ref, className: buildClassName(isCard
1405
1542
  ? compact
1406
- ? 'p-3 sm:p-4 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-gray-200 dark:border-gray-700'
1407
- : 'p-4 sm:p-6 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-gray-200 dark:border-gray-700'
1543
+ ? 'p-3 sm:p-4 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-[var(--ui-border)]'
1544
+ : 'p-4 sm:p-6 bg-gray-50/60 dark:bg-gray-800/40 rounded-2xl border border-[var(--ui-border)]'
1408
1545
  : isBordered
1409
1546
  ? compact
1410
1547
  ? 'p-3 sm:p-4 border border-[var(--ui-border)] rounded-2xl'
@@ -1422,8 +1559,8 @@ const DetailedInformation = React.forwardRef((props, ref) => {
1422
1559
  const isVertical = layout === 'vertical' || isMultiColumn;
1423
1560
  return (jsxRuntime.jsxs("div", { className: buildClassName(isMultiColumn && isCard
1424
1561
  ? compact
1425
- ? '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'
1426
- : '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'
1562
+ ? 'p-3 bg-white dark:bg-gray-900 rounded-xl border border-[var(--ui-border)] shadow-2xs flex flex-col gap-1'
1563
+ : 'p-4 bg-white dark:bg-gray-900 rounded-xl border border-[var(--ui-border)] shadow-2xs flex flex-col gap-1'
1427
1564
  : isVertical
1428
1565
  ? 'flex flex-col gap-1 py-2 px-1'
1429
1566
  : 'grid grid-cols-3 gap-4 items-center py-2.5 px-1', compact && !isMultiColumn ? 'py-1.5' : ''), children: [jsxRuntime.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 && jsxRuntime.jsx("span", { className: "shrink-0 text-gray-400", children: detail.icon }), jsxRuntime.jsx("span", { children: detail.label }), detail.helpText && (jsxRuntime.jsx("span", { className: "text-xs text-gray-400 font-normal cursor-help", title: detail.helpText, children: "(?)" }))] }), jsxRuntime.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 ? (jsxRuntime.jsx(CopyableValue, { text: copyText, children: displayValue })) : (displayValue) })] }, detail.label || index));
@@ -1436,41 +1573,6 @@ const Dot = ({ as = 'span', className, ...props }) => React.createElement(as, {
1436
1573
  ...props,
1437
1574
  });
1438
1575
 
1439
- const alignmentMap = {
1440
- center: 'items-center justify-center h-full',
1441
- start: 'justify-start h-full',
1442
- end: 'justify-end h-full',
1443
- top: 'items-start justify-center w-full',
1444
- bottom: 'items-end justify-center h-full',
1445
- };
1446
- const panelAlignmentMap = {
1447
- center: 'data-[closed]:scale-95 rounded-2xl',
1448
- start: 'data-[closed]:-translate-x-1/2 rounded-r-2xl',
1449
- end: 'data-[closed]:translate-x-1/2 rounded-l-2xl',
1450
- top: 'data-[closed]:-translate-y-1/2 rounded-b-2xl',
1451
- bottom: 'data-[closed]:translate-y-1/2 rounded-t-2xl md:rounded-t-3xl max-h-[92svh]',
1452
- };
1453
- const panelSizeMap = {
1454
- xs: 'max-w-xs',
1455
- sm: 'max-w-sm',
1456
- md: 'max-w-md',
1457
- lg: 'max-w-lg',
1458
- xl: 'max-w-xl',
1459
- '2xl': 'max-w-2xl',
1460
- full: 'w-full',
1461
- };
1462
- 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, }) => {
1463
- const showTitleSection = Boolean(title || description || showBackButton || showCloseButton);
1464
- const shouldShowDragHandle = dragHandle !== null && dragHandle !== void 0 ? dragHandle : align === 'bottom';
1465
- const handleDialogClose = () => {
1466
- if (closeOnOutsideClick) {
1467
- onClose === null || onClose === void 0 ? void 0 : onClose();
1468
- }
1469
- };
1470
- return (jsxRuntime.jsxs(react.Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: handleDialogClose, transition: true, children: [backdrop && (jsxRuntime.jsx(react.DialogBackdrop, { className: "fixed inset-0 bg-black/40 backdrop-blur-xs transition-opacity duration-200" })), jsxRuntime.jsx("div", { className: "fixed inset-0 w-screen h-[100svh]", children: jsxRuntime.jsx("div", { className: buildClassName('flex', alignmentMap[align]), children: jsxRuntime.jsxs(react.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 && (jsxRuntime.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 && (jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [showBackButton && (jsxRuntime.jsx(Button, { iconOnly: true, "aria-label": "Back", variant: "plain", theme: "secondary", size: "xs", onClick: onClose, children: jsxRuntime.jsx(SvgChevronLeft, { className: "size-4" }) })), title && (jsxRuntime.jsx(react.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 && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4" }) }))] }), description && (jsxRuntime.jsx("p", { className: buildClassName('text-sm text-gray-500 dark:text-gray-400 font-normal truncate', descriptionClass), children: description }))] })), jsxRuntime.jsx("div", { className: buildClassName('flex-1 p-4 md:p-6 space-y-4 min-w-0', contentClass), children: children }), footer && (jsxRuntime.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 }))] }) }) })] }));
1471
- };
1472
- Drawer.displayName = 'Drawer';
1473
-
1474
1576
  const WIDTH_CLASS = {
1475
1577
  auto: 'w-auto min-w-[120px]',
1476
1578
  sm: 'w-44',
@@ -1496,7 +1598,7 @@ const Dropdown = ({ triggerButton, renderTriggerButton, className, items, render
1496
1598
  variant: (_b = triggerButton.props.variant) !== null && _b !== void 0 ? _b : variant,
1497
1599
  size: (_c = triggerButton.props.size) !== null && _c !== void 0 ? _c : size,
1498
1600
  disabled: (_d = triggerButton.props.disabled) !== null && _d !== void 0 ? _d : disabled,
1499
- }) })) : (jsxRuntime.jsx(react.MenuButton, { as: React.Fragment, children: triggerButton })), jsxRuntime.jsx(react.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) => (jsxRuntime.jsxs(React.Fragment, { children: [item.groupTitle && (jsxRuntime.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}`)), jsxRuntime.jsx(react.MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled, active }) => (jsxRuntime.jsx("div", { onClick: () => {
1601
+ }) })) : (jsxRuntime.jsx(react.MenuButton, { as: React.Fragment, children: triggerButton })), jsxRuntime.jsx(react.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) => (jsxRuntime.jsxs(React.Fragment, { children: [item.groupTitle && (jsxRuntime.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}`)), !item.divider && (jsxRuntime.jsx(react.MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled, active }) => (jsxRuntime.jsx("div", { onClick: () => {
1500
1602
  var _a;
1501
1603
  if (!disabled) {
1502
1604
  (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, item);
@@ -1508,14 +1610,14 @@ const Dropdown = ({ triggerButton, renderTriggerButton, className, items, render
1508
1610
  : 'hover:bg-rose-50 dark:hover:bg-rose-950/40')
1509
1611
  : buildClassName('text-gray-700 dark:text-gray-200', active
1510
1612
  ? 'bg-gray-100 dark:bg-gray-700/80'
1511
- : '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)) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [item.icon && (jsxRuntime.jsx("span", { className: buildClassName('shrink-0', item.danger ? 'text-rose-500' : 'text-gray-400 dark:text-gray-500'), children: item.icon })), jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0", children: [item.label && jsxRuntime.jsx("span", { className: "font-medium truncate", children: item.label }), item.description && (jsxRuntime.jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500 font-normal truncate", children: item.description }))] })] }), item.shortcut && (jsxRuntime.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 && (jsxRuntime.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))) })] }));
1613
+ : '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)) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [item.icon && (jsxRuntime.jsx("span", { className: buildClassName('shrink-0', item.danger ? 'text-rose-500' : 'text-gray-400 dark:text-gray-500'), children: item.icon })), jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0", children: [item.label && (jsxRuntime.jsx("span", { className: "font-medium truncate", children: item.label })), item.description && (jsxRuntime.jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500 font-normal truncate", children: item.description }))] })] }), item.shortcut && (jsxRuntime.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 && (jsxRuntime.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))) })] }));
1512
1614
  };
1513
1615
  Dropdown.displayName = 'Dropdown';
1514
1616
 
1515
- var _path$2;
1516
- 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); }
1617
+ var _path$3;
1618
+ 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); }
1517
1619
  var SvgFolderPlus = function SvgFolderPlus(props) {
1518
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$2({
1620
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$3({
1519
1621
  xmlns: "http://www.w3.org/2000/svg",
1520
1622
  width: 24,
1521
1623
  height: 24,
@@ -1526,7 +1628,7 @@ var SvgFolderPlus = function SvgFolderPlus(props) {
1526
1628
  strokeWidth: 2,
1527
1629
  className: "lucide lucide-folder-plus-icon lucide-folder-plus",
1528
1630
  viewBox: "0 0 24 24"
1529
- }, props), _path$2 || (_path$2 = /*#__PURE__*/React__namespace.createElement("path", {
1631
+ }, props), _path$3 || (_path$3 = /*#__PURE__*/React__namespace.createElement("path", {
1530
1632
  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"
1531
1633
  })));
1532
1634
  };
@@ -1535,16 +1637,402 @@ const EmptyState = ({ title, description, className, action = null, }) => {
1535
1637
  return (jsxRuntime.jsx("div", { className: buildClassName('w-full flex justify-center px-4 pt-16', className), children: jsxRuntime.jsxs("div", { className: "max-w-md flex flex-col items-center gap-4", children: [jsxRuntime.jsx(SvgFolderPlus, { className: "size-8 text-[var(--ui-text)]" }), jsxRuntime.jsx(HeadingText.SubTitle, { children: title }), description && (jsxRuntime.jsx(BodyText, { as: "p", className: "text-center", muted: true, small: true, children: description })), action] }) }));
1536
1638
  };
1537
1639
 
1538
- const sizeClasses$4 = {
1539
- sm: {
1540
- input: 'px-2.5 py-1 text-xs leading-5',
1541
- group: 'w-8 text-xs',
1542
- icon: 'size-3.5',
1543
- text: 'text-xs',
1544
- },
1545
- md: {
1546
- input: 'px-3.5 py-2 text-sm leading-6',
1547
- group: 'w-10 text-sm',
1640
+ function FloatingActionButton({ icon, activeIcon, label, variant = 'primary', size = 'md', position = 'bottom-right', speedDialActions, isOpen: externalIsOpen, onToggle, disabled = false, onClick, 'aria-label': ariaLabel, containerClass = '', className = '', }) {
1641
+ const [internalIsOpen, setInternalIsOpen] = React.useState(false);
1642
+ const isSpeedDial = Array.isArray(speedDialActions) && speedDialActions.length > 0;
1643
+ const isOpen = externalIsOpen !== undefined ? externalIsOpen : internalIsOpen;
1644
+ const toggleOpen = () => {
1645
+ const nextState = !isOpen;
1646
+ setInternalIsOpen(nextState);
1647
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(nextState);
1648
+ };
1649
+ const handleMainClick = () => {
1650
+ if (disabled)
1651
+ return;
1652
+ if (isSpeedDial) {
1653
+ toggleOpen();
1654
+ }
1655
+ else {
1656
+ onClick === null || onClick === void 0 ? void 0 : onClick();
1657
+ }
1658
+ };
1659
+ const handleSubActionClick = (action) => {
1660
+ var _a;
1661
+ if (action.disabled)
1662
+ return;
1663
+ (_a = action.onClick) === null || _a === void 0 ? void 0 : _a.call(action);
1664
+ setInternalIsOpen(false);
1665
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(false);
1666
+ };
1667
+ const positionClasses = {
1668
+ 'bottom-right': 'fixed bottom-6 right-6 z-40',
1669
+ 'bottom-left': 'fixed bottom-6 left-6 z-40',
1670
+ 'bottom-center': 'fixed bottom-6 left-1/2 -translate-x-1/2 z-40',
1671
+ inline: 'relative inline-flex z-10',
1672
+ }[position];
1673
+ const variantClasses = {
1674
+ primary: 'bg-blue-600 hover:bg-blue-700 active:bg-blue-800 text-white shadow-lg shadow-blue-600/30',
1675
+ 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',
1676
+ danger: 'bg-red-600 hover:bg-red-700 active:bg-red-800 text-white shadow-lg shadow-red-600/30',
1677
+ dark: 'bg-gray-900 hover:bg-black active:bg-black text-white shadow-lg shadow-gray-900/40',
1678
+ }[variant];
1679
+ const sizeClasses = {
1680
+ sm: label ? 'px-3.5 py-2 text-xs gap-2 rounded-full' : 'p-2.5 rounded-full',
1681
+ md: label ? 'px-5 py-3 text-sm gap-2.5 rounded-full' : 'p-3.5 rounded-full',
1682
+ lg: label ? 'px-6 py-4 text-base gap-3 rounded-full' : 'p-4 rounded-full',
1683
+ }[size];
1684
+ return (jsxRuntime.jsxs("div", { className: buildClassName(positionClasses, containerClass), "data-testid": "fab-container", children: [isSpeedDial && isOpen && (jsxRuntime.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 && (jsxRuntime.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'
1685
+ ? 'items-start left-0'
1686
+ : position === 'bottom-center'
1687
+ ? 'items-center left-1/2 -translate-x-1/2'
1688
+ : 'items-end right-0', isOpen
1689
+ ? 'scale-100 opacity-100 pointer-events-auto'
1690
+ : 'scale-90 opacity-0 pointer-events-none'), "data-testid": "fab-speed-dial-menu", children: speedDialActions.map((action) => {
1691
+ const isDanger = action.theme === 'danger';
1692
+ const isPrimary = action.theme === 'primary';
1693
+ return (jsxRuntime.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 &&
1694
+ (isDanger
1695
+ ? 'bg-red-600 text-white hover:bg-red-700'
1696
+ : isPrimary
1697
+ ? 'bg-blue-600 text-white hover:bg-blue-700'
1698
+ : '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: [jsxRuntime.jsx("span", { className: "text-sm", children: action.icon }), jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: action.label })] }, action.id));
1699
+ }) })), jsxRuntime.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: [jsxRuntime.jsx("span", { className: buildClassName('transition-transform duration-200', isOpen && 'rotate-45'), children: isOpen && activeIcon ? activeIcon : icon }), label && jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: label })] })] }));
1700
+ }
1701
+ FloatingActionButton.displayName = 'FloatingActionButton';
1702
+
1703
+ const GAP_MAP = {
1704
+ none: 'gap-0',
1705
+ xs: 'gap-1',
1706
+ sm: 'gap-2',
1707
+ md: 'gap-4',
1708
+ lg: 'gap-6',
1709
+ xl: 'gap-8',
1710
+ '2xl': 'gap-12',
1711
+ };
1712
+ const GAP_X_MAP = {
1713
+ none: 'gap-x-0',
1714
+ xs: 'gap-x-1',
1715
+ sm: 'gap-x-2',
1716
+ md: 'gap-x-4',
1717
+ lg: 'gap-x-6',
1718
+ xl: 'gap-x-8',
1719
+ '2xl': 'gap-x-12',
1720
+ };
1721
+ const GAP_Y_MAP = {
1722
+ none: 'gap-y-0',
1723
+ xs: 'gap-y-1',
1724
+ sm: 'gap-y-2',
1725
+ md: 'gap-y-4',
1726
+ lg: 'gap-y-6',
1727
+ xl: 'gap-y-8',
1728
+ '2xl': 'gap-y-12',
1729
+ };
1730
+ const ALIGN_MAP = {
1731
+ start: 'items-start',
1732
+ center: 'items-center',
1733
+ end: 'items-end',
1734
+ baseline: 'items-baseline',
1735
+ stretch: 'items-stretch',
1736
+ };
1737
+ const JUSTIFY_MAP = {
1738
+ start: 'justify-start',
1739
+ center: 'justify-center',
1740
+ end: 'justify-end',
1741
+ between: 'justify-between',
1742
+ around: 'justify-around',
1743
+ evenly: 'justify-evenly',
1744
+ };
1745
+ const DIRECTION_MAP = {
1746
+ row: 'flex-row',
1747
+ 'row-reverse': 'flex-row-reverse',
1748
+ col: 'flex-col',
1749
+ 'col-reverse': 'flex-col-reverse',
1750
+ };
1751
+ const WRAP_MAP = {
1752
+ wrap: 'flex-wrap',
1753
+ nowrap: 'flex-nowrap',
1754
+ 'wrap-reverse': 'flex-wrap-reverse',
1755
+ };
1756
+ /**
1757
+ * Resolves the `order` prop to inline styles when it's a raw number.
1758
+ *
1759
+ * `'first'` / `'last'` map to the static `order-first`/`order-last` Tailwind
1760
+ * utilities (safe, since those exact class names are literal elsewhere).
1761
+ * Arbitrary numeric orders can't be expressed as a safe literal class (the
1762
+ * value is unbounded), so they're applied as an inline `order` style instead
1763
+ * — that works regardless of what the consuming app's Tailwind build scans.
1764
+ */
1765
+ const resolveOrderStyle = (order) => typeof order === 'number' ? { order } : undefined;
1766
+ const resolveOrderClassName = (order) => {
1767
+ if (order === 'first')
1768
+ return '-order-1';
1769
+ if (order === 'last')
1770
+ return 'order-last';
1771
+ return undefined;
1772
+ };
1773
+ /** Width-fraction span classes used by `Flex.Item` (unprefixed / base breakpoint). */
1774
+ const FLEX_SPAN_MAP = {
1775
+ 1: 'w-1/12 flex-none',
1776
+ 2: 'w-2/12 flex-none',
1777
+ 3: 'w-3/12 flex-none',
1778
+ 4: 'w-4/12 flex-none',
1779
+ 5: 'w-5/12 flex-none',
1780
+ 6: 'w-6/12 flex-none',
1781
+ 7: 'w-7/12 flex-none',
1782
+ 8: 'w-8/12 flex-none',
1783
+ 9: 'w-9/12 flex-none',
1784
+ 10: 'w-10/12 flex-none',
1785
+ 11: 'w-11/12 flex-none',
1786
+ 12: 'w-full flex-none',
1787
+ auto: 'w-auto flex-none',
1788
+ full: 'w-full flex-none',
1789
+ };
1790
+ const FLEX_SM_SPAN_MAP = {
1791
+ 1: 'sm:w-1/12',
1792
+ 2: 'sm:w-2/12',
1793
+ 3: 'sm:w-3/12',
1794
+ 4: 'sm:w-4/12',
1795
+ 5: 'sm:w-5/12',
1796
+ 6: 'sm:w-6/12',
1797
+ 7: 'sm:w-7/12',
1798
+ 8: 'sm:w-8/12',
1799
+ 9: 'sm:w-9/12',
1800
+ 10: 'sm:w-10/12',
1801
+ 11: 'sm:w-11/12',
1802
+ 12: 'sm:w-full',
1803
+ auto: 'sm:w-auto',
1804
+ full: 'sm:w-full',
1805
+ };
1806
+ const FLEX_MD_SPAN_MAP = {
1807
+ 1: 'md:w-1/12',
1808
+ 2: 'md:w-2/12',
1809
+ 3: 'md:w-3/12',
1810
+ 4: 'md:w-4/12',
1811
+ 5: 'md:w-5/12',
1812
+ 6: 'md:w-6/12',
1813
+ 7: 'md:w-7/12',
1814
+ 8: 'md:w-8/12',
1815
+ 9: 'md:w-9/12',
1816
+ 10: 'md:w-10/12',
1817
+ 11: 'md:w-11/12',
1818
+ 12: 'md:w-full',
1819
+ auto: 'md:w-auto',
1820
+ full: 'md:w-full',
1821
+ };
1822
+ const FLEX_LG_SPAN_MAP = {
1823
+ 1: 'lg:w-1/12',
1824
+ 2: 'lg:w-2/12',
1825
+ 3: 'lg:w-3/12',
1826
+ 4: 'lg:w-4/12',
1827
+ 5: 'lg:w-5/12',
1828
+ 6: 'lg:w-6/12',
1829
+ 7: 'lg:w-7/12',
1830
+ 8: 'lg:w-8/12',
1831
+ 9: 'lg:w-9/12',
1832
+ 10: 'lg:w-10/12',
1833
+ 11: 'lg:w-11/12',
1834
+ 12: 'lg:w-full',
1835
+ auto: 'lg:w-auto',
1836
+ full: 'lg:w-full',
1837
+ };
1838
+ const FLEX_XL_SPAN_MAP = {
1839
+ 1: 'xl:w-1/12',
1840
+ 2: 'xl:w-2/12',
1841
+ 3: 'xl:w-3/12',
1842
+ 4: 'xl:w-4/12',
1843
+ 5: 'xl:w-5/12',
1844
+ 6: 'xl:w-6/12',
1845
+ 7: 'xl:w-7/12',
1846
+ 8: 'xl:w-8/12',
1847
+ 9: 'xl:w-9/12',
1848
+ 10: 'xl:w-10/12',
1849
+ 11: 'xl:w-11/12',
1850
+ 12: 'xl:w-full',
1851
+ auto: 'xl:w-auto',
1852
+ full: 'xl:w-full',
1853
+ };
1854
+ const FLEX_XXL_SPAN_MAP = {
1855
+ 1: '2xl:w-1/12',
1856
+ 2: '2xl:w-2/12',
1857
+ 3: '2xl:w-3/12',
1858
+ 4: '2xl:w-4/12',
1859
+ 5: '2xl:w-5/12',
1860
+ 6: '2xl:w-6/12',
1861
+ 7: '2xl:w-7/12',
1862
+ 8: '2xl:w-8/12',
1863
+ 9: '2xl:w-9/12',
1864
+ 10: '2xl:w-10/12',
1865
+ 11: '2xl:w-11/12',
1866
+ 12: '2xl:w-full',
1867
+ auto: '2xl:w-auto',
1868
+ full: '2xl:w-full',
1869
+ };
1870
+ /** `col-span-*` classes used by `Grid.Col` (unprefixed / base breakpoint). */
1871
+ const GRID_SPAN_MAP = {
1872
+ 1: 'col-span-1',
1873
+ 2: 'col-span-2',
1874
+ 3: 'col-span-3',
1875
+ 4: 'col-span-4',
1876
+ 5: 'col-span-5',
1877
+ 6: 'col-span-6',
1878
+ 7: 'col-span-7',
1879
+ 8: 'col-span-8',
1880
+ 9: 'col-span-9',
1881
+ 10: 'col-span-10',
1882
+ 11: 'col-span-11',
1883
+ 12: 'col-span-12',
1884
+ auto: 'col-auto',
1885
+ full: 'col-span-full',
1886
+ };
1887
+ const GRID_SM_SPAN_MAP = {
1888
+ 1: 'sm:col-span-1',
1889
+ 2: 'sm:col-span-2',
1890
+ 3: 'sm:col-span-3',
1891
+ 4: 'sm:col-span-4',
1892
+ 5: 'sm:col-span-5',
1893
+ 6: 'sm:col-span-6',
1894
+ 7: 'sm:col-span-7',
1895
+ 8: 'sm:col-span-8',
1896
+ 9: 'sm:col-span-9',
1897
+ 10: 'sm:col-span-10',
1898
+ 11: 'sm:col-span-11',
1899
+ 12: 'sm:col-span-12',
1900
+ auto: 'sm:col-auto',
1901
+ full: 'sm:col-span-full',
1902
+ };
1903
+ const GRID_MD_SPAN_MAP = {
1904
+ 1: 'md:col-span-1',
1905
+ 2: 'md:col-span-2',
1906
+ 3: 'md:col-span-3',
1907
+ 4: 'md:col-span-4',
1908
+ 5: 'md:col-span-5',
1909
+ 6: 'md:col-span-6',
1910
+ 7: 'md:col-span-7',
1911
+ 8: 'md:col-span-8',
1912
+ 9: 'md:col-span-9',
1913
+ 10: 'md:col-span-10',
1914
+ 11: 'md:col-span-11',
1915
+ 12: 'md:col-span-12',
1916
+ auto: 'md:col-auto',
1917
+ full: 'md:col-span-full',
1918
+ };
1919
+ const GRID_LG_SPAN_MAP = {
1920
+ 1: 'lg:col-span-1',
1921
+ 2: 'lg:col-span-2',
1922
+ 3: 'lg:col-span-3',
1923
+ 4: 'lg:col-span-4',
1924
+ 5: 'lg:col-span-5',
1925
+ 6: 'lg:col-span-6',
1926
+ 7: 'lg:col-span-7',
1927
+ 8: 'lg:col-span-8',
1928
+ 9: 'lg:col-span-9',
1929
+ 10: 'lg:col-span-10',
1930
+ 11: 'lg:col-span-11',
1931
+ 12: 'lg:col-span-12',
1932
+ auto: 'lg:col-auto',
1933
+ full: 'lg:col-span-full',
1934
+ };
1935
+ const GRID_XL_SPAN_MAP = {
1936
+ 1: 'xl:col-span-1',
1937
+ 2: 'xl:col-span-2',
1938
+ 3: 'xl:col-span-3',
1939
+ 4: 'xl:col-span-4',
1940
+ 5: 'xl:col-span-5',
1941
+ 6: 'xl:col-span-6',
1942
+ 7: 'xl:col-span-7',
1943
+ 8: 'xl:col-span-8',
1944
+ 9: 'xl:col-span-9',
1945
+ 10: 'xl:col-span-10',
1946
+ 11: 'xl:col-span-11',
1947
+ 12: 'xl:col-span-12',
1948
+ auto: 'xl:col-auto',
1949
+ full: 'xl:col-span-full',
1950
+ };
1951
+ const GRID_XXL_SPAN_MAP = {
1952
+ 1: '2xl:col-span-1',
1953
+ 2: '2xl:col-span-2',
1954
+ 3: '2xl:col-span-3',
1955
+ 4: '2xl:col-span-4',
1956
+ 5: '2xl:col-span-5',
1957
+ 6: '2xl:col-span-6',
1958
+ 7: '2xl:col-span-7',
1959
+ 8: '2xl:col-span-8',
1960
+ 9: '2xl:col-span-9',
1961
+ 10: '2xl:col-span-10',
1962
+ 11: '2xl:col-span-11',
1963
+ 12: '2xl:col-span-12',
1964
+ auto: '2xl:col-auto',
1965
+ full: '2xl:col-span-full',
1966
+ };
1967
+ /**
1968
+ * Preset track-count classes for `Grid`'s `cols` prop. Each preset
1969
+ * progressively reveals more columns at wider breakpoints so a grid is
1970
+ * responsive out of the box without the caller specifying per-item spans.
1971
+ */
1972
+ const GRID_COLS_MAP = {
1973
+ 1: 'grid-cols-1',
1974
+ 2: 'grid-cols-1 sm:grid-cols-2',
1975
+ 3: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3',
1976
+ 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
1977
+ 5: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5',
1978
+ 6: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6',
1979
+ 7: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-7',
1980
+ 8: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-8',
1981
+ 9: 'grid-cols-1 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-9',
1982
+ 10: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-10',
1983
+ 11: 'grid-cols-1 sm:grid-cols-3 md:grid-cols-6 lg:grid-cols-11',
1984
+ 12: 'grid-cols-12',
1985
+ auto: 'grid-cols-none auto-cols-auto',
1986
+ };
1987
+
1988
+ const FlexItem = React.forwardRef((props, ref) => {
1989
+ const { as: Component = 'div', span, sm, md, lg, xl, xxl, grow, shrink, order, className, style, children, ...restProps } = props;
1990
+ 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);
1991
+ return (jsxRuntime.jsx(Component, { ref: ref, className: classes, style: { ...resolveOrderStyle(order), ...style }, ...restProps, children: children }));
1992
+ });
1993
+ FlexItem.displayName = 'Flex.Item';
1994
+ const Flex = React.forwardRef((props, ref) => {
1995
+ const { as: Component = 'div', gap, gapX, gapY, align = 'stretch', justify = 'start', direction = 'row', wrap = 'wrap', inline = false, className, children, ...restProps } = props;
1996
+ 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);
1997
+ return (jsxRuntime.jsx(Component, { ref: ref, className: classes, ...restProps, children: children }));
1998
+ });
1999
+ Flex.Item = FlexItem;
2000
+ Flex.Col = FlexItem;
2001
+ Flex.displayName = 'Flex';
2002
+
2003
+ const GridContext = React.createContext({ isAutoFit: false });
2004
+ const GridCol = React.forwardRef((props, ref) => {
2005
+ const { as: Component = 'div', span, sm, md, lg, xl, xxl, grow, shrink, order, className, style, children, ...restProps } = props;
2006
+ const { isAutoFit } = React.useContext(GridContext);
2007
+ 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);
2008
+ return (jsxRuntime.jsx(Component, { ref: ref, className: classes, style: { ...resolveOrderStyle(order), ...style }, ...restProps, children: children }));
2009
+ });
2010
+ GridCol.displayName = 'Grid.Col';
2011
+ const Grid = React.forwardRef((props, ref) => {
2012
+ 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;
2013
+ const isAutoFit = Boolean(!flex && minColWidth);
2014
+ 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 &&
2015
+ !minColWidth &&
2016
+ (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);
2017
+ const gridTemplateColumns = !flex && minColWidth
2018
+ ? `repeat(${autoFit ? 'auto-fit' : 'auto-fill'}, minmax(${minColWidth}, 1fr))`
2019
+ : undefined;
2020
+ return (jsxRuntime.jsx(GridContext.Provider, { value: { isAutoFit }, children: jsxRuntime.jsx(Component, { ref: ref, className: classes, style: gridTemplateColumns ? { gridTemplateColumns, ...style } : style, ...restProps, children: children }) }));
2021
+ });
2022
+ Grid.Col = GridCol;
2023
+ Grid.Item = GridCol;
2024
+ Grid.displayName = 'Grid';
2025
+
2026
+ const sizeClasses$4 = {
2027
+ sm: {
2028
+ input: 'px-2.5 py-1.5 text-xs leading-5',
2029
+ group: 'w-8 text-xs',
2030
+ icon: 'size-3.5',
2031
+ text: 'text-xs',
2032
+ },
2033
+ md: {
2034
+ input: 'px-3.5 py-2 text-sm leading-6',
2035
+ group: 'w-10 text-sm',
1548
2036
  icon: 'size-4',
1549
2037
  text: 'text-sm',
1550
2038
  },
@@ -1559,9 +2047,9 @@ function buildInputClass(className, { isFocusWithin = false, disabled = false, h
1559
2047
  const currentSize = sizeClasses$4[size] || sizeClasses$4.md;
1560
2048
  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
1561
2049
  ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
1562
- : 'outline-gray-300 dark:outline-gray-600', disabled
1563
- ? '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'
1564
- : 'bg-white dark:bg-gray-700 dark:text-white outline-gray-300 dark:outline-gray-600 dark:placeholder-gray-400 placeholder-gray-400', isFocusWithin
2050
+ : 'outline-[var(--ui-border)]', disabled
2051
+ ? '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)]'
2052
+ : 'bg-white dark:bg-gray-700 dark:text-white outline-[var(--ui-border)] dark:placeholder-gray-400 placeholder-gray-400', isFocusWithin
1565
2053
  ? 'focus-within:outline-[var(--ui-focus-ring)] focus-within:outline-2 focus-within:-outline-offset-2'
1566
2054
  : 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', className);
1567
2055
  }
@@ -1599,11 +2087,11 @@ const Input = React.forwardRef((props, ref) => {
1599
2087
  const actualRightGroup = rightGroup !== null && rightGroup !== void 0 ? rightGroup : (showClearButton ? (jsxRuntime.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: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: currentSize.icon, children: jsxRuntime.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);
1600
2088
  const hasRightGroup = actualRightGroup !== null && actualRightGroup !== undefined;
1601
2089
  const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
1602
- return (jsxRuntime.jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsxRuntime.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 })), jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsxRuntime.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 })), jsxRuntime.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, {
2090
+ return (jsxRuntime.jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsxRuntime.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 })), jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsxRuntime.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 })), jsxRuntime.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, {
1603
2091
  disabled: inputProps.disabled,
1604
2092
  hasError,
1605
2093
  size,
1606
- }), 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 && (jsxRuntime.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 && (jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
2094
+ }), 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 && (jsxRuntime.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 && (jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
1607
2095
  ? 'text-red-500 font-semibold'
1608
2096
  : 'text-gray-400 dark:text-gray-500'), children: [charLength, maxLength ? ` / ${maxLength}` : ''] }))] })) : null] }));
1609
2097
  });
@@ -1653,6 +2141,170 @@ const PasswordInput = React.forwardRef((props, ref) => {
1653
2141
  });
1654
2142
  PasswordInput.displayName = 'PasswordInput';
1655
2143
 
2144
+ function PinInput({ length = 4, value: externalValue, onChange, onComplete, mask = false, size = 'md', type = 'numeric', error, disabled = false, autoFocus = false, containerClass = '', inputClass = '', }) {
2145
+ const [internalValue, setInternalValue] = React.useState('');
2146
+ const inputRefs = React.useRef([]);
2147
+ const pinValue = externalValue !== undefined ? externalValue : internalValue;
2148
+ const digits = Array.from({ length }, (_, i) => pinValue[i] || '');
2149
+ React.useEffect(() => {
2150
+ if (autoFocus && inputRefs.current[0] && !disabled) {
2151
+ inputRefs.current[0].focus();
2152
+ }
2153
+ }, [autoFocus, disabled]);
2154
+ const updatePin = (newDigits) => {
2155
+ const newPin = newDigits.join('').slice(0, length);
2156
+ setInternalValue(newPin);
2157
+ onChange === null || onChange === void 0 ? void 0 : onChange(newPin);
2158
+ if (newPin.length === length) {
2159
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(newPin);
2160
+ }
2161
+ };
2162
+ const handleInputChange = (e, index) => {
2163
+ var _a;
2164
+ const char = e.target.value.slice(-1);
2165
+ if (!char)
2166
+ return;
2167
+ const isValid = type === 'numeric' ? /^[0-9]$/.test(char) : /^[a-zA-Z0-9]$/.test(char);
2168
+ if (!isValid)
2169
+ return;
2170
+ const nextDigits = [...digits];
2171
+ nextDigits[index] = char;
2172
+ updatePin(nextDigits);
2173
+ if (index < length - 1 && inputRefs.current[index + 1]) {
2174
+ (_a = inputRefs.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
2175
+ }
2176
+ };
2177
+ const handleKeyDown = (e, index) => {
2178
+ var _a, _b, _c;
2179
+ if (e.key === 'Backspace') {
2180
+ if (!digits[index] && index > 0 && inputRefs.current[index - 1]) {
2181
+ const nextDigits = [...digits];
2182
+ nextDigits[index - 1] = '';
2183
+ updatePin(nextDigits);
2184
+ (_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
2185
+ }
2186
+ else if (digits[index]) {
2187
+ const nextDigits = [...digits];
2188
+ nextDigits[index] = '';
2189
+ updatePin(nextDigits);
2190
+ }
2191
+ }
2192
+ else if (e.key === 'ArrowLeft' && index > 0) {
2193
+ (_b = inputRefs.current[index - 1]) === null || _b === void 0 ? void 0 : _b.focus();
2194
+ }
2195
+ else if (e.key === 'ArrowRight' && index < length - 1) {
2196
+ (_c = inputRefs.current[index + 1]) === null || _c === void 0 ? void 0 : _c.focus();
2197
+ }
2198
+ };
2199
+ const handlePaste = (e) => {
2200
+ e.preventDefault();
2201
+ if (disabled)
2202
+ return;
2203
+ const pastedData = e.clipboardData.getData('text').trim();
2204
+ const regex = type === 'numeric' ? /[0-9]/g : /[a-zA-Z0-9]/g;
2205
+ const matchedChars = pastedData.match(regex) || [];
2206
+ if (matchedChars.length === 0)
2207
+ return;
2208
+ const nextDigits = Array.from({ length }, (_, i) => matchedChars[i] || '');
2209
+ updatePin(nextDigits);
2210
+ const focusIndex = Math.min(matchedChars.length, length) - 1;
2211
+ const targetRef = inputRefs.current[focusIndex >= 0 ? focusIndex : 0];
2212
+ targetRef === null || targetRef === void 0 ? void 0 : targetRef.focus();
2213
+ };
2214
+ const sizeClasses = {
2215
+ sm: 'size-9 text-sm rounded-lg',
2216
+ md: 'size-11 text-base rounded-xl',
2217
+ lg: 'size-14 text-lg rounded-2xl',
2218
+ }[size];
2219
+ return (jsxRuntime.jsxs("div", { className: buildClassName('space-y-1.5', containerClass), "data-testid": "pin-input-container", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2.5 sm:gap-3", children: digits.map((digit, index) => {
2220
+ const isFilled = Boolean(digit);
2221
+ return (jsxRuntime.jsx("input", { ref: (el) => {
2222
+ inputRefs.current[index] = el;
2223
+ }, 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
2224
+ ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-600 outline-[var(--ui-border-muted)]'
2225
+ : error
2226
+ ? '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'
2227
+ : isFilled
2228
+ ? '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'
2229
+ : '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));
2230
+ }) }), typeof error === 'string' && (jsxRuntime.jsx("div", { className: "text-xs text-red-500 dark:text-red-400 font-medium pt-0.5", "data-testid": "pin-input-error", children: error }))] }));
2231
+ }
2232
+ PinInput.displayName = 'PinInput';
2233
+
2234
+ function PullArrowIcon({ progress }) {
2235
+ const rotation = Math.min(180, progress * 180);
2236
+ return (jsxRuntime.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: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 14l-7 7m0 0l-7-7m7 7V3" }) }));
2237
+ }
2238
+ function PullToRefresh({ onRefresh, pullThreshold = 70, maxPullDistance = 120, disabled = false, refreshing: externalRefreshing, pullingContent, refreshingContent, children, className = '', contentClass = '', }) {
2239
+ const containerRef = React.useRef(null);
2240
+ const startYRef = React.useRef(0);
2241
+ const isPullingRef = React.useRef(false);
2242
+ const [pullDistance, setPullDistance] = React.useState(0);
2243
+ const [internalRefreshing, setInternalRefreshing] = React.useState(false);
2244
+ const isRefreshing = externalRefreshing !== undefined ? externalRefreshing : internalRefreshing;
2245
+ const handleTouchStart = React.useCallback((e) => {
2246
+ if (disabled || isRefreshing)
2247
+ return;
2248
+ const container = containerRef.current;
2249
+ if (container && container.scrollTop === 0) {
2250
+ startYRef.current = e.touches[0].clientY;
2251
+ isPullingRef.current = true;
2252
+ }
2253
+ }, [disabled, isRefreshing]);
2254
+ const handleTouchMove = React.useCallback((e) => {
2255
+ if (!isPullingRef.current || disabled || isRefreshing)
2256
+ return;
2257
+ const container = containerRef.current;
2258
+ if (!container || container.scrollTop > 0)
2259
+ return;
2260
+ const currentY = e.touches[0].clientY;
2261
+ const rawDistance = currentY - startYRef.current;
2262
+ if (rawDistance > 0) {
2263
+ // Rubber-band resistance formula
2264
+ const dampened = Math.min(maxPullDistance, rawDistance * 0.45);
2265
+ setPullDistance(dampened);
2266
+ if (e.cancelable) {
2267
+ e.preventDefault();
2268
+ }
2269
+ }
2270
+ else {
2271
+ setPullDistance(0);
2272
+ }
2273
+ }, [disabled, isRefreshing, maxPullDistance]);
2274
+ const handleTouchEnd = React.useCallback(async () => {
2275
+ if (!isPullingRef.current || disabled || isRefreshing)
2276
+ return;
2277
+ isPullingRef.current = false;
2278
+ if (pullDistance >= pullThreshold) {
2279
+ setPullDistance(pullThreshold);
2280
+ setInternalRefreshing(true);
2281
+ try {
2282
+ await onRefresh();
2283
+ }
2284
+ finally {
2285
+ setInternalRefreshing(false);
2286
+ setPullDistance(0);
2287
+ }
2288
+ }
2289
+ else {
2290
+ setPullDistance(0);
2291
+ }
2292
+ }, [disabled, isRefreshing, onRefresh, pullDistance, pullThreshold]);
2293
+ const progress = Math.min(1, pullDistance / pullThreshold);
2294
+ const isReady = pullDistance >= pullThreshold;
2295
+ return (jsxRuntime.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: [jsxRuntime.jsx("div", { className: "left-0 right-0 top-0 flex items-center justify-center pointer-events-none transition-all duration-150 z-20", style: {
2296
+ height: isRefreshing ? `${pullThreshold}px` : `${pullDistance}px`,
2297
+ opacity: pullDistance > 0 || isRefreshing ? 1 : 0,
2298
+ }, "data-testid": "pull-to-refresh-indicator", children: jsxRuntime.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 || (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Loader, { size: "sm" }), jsxRuntime.jsx("span", { children: "Refreshing..." })] }))) : pullingContent ? (pullingContent) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PullArrowIcon, { progress: progress }), jsxRuntime.jsx("span", { children: isReady ? 'Release to refresh' : 'Pull down to refresh' })] })) }) }), jsxRuntime.jsx("div", { className: buildClassName('transition-transform duration-150', contentClass), style: {
2299
+ transform: isRefreshing
2300
+ ? `translateY(${pullThreshold}px)`
2301
+ : pullDistance > 0
2302
+ ? `translateY(${pullDistance}px)`
2303
+ : 'translateY(0px)',
2304
+ }, "data-testid": "pull-to-refresh-content", children: children })] }));
2305
+ }
2306
+ PullToRefresh.displayName = 'PullToRefresh';
2307
+
1656
2308
  const SIZE_MAP = {
1657
2309
  sm: 'size-4',
1658
2310
  md: 'size-4.5',
@@ -1668,8 +2320,8 @@ const Radio = React.forwardRef((props, ref) => {
1668
2320
  const generatedId = React.useId();
1669
2321
  const radioId = id !== null && id !== void 0 ? id : (name && rest.value ? `${name}-${rest.value}` : generatedId);
1670
2322
  return (jsxRuntime.jsxs("div", { className: buildClassName(wrapperClass), children: [jsxRuntime.jsxs("div", { className: buildClassName('flex items-start gap-2.5', containerClass), children: [jsxRuntime.jsx("div", { className: "grid place-items-center shrink-0 pt-0.5", children: jsxRuntime.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
1671
- ? 'border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 pointer-events-none'
1672
- : '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) && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsxRuntime.jsx(Label, { htmlFor: radioId, className: buildClassName(disabled
2323
+ ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'
2324
+ : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer', className) }) }), (label || description) && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsxRuntime.jsx(Label, { htmlFor: radioId, className: buildClassName(disabled
1673
2325
  ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'
1674
2326
  : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium', labelClass), children: label })), description && (jsxRuntime.jsx("p", { className: buildClassName('text-xs leading-normal', disabled
1675
2327
  ? 'text-gray-300 dark:text-gray-600'
@@ -1708,7 +2360,7 @@ const RadioGroup = (props) => {
1708
2360
  if (isCards) {
1709
2361
  return (jsxRuntime.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
1710
2362
  ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'
1711
- : 'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
2363
+ : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
1712
2364
  'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsxRuntime.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" }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsxRuntime.jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsxRuntime.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
1713
2365
  }
1714
2366
  return (jsxRuntime.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));
@@ -1803,7 +2455,7 @@ const RadioSwitch = ({ label, items, selected, size = 'md', theme = 'primary', d
1803
2455
  onChange(getValue(nextItem));
1804
2456
  }
1805
2457
  };
1806
- return (jsxRuntime.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: [jsxRuntime.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: {
2458
+ return (jsxRuntime.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: [jsxRuntime.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: {
1807
2459
  transform: `translate(${style.left}px, ${style.top}px)`,
1808
2460
  width: style.width,
1809
2461
  height: style.height,
@@ -1983,155 +2635,1112 @@ const RangeSlider = ({ label, labelHint, labelClass = '', containerClass = '', c
1983
2635
  window.addEventListener('pointermove', stablePointerMoveRef.current);
1984
2636
  window.addEventListener('pointerup', stablePointerUpRef.current);
1985
2637
  };
1986
- const handleTrackClick = (e) => {
1987
- if (!trackRef.current)
2638
+ const handleTrackClick = (e) => {
2639
+ if (!trackRef.current)
2640
+ return;
2641
+ const rect = trackRef.current.getBoundingClientRect();
2642
+ const x = Math.min(Math.max(e.clientX - rect.left, 0), rect.width);
2643
+ const rawVal = min + (x / rect.width) * (max - min);
2644
+ const snappedVal = snapToStep(rawVal);
2645
+ const pxMin = (percent(valueMin) / 100) * rect.width;
2646
+ const pxMax = (percent(valueMax) / 100) * rect.width;
2647
+ if (x <= pxMin) {
2648
+ onChange(Math.min(snappedVal, valueMax - step), valueMax);
2649
+ return;
2650
+ }
2651
+ if (x >= pxMax) {
2652
+ onChange(valueMin, Math.max(snappedVal, valueMin + step));
2653
+ return;
2654
+ }
2655
+ const distMin = Math.abs(snappedVal - valueMin);
2656
+ const distMax = Math.abs(snappedVal - valueMax);
2657
+ if (distMin < distMax) {
2658
+ onChange(Math.min(snappedVal, valueMax - step), valueMax);
2659
+ }
2660
+ else {
2661
+ onChange(valueMin, Math.max(snappedVal, valueMin + step));
2662
+ }
2663
+ };
2664
+ // Keyboard accessibility handler for thumbs
2665
+ const handleKeyDown = (thumb) => (e) => {
2666
+ let delta = 0;
2667
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowDown')
2668
+ delta = -step;
2669
+ else if (e.key === 'ArrowRight' || e.key === 'ArrowUp')
2670
+ delta = step;
2671
+ else if (e.key === 'Home') {
2672
+ if (thumb === 'min')
2673
+ onChange(min, valueMax);
2674
+ else
2675
+ onChange(valueMin, valueMin + step);
2676
+ return;
2677
+ }
2678
+ else if (e.key === 'End') {
2679
+ if (thumb === 'min')
2680
+ onChange(valueMax - step, valueMax);
2681
+ else
2682
+ onChange(valueMin, max);
2683
+ return;
2684
+ }
2685
+ if (delta !== 0) {
2686
+ e.preventDefault();
2687
+ if (thumb === 'min') {
2688
+ const next = snapToStep(valueMin + delta);
2689
+ onChange(Math.min(next, valueMax - step), valueMax);
2690
+ }
2691
+ else {
2692
+ const next = snapToStep(valueMax + delta);
2693
+ onChange(valueMin, Math.max(next, valueMin + step));
2694
+ }
2695
+ }
2696
+ };
2697
+ const markEntries = marks
2698
+ ? Object.entries(marks).map(([k, v]) => ({ value: Number(k), label: v }))
2699
+ : null;
2700
+ return (jsxRuntime.jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [jsxRuntime.jsx(Label, { className: labelClass, children: label }), labelHint] })), jsxRuntime.jsxs("div", { ref: trackRef, onMouseDown: handleTrackClick, className: "relative h-8 select-none w-full flex items-center cursor-pointer", "data-testid": "range-track", children: [jsxRuntime.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) }), jsxRuntime.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: {
2701
+ left: `${percent(valueMin)}%`,
2702
+ width: `${percent(valueMax) - percent(valueMin)}%`,
2703
+ } }), jsxRuntime.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') &&
2704
+ (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2705
+ left: `calc(${percent(valueMin)}% - ${currentSize.thumbPx / 2}px)`,
2706
+ zIndex: activeThumbState === 'min' ? 50 : 30,
2707
+ }, "data-testid": "thumb-min", children: showTooltips && (activeThumbState === 'min' || hoveringThumb === 'min') && (jsxRuntime.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, jsxRuntime.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" })] })) }), jsxRuntime.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') &&
2708
+ (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2709
+ left: `calc(${percent(valueMax)}% - ${currentSize.thumbPx / 2}px)`,
2710
+ zIndex: activeThumbState === 'max' ? 50 : 40,
2711
+ }, "data-testid": "thumb-max", children: showTooltips && (activeThumbState === 'max' || hoveringThumb === 'max') && (jsxRuntime.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, jsxRuntime.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 && (jsxRuntime.jsx("div", { className: "relative w-full h-4 mt-1", children: markEntries.map((m) => {
2712
+ const markPercent = percent(m.value);
2713
+ return (jsxRuntime.jsxs("div", { className: "absolute top-0 transform -translate-x-1/2 flex flex-col items-center", style: { left: `${markPercent}%` }, children: [jsxRuntime.jsx("span", { className: "w-1 h-1.5 bg-gray-300 dark:bg-gray-600 rounded-full" }), jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-gray-400 dark:text-gray-500 mt-0.5", children: m.label })] }, m.value));
2714
+ }) })), jsxRuntime.jsxs("div", { className: buildClassName('flex justify-between font-medium text-gray-700 dark:text-gray-300', currentSize.text), children: [jsxRuntime.jsxs("span", { children: [Math.round(valueMin), valueSuffix] }), jsxRuntime.jsxs("span", { children: [Math.round(valueMax), valueSuffix] })] }), (showErrorMessage && hasError) || helperText ? (jsxRuntime.jsx("div", { className: "mt-1", children: showErrorMessage && hasError ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null })) : null] }));
2715
+ };
2716
+ RangeSlider.displayName = 'RangeSlider';
2717
+
2718
+ const useDebounce = (value, delay) => {
2719
+ const [debouncedValue, setDebouncedValue] = React.useState(value);
2720
+ React.useEffect(() => {
2721
+ const handler = setTimeout(() => {
2722
+ setDebouncedValue(value);
2723
+ }, delay);
2724
+ // Cancel the timeout if value or delay changes
2725
+ return () => {
2726
+ clearTimeout(handler);
2727
+ };
2728
+ }, [value, delay]);
2729
+ return debouncedValue;
2730
+ };
2731
+ const useDebounceFn = (fn, ms) => {
2732
+ const timeout = React.useRef(null);
2733
+ React.useEffect(() => {
2734
+ return () => clearTimeout(timeout.current);
2735
+ }, []);
2736
+ return React.useCallback((...args) => {
2737
+ clearTimeout(timeout.current);
2738
+ timeout.current = setTimeout(() => fn(...args), ms);
2739
+ }, [fn, ms]);
2740
+ };
2741
+
2742
+ var _path$2;
2743
+ 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); }
2744
+ var SvgCheck = function SvgCheck(props) {
2745
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$2({
2746
+ xmlns: "http://www.w3.org/2000/svg",
2747
+ width: 24,
2748
+ height: 24,
2749
+ fill: "none",
2750
+ stroke: "currentColor",
2751
+ strokeLinecap: "round",
2752
+ strokeLinejoin: "round",
2753
+ strokeWidth: 2,
2754
+ className: "lucide lucide-check-icon lucide-check",
2755
+ viewBox: "0 0 24 24"
2756
+ }, props), _path$2 || (_path$2 = /*#__PURE__*/React__namespace.createElement("path", {
2757
+ d: "M20 6 9 17l-5-5"
2758
+ })));
2759
+ };
2760
+
2761
+ var _circle$1, _path$1;
2762
+ 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); }
2763
+ var SvgCirclePlus = function SvgCirclePlus(props) {
2764
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
2765
+ xmlns: "http://www.w3.org/2000/svg",
2766
+ width: 24,
2767
+ height: 24,
2768
+ fill: "none",
2769
+ stroke: "currentColor",
2770
+ strokeLinecap: "round",
2771
+ strokeLinejoin: "round",
2772
+ strokeWidth: 2,
2773
+ className: "lucide lucide-circle-plus-icon lucide-circle-plus",
2774
+ viewBox: "0 0 24 24"
2775
+ }, props), _circle$1 || (_circle$1 = /*#__PURE__*/React__namespace.createElement("circle", {
2776
+ cx: 12,
2777
+ cy: 12,
2778
+ r: 10
2779
+ })), _path$1 || (_path$1 = /*#__PURE__*/React__namespace.createElement("path", {
2780
+ d: "M8 12h8M12 8v8"
2781
+ })));
2782
+ };
2783
+
2784
+ var _circle, _path;
2785
+ 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); }
2786
+ var SvgSearch = function SvgSearch(props) {
2787
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends({
2788
+ xmlns: "http://www.w3.org/2000/svg",
2789
+ width: 24,
2790
+ height: 24,
2791
+ fill: "none",
2792
+ stroke: "currentColor",
2793
+ strokeLinecap: "round",
2794
+ strokeLinejoin: "round",
2795
+ strokeWidth: 2,
2796
+ className: "lucide lucide-search-icon lucide-search",
2797
+ viewBox: "0 0 24 24"
2798
+ }, props), _circle || (_circle = /*#__PURE__*/React__namespace.createElement("circle", {
2799
+ cx: 11,
2800
+ cy: 11,
2801
+ r: 8
2802
+ })), _path || (_path = /*#__PURE__*/React__namespace.createElement("path", {
2803
+ d: "m21 21-4.3-4.3"
2804
+ })));
2805
+ };
2806
+
2807
+ const sizeConfigMap = {
2808
+ sm: {
2809
+ input: 'h-8 text-xs px-2.5',
2810
+ icon: 'size-3.5',
2811
+ badgeSize: 'sm',
2812
+ group: 'w-8',
2813
+ },
2814
+ md: {
2815
+ input: 'h-10 text-sm px-3',
2816
+ icon: 'size-4',
2817
+ badgeSize: 'md',
2818
+ group: 'w-10',
2819
+ },
2820
+ lg: {
2821
+ input: 'h-12 text-base px-3.5',
2822
+ icon: 'size-5',
2823
+ badgeSize: 'md',
2824
+ group: 'w-12',
2825
+ },
2826
+ };
2827
+ function MobilePicker(props) {
2828
+ 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;
2829
+ const [isOpen, setIsOpen] = React.useState(false);
2830
+ const [query, setQuery] = React.useState('');
2831
+ const debouncedQuery = useDebounce(query, 400);
2832
+ const [optionsLoading, setOptionsLoading] = React.useState(false);
2833
+ const [draftSelected, setDraftSelected] = React.useState(selected);
2834
+ const [viewportHeight, setViewportHeight] = React.useState(null);
2835
+ React.useEffect(() => {
2836
+ if (!isOpen) {
2837
+ setViewportHeight(null);
2838
+ return;
2839
+ }
2840
+ const updateHeight = () => {
2841
+ if (typeof window !== 'undefined' && window.visualViewport) {
2842
+ setViewportHeight(window.visualViewport.height);
2843
+ }
2844
+ };
2845
+ updateHeight();
2846
+ const vv = typeof window !== 'undefined' ? window.visualViewport : null;
2847
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('resize', updateHeight);
2848
+ vv === null || vv === void 0 ? void 0 : vv.addEventListener('scroll', updateHeight);
2849
+ return () => {
2850
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('resize', updateHeight);
2851
+ vv === null || vv === void 0 ? void 0 : vv.removeEventListener('scroll', updateHeight);
2852
+ };
2853
+ }, [isOpen]);
2854
+ const currentSize = sizeConfigMap[size] || sizeConfigMap.md;
2855
+ const hasError = Boolean(error);
2856
+ const isAsyncLoading = loading || optionsLoading;
2857
+ const baseInputClass = React.useMemo(() => buildInputClass('', { disabled, hasError, size }), [disabled, hasError, size]);
2858
+ const onSearchRef = React.useRef(onSearch);
2859
+ React.useEffect(() => {
2860
+ onSearchRef.current = onSearch;
2861
+ }, [onSearch]);
2862
+ const handleAsyncSearch = React.useCallback(async (searchString) => {
2863
+ var _a;
2864
+ try {
2865
+ setOptionsLoading(true);
2866
+ await ((_a = onSearchRef.current) === null || _a === void 0 ? void 0 : _a.call(onSearchRef, searchString));
2867
+ }
2868
+ catch (err) {
2869
+ console.error('Error loading options:', err);
2870
+ }
2871
+ finally {
2872
+ setOptionsLoading(false);
2873
+ }
2874
+ }, []);
2875
+ React.useEffect(() => {
2876
+ if (isOpen && async) {
2877
+ handleAsyncSearch(debouncedQuery);
2878
+ }
2879
+ }, [isOpen, async, debouncedQuery, handleAsyncSearch]);
2880
+ const getDisplayValue = React.useCallback((opt) => {
2881
+ var _a, _b;
2882
+ if (typeof opt === 'string')
2883
+ return opt;
2884
+ 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);
2885
+ }, [labelKey, valueKey]);
2886
+ const getValue = React.useCallback((opt) => {
2887
+ var _a, _b;
2888
+ if (typeof opt === 'string')
2889
+ return opt;
2890
+ 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);
2891
+ }, [valueKey, labelKey]);
2892
+ const normalizedSelected = React.useMemo(() => {
2893
+ if (multiple) {
2894
+ if (Array.isArray(selected))
2895
+ return selected;
2896
+ if (selected !== null && selected !== undefined)
2897
+ return [selected];
2898
+ return [];
2899
+ }
2900
+ else {
2901
+ if (Array.isArray(selected))
2902
+ return selected.length > 0 ? selected[0] : null;
2903
+ return selected !== null && selected !== void 0 ? selected : null;
2904
+ }
2905
+ }, [multiple, selected]);
2906
+ const normalizedDraft = React.useMemo(() => {
2907
+ if (multiple) {
2908
+ if (Array.isArray(draftSelected))
2909
+ return draftSelected;
2910
+ if (draftSelected !== null && draftSelected !== undefined)
2911
+ return [draftSelected];
2912
+ return [];
2913
+ }
2914
+ else {
2915
+ if (Array.isArray(draftSelected))
2916
+ return draftSelected.length > 0 ? draftSelected[0] : null;
2917
+ return draftSelected !== null && draftSelected !== void 0 ? draftSelected : null;
2918
+ }
2919
+ }, [multiple, draftSelected]);
2920
+ const rawAllOptions = React.useMemo(() => {
2921
+ if (groups === null || groups === void 0 ? void 0 : groups.length) {
2922
+ return groups.flatMap((g) => g.options);
2923
+ }
2924
+ return options !== null && options !== void 0 ? options : [];
2925
+ }, [groups, options]);
2926
+ const allOptions = React.useMemo(() => {
2927
+ const list = [...rawAllOptions];
2928
+ const selectedList = Array.isArray(normalizedDraft)
2929
+ ? normalizedDraft
2930
+ : normalizedDraft
2931
+ ? [normalizedDraft]
2932
+ : [];
2933
+ for (const sel of selectedList) {
2934
+ if (sel !== null && sel !== undefined) {
2935
+ const selVal = getValue(sel);
2936
+ const exists = list.some((item) => getValue(item) === selVal);
2937
+ if (!exists) {
2938
+ list.unshift(sel);
2939
+ }
2940
+ }
2941
+ }
2942
+ return list;
2943
+ }, [rawAllOptions, normalizedDraft, getValue]);
2944
+ React.useEffect(() => {
2945
+ if (isOpen) {
2946
+ setDraftSelected(normalizedSelected);
2947
+ setQuery('');
2948
+ }
2949
+ }, [isOpen, normalizedSelected]);
2950
+ const defaultFilter = React.useCallback((opt, q) => {
2951
+ var _a;
2952
+ if (!q.trim())
2953
+ return true;
2954
+ const searchTarget = ((_a = getDisplayValue(opt)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
2955
+ return searchTarget.includes(q.trim().toLowerCase());
2956
+ }, [getDisplayValue]);
2957
+ const activeFilter = filterOption || defaultFilter;
2958
+ const filteredOptions = React.useMemo(() => {
2959
+ if (async)
2960
+ return allOptions;
2961
+ if (!query.trim())
2962
+ return allOptions;
2963
+ return allOptions.filter((opt) => activeFilter(opt, query));
2964
+ }, [allOptions, query, async, activeFilter]);
2965
+ const filteredGroups = React.useMemo(() => {
2966
+ if (!(groups === null || groups === void 0 ? void 0 : groups.length))
2967
+ return null;
2968
+ if (async)
2969
+ return groups;
2970
+ if (!query.trim())
2971
+ return groups;
2972
+ return groups
2973
+ .map((g) => ({
2974
+ ...g,
2975
+ options: g.options.filter((opt) => activeFilter(opt, query)),
2976
+ }))
2977
+ .filter((g) => g.options.length > 0);
2978
+ }, [groups, query, async, activeFilter]);
2979
+ const createFreeTextOption = React.useCallback((text) => {
2980
+ const sample = allOptions[0] || (Array.isArray(selected) ? selected[0] : selected);
2981
+ if (typeof sample === 'string' ||
2982
+ (!sample && typeof labelKey === 'string' && labelKey === 'label')) {
2983
+ return text;
2984
+ }
2985
+ return {
2986
+ [labelKey]: text,
2987
+ [valueKey]: text,
2988
+ };
2989
+ }, [allOptions, selected, labelKey, valueKey]);
2990
+ const handleToggleOption = (option) => {
2991
+ const optVal = getValue(option);
2992
+ if (multiple) {
2993
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
2994
+ const index = current.findIndex((item) => getValue(item) === optVal);
2995
+ if (index > -1) {
2996
+ current.splice(index, 1);
2997
+ setDraftSelected(current);
2998
+ }
2999
+ else {
3000
+ if (maxSelection && current.length >= maxSelection)
3001
+ return;
3002
+ current.push(option);
3003
+ setDraftSelected(current);
3004
+ }
3005
+ }
3006
+ else {
3007
+ setDraftSelected(option);
3008
+ onChange(option);
3009
+ setIsOpen(false);
3010
+ }
3011
+ };
3012
+ const handleCommitFreeText = (text) => {
3013
+ const trimmed = text.trim();
3014
+ if (!trimmed)
3015
+ return;
3016
+ const existing = allOptions.find((opt) => getDisplayValue(opt).toLowerCase() === trimmed.toLowerCase());
3017
+ const optionToCommit = existing || createFreeTextOption(trimmed);
3018
+ if (multiple) {
3019
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
3020
+ const already = current.some((item) => getDisplayValue(item).toLowerCase() === trimmed.toLowerCase());
3021
+ if (!already) {
3022
+ if (maxSelection && current.length >= maxSelection)
3023
+ return;
3024
+ current.push(optionToCommit);
3025
+ setDraftSelected(current);
3026
+ }
3027
+ setQuery('');
3028
+ }
3029
+ else {
3030
+ setDraftSelected(optionToCommit);
3031
+ onChange(optionToCommit);
3032
+ setIsOpen(false);
3033
+ }
3034
+ };
3035
+ const handleAddAndSelect = async (valueToAdd) => {
3036
+ try {
3037
+ const result = await onAdd(valueToAdd);
3038
+ const optionToCommit = (result || valueToAdd);
3039
+ if (multiple) {
3040
+ const current = Array.isArray(normalizedDraft) ? [...normalizedDraft] : [];
3041
+ current.push(optionToCommit);
3042
+ setDraftSelected(current);
3043
+ setQuery('');
3044
+ }
3045
+ else {
3046
+ setDraftSelected(optionToCommit);
3047
+ onChange(optionToCommit);
3048
+ setIsOpen(false);
3049
+ }
3050
+ }
3051
+ catch (err) {
3052
+ console.error('MobilePicker onAdd error:', err);
3053
+ }
3054
+ };
3055
+ const isAllSelected = React.useMemo(() => {
3056
+ if (!multiple || !Array.isArray(normalizedDraft) || !allOptions.length)
3057
+ return false;
3058
+ return allOptions.length === normalizedDraft.length;
3059
+ }, [multiple, normalizedDraft, allOptions]);
3060
+ const handleToggleSelectAll = () => {
3061
+ if (isAllSelected) {
3062
+ setDraftSelected([]);
3063
+ }
3064
+ else {
3065
+ setDraftSelected(allOptions);
3066
+ }
3067
+ };
3068
+ const handleConfirmMultiSelect = () => {
3069
+ onChange(normalizedDraft);
3070
+ setIsOpen(false);
3071
+ };
3072
+ const handleClearSingleSelect = (e) => {
3073
+ e.preventDefault();
3074
+ e.stopPropagation();
3075
+ setDraftSelected(multiple ? [] : null);
3076
+ onChange(multiple ? [] : null);
3077
+ };
3078
+ const handleTriggerClick = (e) => {
3079
+ if (disabled)
3080
+ return;
3081
+ const isClearClick = e.target.closest('[data-testid="mobile-picker-clear-button"]');
3082
+ if (isClearClick)
3083
+ return;
3084
+ setIsOpen(true);
3085
+ };
3086
+ const isOptionSelected = (option) => {
3087
+ const optVal = getValue(option);
3088
+ if (multiple) {
3089
+ return (Array.isArray(normalizedDraft) && normalizedDraft.some((item) => getValue(item) === optVal));
3090
+ }
3091
+ else {
3092
+ return Boolean(normalizedDraft && getValue(normalizedDraft) === optVal);
3093
+ }
3094
+ };
3095
+ const shouldShowTypeToSearch = async && !query && !isAsyncLoading && allOptions.length === 0;
3096
+ const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
3097
+ return (jsxRuntime.jsxs("div", { className: buildClassName('group space-y-2 w-full', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.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 && (jsxRuntime.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 })), jsxRuntime.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) => (jsxRuntime.jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, children: getDisplayValue(item) }, `${getValue(item)}-${idx}`)))) : (jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children: placeholder }))) : normalizedSelected ? (jsxRuntime.jsx("span", { className: "text-gray-900 dark:text-white font-normal truncate", children: getDisplayValue(normalizedSelected) })) : (jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children: placeholder })) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [allowClear && !multiple && normalizedSelected && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-3.5 stroke-gray-500 dark:stroke-gray-400" }) })), jsxRuntime.jsx(SvgChevronDown, { className: buildClassName(currentSize.icon, 'stroke-gray-500 shrink-0') })] })] }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText }) })), jsxRuntime.jsxs(react.Dialog, { open: isOpen, as: "div", className: "relative z-50 focus:outline-none", onClose: () => setIsOpen(false), transition: true, children: [jsxRuntime.jsx(react.DialogBackdrop, { className: "fixed inset-0 bg-black/50 backdrop-blur-xs transition-opacity duration-200" }), jsxRuntime.jsx("div", { className: "fixed left-0 top-0 w-full flex items-end justify-center pointer-events-none z-50", style: {
3098
+ height: viewportHeight ? `${viewportHeight}px` : '100dvh',
3099
+ }, children: jsxRuntime.jsxs(react.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: {
3100
+ maxHeight: viewportHeight ? `${Math.floor(viewportHeight * 0.9)}px` : undefined,
3101
+ }, "data-testid": "mobile-picker-sheet", children: [jsxRuntime.jsx("div", { className: "w-12 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700 mx-auto my-2.5 shrink-0" }), jsxRuntime.jsxs("div", { className: "px-4 pb-3 border-b border-[var(--ui-border-muted)] flex items-center justify-between gap-3 shrink-0", children: [jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [jsxRuntime.jsx(react.DialogTitle, { as: "h3", className: "text-base md:text-lg font-bold text-gray-900 dark:text-white truncate", children: title || label || 'Select Option' }), description && (jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 truncate mt-0.5", children: description }))] }), jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4" }) })] }), searchable && (jsxRuntime.jsx("div", { className: "p-3 border-b border-[var(--ui-border-muted)] bg-gray-50 dark:bg-gray-800/50 shrink-0", children: jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsx(SvgSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-gray-400" }), jsxRuntime.jsx("input", { type: "text", value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: (e) => {
3102
+ if (allowFreeText && e.key === 'Enter' && query.trim()) {
3103
+ e.preventDefault();
3104
+ handleCommitFreeText(query);
3105
+ }
3106
+ }, 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" }), jsxRuntime.jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1.5", children: isAsyncLoading ? (jsxRuntime.jsx(Loader, { size: "xs" })) : (query && (jsxRuntime.jsx("button", { type: "button", onClick: () => setQuery(''), className: "p-0.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200", children: jsxRuntime.jsx(SvgX, { className: "size-3.5" }) }))) })] }) })), quickOptions && quickOptions.length > 0 && (jsxRuntime.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: [jsxRuntime.jsx("div", { className: "text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-1.5 px-1", children: quickOptionsTitle }), jsxRuntime.jsx("div", { className: "flex items-center gap-2 overflow-x-auto no-scrollbar pb-1", children: quickOptions.map((chip, cIdx) => {
3107
+ const isSelected = isOptionSelected(chip);
3108
+ return (jsxRuntime.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
3109
+ ? 'bg-blue-600 text-white border-blue-600'
3110
+ : '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));
3111
+ }) })] })), multiple && showSelectAll && allOptions.length > 0 && (jsxRuntime.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: [jsxRuntime.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' }), jsxRuntime.jsxs("span", { className: "text-gray-500 dark:text-gray-400 font-medium", children: [Array.isArray(normalizedDraft) ? normalizedDraft.length : 0, " of", ' ', allOptions.length] })] })), jsxRuntime.jsxs("div", { onScroll: (e) => {
3112
+ const el = e.currentTarget;
3113
+ if (el.scrollTop === 0) {
3114
+ el.scrollTop = 1;
3115
+ }
3116
+ else if (el.scrollTop + el.clientHeight >= el.scrollHeight) {
3117
+ el.scrollTop = el.scrollHeight - el.clientHeight - 1;
3118
+ }
3119
+ }, 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 &&
3120
+ query.trim() &&
3121
+ !allOptions.some((opt) => getDisplayValue(opt).toLowerCase() === query.trim().toLowerCase()) && (jsxRuntime.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: [jsxRuntime.jsxs("span", { className: "text-sm font-medium", children: ["Use \"", query.trim(), "\""] }), jsxRuntime.jsx(SvgChevronDown, { className: "size-4 rotate-[-90deg]" })] })), isAsyncLoading && allOptions.length === 0 ? (jsxRuntime.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: [jsxRuntime.jsx(Loader, { size: "md" }), jsxRuntime.jsx("span", { children: "Loading options..." })] })) : shouldShowTypeToSearch ? (jsxRuntime.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) => (jsxRuntime.jsxs("div", { className: "pt-2", children: [jsxRuntime.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 }), jsxRuntime.jsx("div", { className: "space-y-1", children: grp.options.map((option) => {
3122
+ const optVal = getValue(option);
3123
+ const isSelected = isOptionSelected(option);
3124
+ const optDisabled = option.disabled;
3125
+ const optDesc = typeof option === 'object'
3126
+ ? (option === null || option === void 0 ? void 0 : option.description) || (option === null || option === void 0 ? void 0 : option.subtitle)
3127
+ : null;
3128
+ return (jsxRuntime.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
3129
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3130
+ : 'text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800/70', optDisabled && 'opacity-50 pointer-events-none'), children: [jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 pr-3", children: [jsxRuntime.jsx("div", { className: "text-sm/6 truncate", children: renderOption
3131
+ ? renderOption(option, isSelected)
3132
+ : getDisplayValue(option) }), optDesc && (jsxRuntime.jsx("div", { className: "text-xs text-gray-400 font-normal truncate mt-0.5", children: optDesc }))] }), isSelected && (jsxRuntime.jsx(SvgCheck, { className: "size-5 stroke-blue-600 dark:stroke-blue-400 shrink-0" }))] }, optVal));
3133
+ }) })] }, gIdx)))) : filteredOptions.length > 0 ? (filteredOptions.map((option) => {
3134
+ const optVal = getValue(option);
3135
+ const isSelected = isOptionSelected(option);
3136
+ const optDisabled = option.disabled;
3137
+ const optDesc = typeof option === 'object' ? (option === null || option === void 0 ? void 0 : option.description) || (option === null || option === void 0 ? void 0 : option.subtitle) : null;
3138
+ return (jsxRuntime.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
3139
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3140
+ : 'text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800/70', optDisabled && 'opacity-50 pointer-events-none'), children: [jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 pr-3", children: [jsxRuntime.jsx("div", { className: "text-sm/6 truncate", children: renderOption
3141
+ ? renderOption(option, isSelected)
3142
+ : getDisplayValue(option) }), optDesc && (jsxRuntime.jsx("div", { className: "text-xs text-gray-400 font-normal truncate mt-0.5", children: optDesc }))] }), isSelected && (jsxRuntime.jsx(SvgCheck, { className: "size-5 stroke-blue-600 dark:stroke-blue-400 shrink-0" }))] }, optVal));
3143
+ })) : (!allowFreeText &&
3144
+ !(allowAdd && query.trim()) && (jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400 select-none", children: query
3145
+ ? noOptionsText !== 'No options available'
3146
+ ? noOptionsText
3147
+ : `No results found for "${query}"`
3148
+ : noOptionsText }))), !allowFreeText && allowAdd && Boolean(query.trim()) && (jsxRuntime.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: [jsxRuntime.jsx(SvgCirclePlus, { className: "size-5 text-blue-600 dark:text-blue-400" }), jsxRuntime.jsxs("span", { className: "text-sm font-medium", children: [addNewText, " \"", query.trim(), "\""] })] }))] }), multiple && (jsxRuntime.jsx("div", { className: "p-4 border-t border-[var(--ui-border-muted)] bg-white dark:bg-gray-900 shrink-0", children: jsxRuntime.jsxs(Button, { fullWidth: true, theme: "primary", size: "md", onClick: handleConfirmMultiSelect, "data-testid": "mobile-picker-confirm-button", children: [confirmText, ' ', Array.isArray(normalizedDraft) && normalizedDraft.length > 0
3149
+ ? `(${normalizedDraft.length})`
3150
+ : ''] }) }))] }) })] })] }));
3151
+ }
3152
+ MobilePicker.displayName = 'MobilePicker';
3153
+
3154
+ function SingleWheelColumn({ column, itemHeight, height, disabled, onValueChange, }) {
3155
+ var _a;
3156
+ const containerRef = React.useRef(null);
3157
+ const [selectedValue, setSelectedValue] = React.useState(column.value !== undefined
3158
+ ? column.value
3159
+ : column.defaultValue !== undefined
3160
+ ? column.defaultValue
3161
+ : (_a = column.options[0]) === null || _a === void 0 ? void 0 : _a.value);
3162
+ const isControlled = column.value !== undefined;
3163
+ const currentValue = isControlled ? column.value : selectedValue;
3164
+ const selectedIndex = Math.max(0, column.options.findIndex((opt) => opt.value === currentValue));
3165
+ const paddingY = (height - itemHeight) / 2;
3166
+ // Sync scroll position when active value changes externally
3167
+ React.useEffect(() => {
3168
+ if (containerRef.current) {
3169
+ const targetScrollTop = selectedIndex * itemHeight;
3170
+ if (Math.abs(containerRef.current.scrollTop - targetScrollTop) > 2) {
3171
+ containerRef.current.scrollTop = targetScrollTop;
3172
+ }
3173
+ }
3174
+ }, [selectedIndex, itemHeight]);
3175
+ const handleScroll = () => {
3176
+ var _a;
3177
+ if (!containerRef.current || disabled)
3178
+ return;
3179
+ const scrollTop = containerRef.current.scrollTop;
3180
+ const index = Math.round(scrollTop / itemHeight);
3181
+ const targetOption = column.options[index];
3182
+ if (targetOption && targetOption.value !== currentValue && !targetOption.disabled) {
3183
+ if (!isControlled) {
3184
+ setSelectedValue(targetOption.value);
3185
+ }
3186
+ (_a = column.onChange) === null || _a === void 0 ? void 0 : _a.call(column, targetOption.value);
3187
+ onValueChange(targetOption.value);
3188
+ }
3189
+ };
3190
+ return (jsxRuntime.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: {
3191
+ paddingTop: `${paddingY}px`,
3192
+ paddingBottom: `${paddingY}px`,
3193
+ scrollSnapType: 'y mandatory',
3194
+ }, "data-testid": `wheel-column-${column.id}`, children: column.options.map((opt, index) => {
3195
+ const isSelected = opt.value === currentValue;
3196
+ return (jsxRuntime.jsx("div", { onClick: () => {
3197
+ if (disabled || opt.disabled || !containerRef.current)
3198
+ return;
3199
+ const targetTop = index * itemHeight;
3200
+ if (typeof containerRef.current.scrollTo === 'function') {
3201
+ containerRef.current.scrollTo({
3202
+ top: targetTop,
3203
+ behavior: 'smooth',
3204
+ });
3205
+ }
3206
+ else {
3207
+ containerRef.current.scrollTop = targetTop;
3208
+ }
3209
+ }, 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
3210
+ ? 'text-blue-600 dark:text-blue-400 text-sm font-bold scale-105'
3211
+ : '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}`));
3212
+ }) }));
3213
+ }
3214
+ function WheelPicker({ columns, height = 200, itemHeight = 40, onChange, disabled = false, containerClass = '', }) {
3215
+ const valuesRef = React.useRef({});
3216
+ const handleColumnChange = (columnId, value) => {
3217
+ valuesRef.current[columnId] = value;
3218
+ onChange === null || onChange === void 0 ? void 0 : onChange({ ...valuesRef.current });
3219
+ };
3220
+ const highlightTop = (height - itemHeight) / 2;
3221
+ return (jsxRuntime.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: [jsxRuntime.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: {
3222
+ height: `${itemHeight}px`,
3223
+ top: `${highlightTop}px`,
3224
+ }, "data-testid": "wheel-highlight-window" }), jsxRuntime.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` } }), jsxRuntime.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` } }), jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-around relative z-10 px-2", children: columns.map((col) => (jsxRuntime.jsx(SingleWheelColumn, { column: col, itemHeight: itemHeight, height: height, disabled: disabled, onValueChange: (val) => handleColumnChange(col.id, val) }, col.id))) })] }));
3225
+ }
3226
+ WheelPicker.displayName = 'WheelPicker';
3227
+
3228
+ function ChevronLeftIcon$1() {
3229
+ return (jsxRuntime.jsx("svg", { className: "size-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M15 19l-7-7 7-7" }) }));
3230
+ }
3231
+ function SearchIcon$1() {
3232
+ return (jsxRuntime.jsx("svg", { className: "size-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }));
3233
+ }
3234
+ function ClearIcon() {
3235
+ return (jsxRuntime.jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }));
3236
+ }
3237
+ function MobileHeader({ title, subtitle, titleAlign = 'center', onBack, backLabel = 'Back', leading, actions, searchable = false, searchValue: externalSearchValue, onSearchChange, searchPlaceholder = 'Search...', sticky = true, transparent = false, bottomSlot, className = '', }) {
3238
+ const [isSearchActive, setIsSearchActive] = React.useState(false);
3239
+ const [internalSearchValue, setInternalSearchValue] = React.useState('');
3240
+ const searchValue = externalSearchValue !== undefined ? externalSearchValue : internalSearchValue;
3241
+ const handleSearchInput = (e) => {
3242
+ const val = e.target.value;
3243
+ setInternalSearchValue(val);
3244
+ onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(val);
3245
+ };
3246
+ const handleClearSearch = () => {
3247
+ setInternalSearchValue('');
3248
+ onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange('');
3249
+ };
3250
+ return (jsxRuntime.jsxs("header", { className: buildClassName('w-full transition-colors select-none z-30', sticky && 'sticky top-0', transparent
3251
+ ? 'bg-white/80 dark:bg-gray-900/80 backdrop-blur-md border-b border-[var(--ui-border-muted)]'
3252
+ : '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: [jsxRuntime.jsx("div", { className: "h-14 px-3.5 flex items-center justify-between gap-3 relative", children: searchable && isSearchActive ? (jsxRuntime.jsxs("div", { className: "flex-1 flex items-center gap-2", "data-testid": "mobile-header-search-container", children: [jsxRuntime.jsxs("div", { className: "relative flex-1 flex items-center", children: [jsxRuntime.jsx("span", { className: "absolute left-3 pointer-events-none", children: jsxRuntime.jsx(SearchIcon$1, {}) }), jsxRuntime.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 && (jsxRuntime.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: jsxRuntime.jsx(ClearIcon, {}) }))] }), jsxRuntime.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" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "flex items-center gap-1 min-w-[40px] shrink-0 z-10", children: onBack ? (jsxRuntime.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: [jsxRuntime.jsx(ChevronLeftIcon$1, {}), jsxRuntime.jsx("span", { className: "text-xs font-semibold hidden sm:inline", children: backLabel })] })) : (leading) }), jsxRuntime.jsxs("div", { className: buildClassName('flex-1 min-w-0 px-2', titleAlign === 'center'
3253
+ ? 'absolute inset-x-12 text-center pointer-events-none flex flex-col items-center justify-center'
3254
+ : 'text-left'), children: [title && (jsxRuntime.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 && (jsxRuntime.jsx("div", { className: "text-[11px] text-gray-500 dark:text-gray-400 truncate pointer-events-auto", "data-testid": "mobile-header-subtitle", children: subtitle }))] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 min-w-[40px] shrink-0 justify-end z-10", children: [searchable && (jsxRuntime.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: jsxRuntime.jsx(SearchIcon$1, {}) })), actions === null || actions === void 0 ? void 0 : actions.map((action) => {
3255
+ const badgeColor = {
3256
+ danger: 'bg-red-500 text-white',
3257
+ info: 'bg-blue-500 text-white',
3258
+ success: 'bg-emerald-500 text-white',
3259
+ }[action.badgeVariant || 'danger'];
3260
+ return (jsxRuntime.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: [jsxRuntime.jsx("span", { className: "text-base", children: action.icon }), action.badge !== undefined && action.badge !== null && (jsxRuntime.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));
3261
+ })] })] })) }), bottomSlot && (jsxRuntime.jsx("div", { className: "px-3 py-2 border-t border-[var(--ui-border-muted)]", "data-testid": "mobile-header-bottom-slot", children: bottomSlot }))] }));
3262
+ }
3263
+ MobileHeader.displayName = 'MobileHeader';
3264
+
3265
+ function ChevronLeftIcon() {
3266
+ return (jsxRuntime.jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M15 19l-7-7 7-7" }) }));
3267
+ }
3268
+ function ChevronRightIcon() {
3269
+ return (jsxRuntime.jsx("svg", { className: "size-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M9 5l7 7-7 7" }) }));
3270
+ }
3271
+ function MobileStepper({ steps, activeStep, variant = 'dots', onBack, onNext, backLabel = 'Back', nextLabel = 'Next', stepTitle, nextDisabled = false, backDisabled = false, nextLoading = false, className = '', }) {
3272
+ const isFirstStep = activeStep <= 0;
3273
+ const isLastStep = activeStep >= steps - 1;
3274
+ const progressPercent = Math.min(Math.max(((activeStep + 1) / steps) * 100, 0), 100);
3275
+ return (jsxRuntime.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 && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-1", children: [jsxRuntime.jsx("span", { className: "text-xs font-bold text-gray-900 dark:text-white truncate", "data-testid": "mobile-stepper-title", children: stepTitle }), jsxRuntime.jsxs("span", { className: "text-[11px] font-medium text-gray-500 dark:text-gray-400 shrink-0 ml-2", children: [activeStep + 1, " / ", steps] })] })), jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntime.jsx(Button, { size: "xs", variant: "plain", theme: "secondary", disabled: disabledBack(isFirstStep, backDisabled), onClick: onBack, "aria-label": "Previous step", leftIcon: jsxRuntime.jsx(ChevronLeftIcon, {}), "data-testid": "mobile-stepper-back-btn", children: backLabel }), jsxRuntime.jsxs("div", { className: "flex items-center justify-center flex-1", "data-testid": "mobile-stepper-indicator", children: [variant === 'dots' && (jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", "data-testid": "mobile-stepper-dots", children: Array.from({ length: steps }).map((_, index) => {
3276
+ const isActive = index === activeStep;
3277
+ const isCompleted = index < activeStep;
3278
+ return (jsxRuntime.jsx("span", { className: buildClassName('h-2 transition-all duration-300 rounded-full', isActive
3279
+ ? 'w-5 bg-blue-600 dark:bg-blue-400'
3280
+ : isCompleted
3281
+ ? 'w-2 bg-blue-300 dark:bg-blue-800'
3282
+ : 'w-2 bg-gray-200 dark:bg-gray-700'), "data-testid": `mobile-stepper-dot-${index}` }, index));
3283
+ }) })), variant === 'progress' && (jsxRuntime.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: jsxRuntime.jsx("div", { className: "bg-blue-600 dark:bg-blue-400 h-full transition-all duration-300 rounded-full", style: { width: `${progressPercent}%` } }) })), variant === 'text' && (jsxRuntime.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] }))] }), jsxRuntime.jsx(Button, { size: "xs", variant: "default", theme: "primary", disabled: nextDisabled, loading: nextLoading, onClick: onNext, "aria-label": "Next step", rightIcon: !isLastStep ? jsxRuntime.jsx(ChevronRightIcon, {}) : undefined, "data-testid": "mobile-stepper-next-btn", children: nextLabel })] })] }));
3284
+ }
3285
+ function disabledBack(isFirstStep, backDisabled) {
3286
+ return isFirstStep || backDisabled;
3287
+ }
3288
+ MobileStepper.displayName = 'MobileStepper';
3289
+
3290
+ const themeClasses = {
3291
+ danger: 'bg-red-600 text-white hover:bg-red-700 active:bg-red-800',
3292
+ primary: 'bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800',
3293
+ success: 'bg-emerald-600 text-white hover:bg-emerald-700 active:bg-emerald-800',
3294
+ warning: 'bg-amber-500 text-white hover:bg-amber-600 active:bg-amber-700',
3295
+ info: 'bg-cyan-600 text-white hover:bg-cyan-700 active:bg-cyan-800',
3296
+ secondary: 'bg-gray-600 text-white hover:bg-gray-700 active:bg-gray-800',
3297
+ gray: 'bg-gray-500 text-white hover:bg-gray-600 active:bg-gray-700',
3298
+ };
3299
+ const SwipeableRow = ({ children, leftActions = [], rightActions = [], actionWidth = 76, threshold = 40, fullSwipeToExecute = false, fullSwipeThreshold = 180, disabled = false, className = '', contentClassName = '', onOpen, onClose, }) => {
3300
+ const [offset, setOffset] = React.useState(0);
3301
+ const [isDragging, setIsDragging] = React.useState(false);
3302
+ const containerRef = React.useRef(null);
3303
+ const startXRef = React.useRef(0);
3304
+ const startYRef = React.useRef(0);
3305
+ const initialOffsetRef = React.useRef(0);
3306
+ const isHorizontalSwipeRef = React.useRef(null);
3307
+ const maxLeftWidth = React.useMemo(() => leftActions.length * actionWidth, [leftActions, actionWidth]);
3308
+ const maxRightWidth = React.useMemo(() => rightActions.length * actionWidth, [rightActions, actionWidth]);
3309
+ const handleClose = React.useCallback(() => {
3310
+ setOffset(0);
3311
+ onClose === null || onClose === void 0 ? void 0 : onClose();
3312
+ }, [onClose]);
3313
+ const handleOpenLeft = React.useCallback(() => {
3314
+ if (maxLeftWidth > 0) {
3315
+ setOffset(maxLeftWidth);
3316
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen('left');
3317
+ }
3318
+ else {
3319
+ handleClose();
3320
+ }
3321
+ }, [maxLeftWidth, onOpen, handleClose]);
3322
+ const handleOpenRight = React.useCallback(() => {
3323
+ if (maxRightWidth > 0) {
3324
+ setOffset(-maxRightWidth);
3325
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen('right');
3326
+ }
3327
+ else {
3328
+ handleClose();
3329
+ }
3330
+ }, [maxRightWidth, onOpen, handleClose]);
3331
+ const handleDragStart = (clientX, clientY) => {
3332
+ if (disabled)
1988
3333
  return;
1989
- const rect = trackRef.current.getBoundingClientRect();
1990
- const x = Math.min(Math.max(e.clientX - rect.left, 0), rect.width);
1991
- const rawVal = min + (x / rect.width) * (max - min);
1992
- const snappedVal = snapToStep(rawVal);
1993
- const pxMin = (percent(valueMin) / 100) * rect.width;
1994
- const pxMax = (percent(valueMax) / 100) * rect.width;
1995
- if (x <= pxMin) {
1996
- onChange(Math.min(snappedVal, valueMax - step), valueMax);
3334
+ setIsDragging(true);
3335
+ startXRef.current = clientX;
3336
+ startYRef.current = clientY;
3337
+ initialOffsetRef.current = offset;
3338
+ isHorizontalSwipeRef.current = null;
3339
+ };
3340
+ const handleDragMove = (clientX, clientY) => {
3341
+ if (!isDragging || disabled)
1997
3342
  return;
3343
+ const deltaX = clientX - startXRef.current;
3344
+ const deltaY = clientY - startYRef.current;
3345
+ // Lock direction once initial movement surpasses 5px
3346
+ if (isHorizontalSwipeRef.current === null) {
3347
+ if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
3348
+ isHorizontalSwipeRef.current = Math.abs(deltaX) > Math.abs(deltaY);
3349
+ }
1998
3350
  }
1999
- if (x >= pxMax) {
2000
- onChange(valueMin, Math.max(snappedVal, valueMin + step));
3351
+ if (isHorizontalSwipeRef.current === false) {
2001
3352
  return;
2002
3353
  }
2003
- const distMin = Math.abs(snappedVal - valueMin);
2004
- const distMax = Math.abs(snappedVal - valueMax);
2005
- if (distMin < distMax) {
2006
- onChange(Math.min(snappedVal, valueMax - step), valueMax);
3354
+ let nextOffset = initialOffsetRef.current + deltaX;
3355
+ // Limit drag range with resistance overscroll
3356
+ if (nextOffset > 0) {
3357
+ if (!leftActions.length) {
3358
+ nextOffset = 0;
3359
+ }
3360
+ else if (nextOffset > maxLeftWidth && !fullSwipeToExecute) {
3361
+ const overflow = nextOffset - maxLeftWidth;
3362
+ nextOffset = maxLeftWidth + overflow * 0.2;
3363
+ }
2007
3364
  }
2008
- else {
2009
- onChange(valueMin, Math.max(snappedVal, valueMin + step));
3365
+ else if (nextOffset < 0) {
3366
+ if (!rightActions.length) {
3367
+ nextOffset = 0;
3368
+ }
3369
+ else if (Math.abs(nextOffset) > maxRightWidth && !fullSwipeToExecute) {
3370
+ const overflow = Math.abs(nextOffset) - maxRightWidth;
3371
+ nextOffset = -(maxRightWidth + overflow * 0.2);
3372
+ }
2010
3373
  }
3374
+ setOffset(nextOffset);
2011
3375
  };
2012
- // Keyboard accessibility handler for thumbs
2013
- const handleKeyDown = (thumb) => (e) => {
2014
- let delta = 0;
2015
- if (e.key === 'ArrowLeft' || e.key === 'ArrowDown')
2016
- delta = -step;
2017
- else if (e.key === 'ArrowRight' || e.key === 'ArrowUp')
2018
- delta = step;
2019
- else if (e.key === 'Home') {
2020
- if (thumb === 'min')
2021
- onChange(min, valueMax);
2022
- else
2023
- onChange(valueMin, valueMin + step);
3376
+ const handleDragEnd = () => {
3377
+ if (!isDragging)
2024
3378
  return;
2025
- }
2026
- else if (e.key === 'End') {
2027
- if (thumb === 'min')
2028
- onChange(valueMax - step, valueMax);
2029
- else
2030
- onChange(valueMin, max);
3379
+ setIsDragging(false);
3380
+ if (isHorizontalSwipeRef.current === false) {
2031
3381
  return;
2032
3382
  }
2033
- if (delta !== 0) {
2034
- e.preventDefault();
2035
- if (thumb === 'min') {
2036
- const next = snapToStep(valueMin + delta);
2037
- onChange(Math.min(next, valueMax - step), valueMax);
3383
+ // Check full swipe auto-execution
3384
+ if (fullSwipeToExecute) {
3385
+ if (offset > fullSwipeThreshold && leftActions.length > 0) {
3386
+ leftActions[0].onClick();
3387
+ handleClose();
3388
+ return;
3389
+ }
3390
+ if (offset < -fullSwipeThreshold && rightActions.length > 0) {
3391
+ rightActions[0].onClick();
3392
+ handleClose();
3393
+ return;
3394
+ }
3395
+ }
3396
+ // Snap logic
3397
+ if (offset > 0) {
3398
+ if (offset > threshold) {
3399
+ handleOpenLeft();
2038
3400
  }
2039
3401
  else {
2040
- const next = snapToStep(valueMax + delta);
2041
- onChange(valueMin, Math.max(next, valueMin + step));
3402
+ handleClose();
3403
+ }
3404
+ }
3405
+ else if (offset < 0) {
3406
+ if (Math.abs(offset) > threshold) {
3407
+ handleOpenRight();
3408
+ }
3409
+ else {
3410
+ handleClose();
2042
3411
  }
2043
3412
  }
2044
3413
  };
2045
- const markEntries = marks
2046
- ? Object.entries(marks).map(([k, v]) => ({ value: Number(k), label: v }))
2047
- : null;
2048
- return (jsxRuntime.jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [jsxRuntime.jsx(Label, { className: labelClass, children: label }), labelHint] })), jsxRuntime.jsxs("div", { ref: trackRef, onMouseDown: handleTrackClick, className: "relative h-8 select-none w-full flex items-center cursor-pointer", "data-testid": "range-track", children: [jsxRuntime.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) }), jsxRuntime.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: {
2049
- left: `${percent(valueMin)}%`,
2050
- width: `${percent(valueMax) - percent(valueMin)}%`,
2051
- } }), jsxRuntime.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') &&
2052
- (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2053
- left: `calc(${percent(valueMin)}% - ${currentSize.thumbPx / 2}px)`,
2054
- zIndex: activeThumbState === 'min' ? 50 : 30,
2055
- }, "data-testid": "thumb-min", children: showTooltips && (activeThumbState === 'min' || hoveringThumb === 'min') && (jsxRuntime.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, jsxRuntime.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" })] })) }), jsxRuntime.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') &&
2056
- (hasError ? 'ring-4 ring-red-200' : 'ring-4 ring-blue-200'), className), style: {
2057
- left: `calc(${percent(valueMax)}% - ${currentSize.thumbPx / 2}px)`,
2058
- zIndex: activeThumbState === 'max' ? 50 : 40,
2059
- }, "data-testid": "thumb-max", children: showTooltips && (activeThumbState === 'max' || hoveringThumb === 'max') && (jsxRuntime.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, jsxRuntime.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 && (jsxRuntime.jsx("div", { className: "relative w-full h-4 mt-1", children: markEntries.map((m) => {
2060
- const markPercent = percent(m.value);
2061
- return (jsxRuntime.jsxs("div", { className: "absolute top-0 transform -translate-x-1/2 flex flex-col items-center", style: { left: `${markPercent}%` }, children: [jsxRuntime.jsx("span", { className: "w-1 h-1.5 bg-gray-300 dark:bg-gray-600 rounded-full" }), jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-gray-400 dark:text-gray-500 mt-0.5", children: m.label })] }, m.value));
2062
- }) })), jsxRuntime.jsxs("div", { className: buildClassName('flex justify-between font-medium text-gray-700 dark:text-gray-300', currentSize.text), children: [jsxRuntime.jsxs("span", { children: [Math.round(valueMin), valueSuffix] }), jsxRuntime.jsxs("span", { children: [Math.round(valueMax), valueSuffix] })] }), (showErrorMessage && hasError) || helperText ? (jsxRuntime.jsx("div", { className: "mt-1", children: showErrorMessage && hasError ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null })) : null] }));
2063
- };
2064
- RangeSlider.displayName = 'RangeSlider';
2065
-
2066
- const useDebounce = (value, delay) => {
2067
- const [debouncedValue, setDebouncedValue] = React.useState(value);
3414
+ // Touch Handlers
3415
+ const handleTouchStart = (e) => {
3416
+ const touch = e.touches[0];
3417
+ handleDragStart(touch.clientX, touch.clientY);
3418
+ };
3419
+ const handleTouchMove = (e) => {
3420
+ const touch = e.touches[0];
3421
+ handleDragMove(touch.clientX, touch.clientY);
3422
+ };
3423
+ const handleTouchEnd = () => {
3424
+ handleDragEnd();
3425
+ };
3426
+ // Pointer/Mouse Handlers
3427
+ const handlePointerDown = (e) => {
3428
+ if (e.pointerType === 'mouse' && e.button !== 0)
3429
+ return;
3430
+ handleDragStart(e.clientX, e.clientY);
3431
+ };
3432
+ const handlePointerMove = (e) => {
3433
+ if (!isDragging)
3434
+ return;
3435
+ handleDragMove(e.clientX, e.clientY);
3436
+ };
3437
+ const handlePointerUp = () => {
3438
+ handleDragEnd();
3439
+ };
3440
+ // Close row on click outside if swiped open
2068
3441
  React.useEffect(() => {
2069
- const handler = setTimeout(() => {
2070
- setDebouncedValue(value);
2071
- }, delay);
2072
- // Cancel the timeout if value or delay changes
3442
+ if (offset === 0)
3443
+ return;
3444
+ const handleClickOutside = (e) => {
3445
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
3446
+ handleClose();
3447
+ }
3448
+ };
3449
+ document.addEventListener('click', handleClickOutside);
2073
3450
  return () => {
2074
- clearTimeout(handler);
3451
+ document.removeEventListener('click', handleClickOutside);
2075
3452
  };
2076
- }, [value, delay]);
2077
- return debouncedValue;
2078
- };
2079
- const useDebounceFn = (fn, ms) => {
2080
- const timeout = React.useRef(null);
2081
- React.useEffect(() => {
2082
- return () => clearTimeout(timeout.current);
2083
- }, []);
2084
- return React.useCallback((...args) => {
2085
- clearTimeout(timeout.current);
2086
- timeout.current = setTimeout(() => fn(...args), ms);
2087
- }, [fn, ms]);
2088
- };
2089
-
2090
- var _path$1;
2091
- 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); }
2092
- var SvgCheck = function SvgCheck(props) {
2093
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
2094
- xmlns: "http://www.w3.org/2000/svg",
2095
- width: 24,
2096
- height: 24,
2097
- fill: "none",
2098
- stroke: "currentColor",
2099
- strokeLinecap: "round",
2100
- strokeLinejoin: "round",
2101
- strokeWidth: 2,
2102
- className: "lucide lucide-check-icon lucide-check",
2103
- viewBox: "0 0 24 24"
2104
- }, props), _path$1 || (_path$1 = /*#__PURE__*/React__namespace.createElement("path", {
2105
- d: "M20 6 9 17l-5-5"
2106
- })));
3453
+ }, [offset, handleClose]);
3454
+ const renderActionButton = (action) => {
3455
+ const themeStyle = themeClasses[action.theme || 'primary'];
3456
+ return (jsxRuntime.jsxs("button", { type: "button", style: { width: `${actionWidth}px` }, onClick: (e) => {
3457
+ e.stopPropagation();
3458
+ action.onClick();
3459
+ handleClose();
3460
+ }, 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 && jsxRuntime.jsx("span", { className: "shrink-0", children: action.icon }), action.label && jsxRuntime.jsx("span", { className: "truncate max-w-full", children: action.label })] }, action.id));
3461
+ };
3462
+ return (jsxRuntime.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 && (jsxRuntime.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 && (jsxRuntime.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) })), jsxRuntime.jsx("div", { onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerUp, style: {
3463
+ transform: `translateX(${offset}px)`,
3464
+ transition: isDragging ? 'none' : 'transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1)',
3465
+ }, 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 })] }));
2107
3466
  };
3467
+ SwipeableRow.displayName = 'SwipeableRow';
2108
3468
 
2109
- var _circle, _path;
2110
- 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); }
2111
- var SvgCirclePlus = function SvgCirclePlus(props) {
2112
- return /*#__PURE__*/React__namespace.createElement("svg", _extends({
2113
- xmlns: "http://www.w3.org/2000/svg",
2114
- width: 24,
2115
- height: 24,
2116
- fill: "none",
2117
- stroke: "currentColor",
2118
- strokeLinecap: "round",
2119
- strokeLinejoin: "round",
2120
- strokeWidth: 2,
2121
- className: "lucide lucide-circle-plus-icon lucide-circle-plus",
2122
- viewBox: "0 0 24 24"
2123
- }, props), _circle || (_circle = /*#__PURE__*/React__namespace.createElement("circle", {
2124
- cx: 12,
2125
- cy: 12,
2126
- r: 10
2127
- })), _path || (_path = /*#__PURE__*/React__namespace.createElement("path", {
2128
- d: "M8 12h8M12 8v8"
2129
- })));
3469
+ function SearchIcon() {
3470
+ return (jsxRuntime.jsx("svg", { className: "size-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }));
3471
+ }
3472
+ function FilterIcon() {
3473
+ return (jsxRuntime.jsx("svg", { className: "size-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.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" }) }));
3474
+ }
3475
+ function SortIcon() {
3476
+ return (jsxRuntime.jsx("svg", { className: "size-3.5 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
3477
+ }
3478
+ function CheckIcon() {
3479
+ return (jsxRuntime.jsx("svg", { className: "size-4 text-blue-600 dark:text-blue-400 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M5 13l4 4L19 7" }) }));
3480
+ }
3481
+ const parseNumericValue = (val) => {
3482
+ if (typeof val === 'number')
3483
+ return val;
3484
+ if (val === null || val === undefined)
3485
+ return NaN;
3486
+ const cleaned = String(val).replace(/[^0-9.-]/g, '');
3487
+ return cleaned !== '' ? Number(cleaned) : NaN;
2130
3488
  };
3489
+ 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 = '', }) {
3490
+ // Internal Search State
3491
+ const [internalSearchQuery, setInternalSearchQuery] = React.useState('');
3492
+ const searchQuery = externalSearchQuery !== undefined ? externalSearchQuery : internalSearchQuery;
3493
+ const handleSearchInput = (query) => {
3494
+ onSearchChange ? onSearchChange(query) : setInternalSearchQuery(query);
3495
+ };
3496
+ // Internal Filter State
3497
+ const [internalFilters, setInternalFilters] = React.useState({});
3498
+ const selectedFilters = externalFilters !== undefined ? externalFilters : internalFilters;
3499
+ // Mobile Bottom Sheet Filter Drawer State
3500
+ const [isFilterSheetOpen, setIsFilterSheetOpen] = React.useState(false);
3501
+ const [draftFilters, setDraftFilters] = React.useState({});
3502
+ // Mobile Bottom Sheet Sort Drawer State
3503
+ const [isSortSheetOpen, setIsSortSheetOpen] = React.useState(false);
3504
+ // Active Filter Count Calculation
3505
+ const activeFilterCount = React.useMemo(() => {
3506
+ let count = 0;
3507
+ Object.values(selectedFilters).forEach((val) => {
3508
+ if (Array.isArray(val)) {
3509
+ count += val.length;
3510
+ }
3511
+ else if (val !== '' && val !== null && val !== undefined && val !== 'all') {
3512
+ count += 1;
3513
+ }
3514
+ });
3515
+ return count;
3516
+ }, [selectedFilters]);
3517
+ // Internal Sort State
3518
+ const [internalSort, setInternalSort] = React.useState(() => {
3519
+ if (externalSorting && Object.keys(externalSorting).length > 0) {
3520
+ const field = Object.keys(externalSorting)[0];
3521
+ return { field, dir: externalSorting[field] };
3522
+ }
3523
+ return null;
3524
+ });
3525
+ React.useEffect(() => {
3526
+ if (externalSorting !== undefined) {
3527
+ if (Object.keys(externalSorting).length > 0) {
3528
+ const field = Object.keys(externalSorting)[0];
3529
+ setInternalSort({ field, dir: externalSorting[field] });
3530
+ }
3531
+ else {
3532
+ setInternalSort(null);
3533
+ }
3534
+ }
3535
+ }, [externalSorting]);
3536
+ const activeSort = internalSort;
3537
+ const sortableColumns = React.useMemo(() => (columns === null || columns === void 0 ? void 0 : columns.filter((c) => c.sortable)) || [], [columns]);
3538
+ const sortOptions = React.useMemo(() => {
3539
+ const opts = [{ label: 'Default Order', value: '' }];
3540
+ sortableColumns.forEach((col) => {
3541
+ const isNum = col.type === 'number';
3542
+ const isDate = col.type === 'date';
3543
+ const lowHigh = isNum
3544
+ ? `${col.label} (Low to High)`
3545
+ : isDate
3546
+ ? `${col.label} (Oldest First)`
3547
+ : `${col.label} (A to Z)`;
3548
+ const highLow = isNum
3549
+ ? `${col.label} (High to Low)`
3550
+ : isDate
3551
+ ? `${col.label} (Newest First)`
3552
+ : `${col.label} (Z to A)`;
3553
+ opts.push({ label: lowHigh, value: `${col.name}:asc` });
3554
+ opts.push({ label: highLow, value: `${col.name}:desc` });
3555
+ });
3556
+ return opts;
3557
+ }, [sortableColumns]);
3558
+ const handleSortSelect = (val) => {
3559
+ if (!val) {
3560
+ setInternalSort(null);
3561
+ onSortChange === null || onSortChange === void 0 ? void 0 : onSortChange({});
3562
+ return;
3563
+ }
3564
+ const [field, dir] = val.split(':');
3565
+ const sortObj = { [field]: dir };
3566
+ setInternalSort({ field, dir: dir });
3567
+ onSortChange === null || onSortChange === void 0 ? void 0 : onSortChange(sortObj);
3568
+ };
3569
+ const activeSortLabel = React.useMemo(() => {
3570
+ if (!activeSort)
3571
+ return 'Sort';
3572
+ const currVal = `${activeSort.field}:${activeSort.dir}`;
3573
+ const match = sortOptions.find((o) => o.value === currVal);
3574
+ if (!match || !match.value)
3575
+ return 'Sort';
3576
+ return `Sort: ${match.label}`;
3577
+ }, [activeSort, sortOptions]);
3578
+ // Processed Items (Filter + Search + Sort)
3579
+ const processedItems = React.useMemo(() => {
3580
+ let result = [...items];
3581
+ // 1. Apply Search
3582
+ if (searchQuery.trim()) {
3583
+ const q = searchQuery.toLowerCase().trim();
3584
+ const fieldsToSearch = searchFields || (columns === null || columns === void 0 ? void 0 : columns.map((c) => c.name)) || ['id', 'name', 'title'];
3585
+ result = result.filter((item) => fieldsToSearch.some((field) => {
3586
+ const val = get(item, field);
3587
+ return val !== null && val !== undefined && String(val).toLowerCase().includes(q);
3588
+ }));
3589
+ }
3590
+ // 2. Apply Filters (supporting array checkboxes or single values)
3591
+ const filterKeys = Object.keys(selectedFilters);
3592
+ if (filterKeys.length > 0) {
3593
+ result = result.filter((item) => filterKeys.every((key) => {
3594
+ const filterVal = selectedFilters[key];
3595
+ if (filterVal === undefined || filterVal === null || filterVal === '')
3596
+ return true;
3597
+ const actual = String(get(item, key));
3598
+ if (Array.isArray(filterVal)) {
3599
+ if (filterVal.length === 0)
3600
+ return true;
3601
+ return filterVal.map(String).includes(actual);
3602
+ }
3603
+ return actual === String(filterVal);
3604
+ }));
3605
+ }
3606
+ // 3. Apply Auto Sorting
3607
+ if (activeSort) {
3608
+ const { field, dir } = activeSort;
3609
+ const colDef = columns === null || columns === void 0 ? void 0 : columns.find((c) => c.name === field);
3610
+ const isAsc = dir === 'asc' || dir === '1';
3611
+ result.sort((a, b) => {
3612
+ const valA = get(a, field);
3613
+ const valB = get(b, field);
3614
+ const numA = parseNumericValue(valA);
3615
+ const numB = parseNumericValue(valB);
3616
+ if ((colDef === null || colDef === void 0 ? void 0 : colDef.type) === 'number' || (!isNaN(numA) && !isNaN(numB))) {
3617
+ return isAsc ? numA - numB : numB - numA;
3618
+ }
3619
+ if ((colDef === null || colDef === void 0 ? void 0 : colDef.type) === 'date') {
3620
+ const dA = new Date(valA).getTime();
3621
+ const dB = new Date(valB).getTime();
3622
+ if (!isNaN(dA) && !isNaN(dB)) {
3623
+ return isAsc ? dA - dB : dB - dA;
3624
+ }
3625
+ }
3626
+ const strA = String(valA !== null && valA !== void 0 ? valA : '');
3627
+ const strB = String(valB !== null && valB !== void 0 ? valB : '');
3628
+ return isAsc
3629
+ ? strA.localeCompare(strB, undefined, { numeric: true })
3630
+ : strB.localeCompare(strA, undefined, { numeric: true });
3631
+ });
3632
+ }
3633
+ return result;
3634
+ }, [items, searchQuery, searchFields, columns, selectedFilters, activeSort]);
3635
+ // Draft Filters Matching Count
3636
+ const draftMatchingCount = React.useMemo(() => {
3637
+ let result = [...items];
3638
+ const filterKeys = Object.keys(draftFilters);
3639
+ if (filterKeys.length > 0) {
3640
+ result = result.filter((item) => filterKeys.every((key) => {
3641
+ const filterVal = draftFilters[key];
3642
+ if (filterVal === undefined || filterVal === null || filterVal === '')
3643
+ return true;
3644
+ const actual = String(get(item, key));
3645
+ if (Array.isArray(filterVal)) {
3646
+ if (filterVal.length === 0)
3647
+ return true;
3648
+ return filterVal.map(String).includes(actual);
3649
+ }
3650
+ return actual === String(filterVal);
3651
+ }));
3652
+ }
3653
+ return result.length;
3654
+ }, [items, draftFilters]);
3655
+ const getKey = (item, idx) => {
3656
+ var _a;
3657
+ if (typeof rowKey === 'function')
3658
+ return rowKey(item);
3659
+ return (_a = item[rowKey]) !== null && _a !== void 0 ? _a : idx;
3660
+ };
3661
+ const isSelected = (key) => selectedKeys.includes(key);
3662
+ const toggleSelectAll = () => {
3663
+ if (selectedKeys.length === processedItems.length) {
3664
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([], []);
3665
+ }
3666
+ else {
3667
+ const allKeys = processedItems.map(getKey);
3668
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(allKeys, processedItems);
3669
+ }
3670
+ };
3671
+ const toggleItemSelect = (key, item) => {
3672
+ const nextKeys = isSelected(key)
3673
+ ? selectedKeys.filter((k) => k !== key)
3674
+ : [...selectedKeys, key];
3675
+ const nextItems = processedItems.filter((it, idx) => nextKeys.includes(getKey(it, idx)));
3676
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(nextKeys, nextItems);
3677
+ };
3678
+ const getItemClassStr = (item, idx) => {
3679
+ if (typeof itemClass === 'function')
3680
+ return itemClass(item, idx);
3681
+ return itemClass;
3682
+ };
3683
+ return (jsxRuntime.jsxs("div", { className: buildClassName('w-full space-y-3', containerClass), "data-testid": "data-list", children: [(searchable || (filterFields && filterFields.length > 0) || sortableColumns.length > 0) && (jsxRuntime.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 && (jsxRuntime.jsx(Input, { value: searchQuery, onChange: (e) => handleSearchInput(e.target.value), placeholder: "Search items...", leftGroup: jsxRuntime.jsx(SearchIcon, {}), clearable: true, onClear: () => handleSearchInput(''), className: "w-full text-xs", size: "sm" })), ((filterFields && filterFields.length > 0) || sortableColumns.length > 0) && (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [filterFields && filterFields.length > 0 && (jsxRuntime.jsxs(Button, { theme: "secondary", size: "sm", onClick: () => {
3684
+ setDraftFilters(selectedFilters);
3685
+ setIsFilterSheetOpen(true);
3686
+ }, className: "flex items-center gap-1.5 text-xs font-semibold flex-1 justify-center", "data-testid": "data-list-filter-btn", children: [jsxRuntime.jsx(FilterIcon, {}), jsxRuntime.jsx("span", { children: "Filters" }), activeFilterCount > 0 && (jsxRuntime.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 && (jsxRuntime.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: [jsxRuntime.jsx(SortIcon, {}), jsxRuntime.jsx("span", { children: activeSortLabel })] }))] }))] })), filterFields && filterFields.length > 0 && (jsxRuntime.jsx(Drawer, { isOpen: isFilterSheetOpen, onClose: () => setIsFilterSheetOpen(false), align: "bottom", title: "Filter Items", dragHandle: true, panelClass: "max-h-[85vh] rounded-t-2xl", footer: jsxRuntime.jsxs("div", { className: "flex items-center gap-3 w-full", children: [jsxRuntime.jsx(Button, { theme: "secondary", size: "md", onClick: () => setDraftFilters({}), className: "flex-1 text-xs", children: "Clear All" }), jsxRuntime.jsxs(Button, { theme: "primary", size: "md", onClick: () => {
3687
+ onFilterChange ? onFilterChange(draftFilters) : setInternalFilters(draftFilters);
3688
+ setIsFilterSheetOpen(false);
3689
+ }, className: "flex-1 text-xs font-semibold", "data-testid": "data-list-apply-filters-btn", children: ["Apply Filters (", draftMatchingCount, ")"] })] }), footerSticky: true, children: jsxRuntime.jsx("div", { className: "space-y-6 py-2", children: filterFields.map((field) => {
3690
+ const selectedArray = Array.isArray(draftFilters[field.name])
3691
+ ? draftFilters[field.name]
3692
+ : draftFilters[field.name] !== undefined && draftFilters[field.name] !== ''
3693
+ ? [draftFilters[field.name]]
3694
+ : [];
3695
+ return (jsxRuntime.jsxs("div", { className: "space-y-2.5", children: [jsxRuntime.jsx("h4", { className: "text-xs font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400 px-1", children: field.label }), jsxRuntime.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) => {
3696
+ const checked = selectedArray.includes(opt.value);
3697
+ return (jsxRuntime.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: [jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-800 dark:text-gray-200", children: opt.label }), jsxRuntime.jsx(Checkbox, { checked: checked, onChange: () => {
3698
+ const next = checked
3699
+ ? selectedArray.filter((v) => v !== opt.value)
3700
+ : [...selectedArray, opt.value];
3701
+ setDraftFilters((prev) => ({
3702
+ ...prev,
3703
+ [field.name]: next,
3704
+ }));
3705
+ } })] }, String(opt.value)));
3706
+ }) })] }, field.name));
3707
+ }) }) })), sortableColumns.length > 0 && (jsxRuntime.jsx(Drawer, { isOpen: isSortSheetOpen, onClose: () => setIsSortSheetOpen(false), align: "bottom", title: "Sort Items By", dragHandle: true, panelClass: "max-h-[70vh] rounded-t-2xl", children: jsxRuntime.jsx("div", { className: "space-y-1 py-2", children: sortOptions.map((opt) => {
3708
+ const isSelected = (activeSort ? `${activeSort.field}:${activeSort.dir}` : '') === opt.value;
3709
+ return (jsxRuntime.jsxs("button", { type: "button", onClick: () => {
3710
+ handleSortSelect(opt.value);
3711
+ setIsSortSheetOpen(false);
3712
+ }, className: buildClassName('w-full flex items-center justify-between p-3.5 rounded-xl text-left transition-colors cursor-pointer', isSelected
3713
+ ? 'bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 font-semibold'
3714
+ : '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: [jsxRuntime.jsx("span", { className: "text-sm", children: opt.label }), isSelected && jsxRuntime.jsx(CheckIcon, {})] }, opt.value));
3715
+ }) }) })), selectable && processedItems.length > 0 && (jsxRuntime.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: [jsxRuntime.jsxs("label", { className: "flex items-center gap-2 font-medium text-gray-700 dark:text-gray-300 cursor-pointer", children: [jsxRuntime.jsx(Checkbox, { checked: processedItems.length > 0 && selectedKeys.length === processedItems.length, onChange: toggleSelectAll }), jsxRuntime.jsx("span", { children: "Select All Items" })] }), jsxRuntime.jsxs("span", { className: "text-gray-400 font-semibold", children: [selectedKeys.length, " of ", processedItems.length] })] })), jsxRuntime.jsx("div", { className: "space-y-3", children: loading ? (jsxRuntime.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 ? (jsxRuntime.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) => {
3716
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
3717
+ const key = getKey(item, idx);
3718
+ const selected = isSelected(key);
3719
+ const actions = swipeableActions === null || swipeableActions === void 0 ? void 0 : swipeableActions(item);
3720
+ const customClass = getItemClassStr(item, idx);
3721
+ const contentNode = renderItem ? (renderItem(item, idx)) : (jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-[var(--ui-border-muted)] pb-2.5", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: selectable ? (jsxRuntime.jsx(Checkbox, { checked: selected, onChange: () => toggleItemSelect(key), "aria-label": `Select item ${key}`, label: jsxRuntime.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)
3722
+ ? columns[0].render(item)
3723
+ : 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 : '') }) })) : (jsxRuntime.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)
3724
+ ? columns[0].render(item)
3725
+ : 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] && (jsxRuntime.jsx("div", { className: "shrink-0 text-xs", children: columns[1].render
3726
+ ? columns[1].render(item)
3727
+ : String((_j = get(item, columns[1].name)) !== null && _j !== void 0 ? _j : '') }))] }), columns && columns.length > 2 && (jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-2 text-xs pt-1", children: columns.slice(2).map((col) => {
3728
+ const val = col.render ? col.render(item) : get(item, col.name);
3729
+ if (val === null || val === undefined || val === '')
3730
+ return null;
3731
+ return (jsxRuntime.jsxs("div", { className: "min-w-0", children: [jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500 font-medium block truncate", children: col.label }), jsxRuntime.jsx("span", { className: "text-gray-800 dark:text-gray-200 font-semibold block truncate mt-0.5", children: val })] }, String(col.name)));
3732
+ }) }))] }));
3733
+ if (actions && (((_k = actions.leftActions) === null || _k === void 0 ? void 0 : _k.length) || ((_l = actions.rightActions) === null || _l === void 0 ? void 0 : _l.length))) {
3734
+ return (jsxRuntime.jsx(SwipeableRow, { leftActions: actions.leftActions, rightActions: actions.rightActions, children: contentNode }, key));
3735
+ }
3736
+ return jsxRuntime.jsx("div", { children: contentNode }, key);
3737
+ })) }), pagination && pagination.total > 0 && (jsxRuntime.jsx("div", { className: "pt-2 flex justify-center", children: jsxRuntime.jsx(Pagination, { ...pagination, onChange: (newPag) => setPagination === null || setPagination === void 0 ? void 0 : setPagination(newPag) }) }))] }));
3738
+ }
3739
+ DataList.displayName = 'DataList';
2131
3740
 
2132
3741
  const sizeClasses$1 = {
2133
3742
  sm: {
2134
- input: 'px-2.5 py-1 text-xs leading-5 min-h-[30px]',
3743
+ input: 'px-2.5 py-1.5 text-xs leading-5 min-h-[32px]',
2135
3744
  group: 'w-8 text-xs',
2136
3745
  icon: 'size-3.5',
2137
3746
  badgeSize: 'sm',
@@ -2150,7 +3759,10 @@ const sizeClasses$1 = {
2150
3759
  },
2151
3760
  };
2152
3761
  const SelectBox = React.forwardRef((props, forwardedRef) => {
2153
- 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;
3762
+ 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;
3763
+ if (props.asBottomSheet || props.mobileMode === 'sheet') {
3764
+ return jsxRuntime.jsx(MobilePicker, { ...props });
3765
+ }
2154
3766
  const hasError = Boolean(error);
2155
3767
  const [query, setQuery] = React.useState('');
2156
3768
  const debouncedQuery = useDebounce(query, 500);
@@ -2198,6 +3810,49 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
2198
3810
  const getValue = React.useCallback((opt) => {
2199
3811
  return typeof opt === 'string' ? opt : opt[valueKey];
2200
3812
  }, [valueKey]);
3813
+ const createFreeTextOption = React.useCallback((text) => {
3814
+ const sample = allOptions[0] || (Array.isArray(selected) ? selected[0] : selected);
3815
+ if (typeof sample === 'string' ||
3816
+ (!sample && typeof labelKey === 'string' && labelKey === 'label')) {
3817
+ return text;
3818
+ }
3819
+ return {
3820
+ [labelKey]: text,
3821
+ [valueKey]: text,
3822
+ };
3823
+ }, [allOptions, selected, labelKey, valueKey]);
3824
+ const handleFreeTextCommit = React.useCallback((queryText) => {
3825
+ const trimmed = queryText.trim();
3826
+ if (!trimmed)
3827
+ return;
3828
+ const existing = allOptions.find((opt) => {
3829
+ const display = getDisplayValue(opt);
3830
+ return (display === null || display === void 0 ? void 0 : display.toLowerCase()) === trimmed.toLowerCase();
3831
+ });
3832
+ const valueToCommit = existing || createFreeTextOption(trimmed);
3833
+ if (multiple) {
3834
+ const current = isArray(selected) ? selected : [];
3835
+ const alreadySelected = current.some((item) => { var _a; return ((_a = getDisplayValue(item)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === trimmed.toLowerCase(); });
3836
+ if (!alreadySelected) {
3837
+ if (maxSelection && current.length >= maxSelection)
3838
+ return;
3839
+ onChange([...current, valueToCommit]);
3840
+ }
3841
+ setQuery('');
3842
+ }
3843
+ else {
3844
+ onChange(valueToCommit);
3845
+ setQuery('');
3846
+ }
3847
+ }, [
3848
+ allOptions,
3849
+ getDisplayValue,
3850
+ createFreeTextOption,
3851
+ multiple,
3852
+ selected,
3853
+ maxSelection,
3854
+ onChange,
3855
+ ]);
2201
3856
  const removeSelection = (idx) => {
2202
3857
  var _a;
2203
3858
  if (!isArray(selected))
@@ -2270,11 +3925,25 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
2270
3925
  if (async && debouncedQuery)
2271
3926
  handleSearch(debouncedQuery);
2272
3927
  }, [debouncedQuery, async, handleSearch]);
3928
+ const normalizedSelected = React.useMemo(() => {
3929
+ if (multiple) {
3930
+ if (Array.isArray(selected))
3931
+ return selected;
3932
+ if (selected !== null && selected !== undefined)
3933
+ return [selected];
3934
+ return [];
3935
+ }
3936
+ else {
3937
+ if (Array.isArray(selected))
3938
+ return selected.length > 0 ? selected[0] : null;
3939
+ return selected !== null && selected !== void 0 ? selected : null;
3940
+ }
3941
+ }, [multiple, selected]);
2273
3942
  const isAllSelected = React.useMemo(() => {
2274
- if (!multiple || !Array.isArray(selected) || !allOptions.length)
3943
+ if (!multiple || !Array.isArray(normalizedSelected) || !allOptions.length)
2275
3944
  return false;
2276
- return allOptions.length === selected.length;
2277
- }, [multiple, selected, allOptions]);
3945
+ return allOptions.length === normalizedSelected.length;
3946
+ }, [multiple, normalizedSelected, allOptions]);
2278
3947
  const handleToggleSelectAll = () => {
2279
3948
  if (isAllSelected) {
2280
3949
  onChange([]);
@@ -2284,30 +3953,69 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
2284
3953
  }
2285
3954
  };
2286
3955
  const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
2287
- return (jsxRuntime.jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), ref: containerRef, children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, "aria-required": required, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs(react.Combobox, { multiple: multiple, immediate: immediate, name: name, value: selected, onChange: comboboxOnChangeWrapper, onClose: () => setQuery(''), disabled: disabled, children: [multiple ? (jsxRuntime.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 && (jsxRuntime.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) &&
2288
- (selected === null || selected === void 0 ? void 0 : selected.length) > 0 &&
2289
- selected.map((option, idx) => (jsxRuntime.jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, removable: !disabled, onRemove: () => removeSelection(idx), children: getDisplayValue(option) }, `${getValue(option)}-${idx}`))), jsxRuntime.jsx(react.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) => {
2290
- if (multiple && e.key === 'Backspace' && !query) {
2291
- if (Array.isArray(selected) && selected.length > 0) {
2292
- removeSelection(selected.length - 1);
3956
+ return (jsxRuntime.jsxs("div", { className: buildClassName('group space-y-2', hasError && 'has-error', containerClass), ref: containerRef, children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, "aria-required": required, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs(react.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 ? (jsxRuntime.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 && (jsxRuntime.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) &&
3957
+ (normalizedSelected === null || normalizedSelected === void 0 ? void 0 : normalizedSelected.length) > 0 &&
3958
+ normalizedSelected.map((option, idx) => (jsxRuntime.jsx(Badge, { theme: "secondary", size: currentSize.badgeSize, removable: !disabled, onRemove: () => removeSelection(idx), children: getDisplayValue(option) }, `${getValue(option)}-${idx}`))), jsxRuntime.jsx(react.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) => {
3959
+ const val = e.target.value;
3960
+ if (allowFreeText && multiple && val.includes(',')) {
3961
+ const parts = val.split(',');
3962
+ parts.forEach((p) => {
3963
+ if (p.trim())
3964
+ handleFreeTextCommit(p.trim());
3965
+ });
3966
+ setQuery('');
3967
+ }
3968
+ else {
3969
+ setQuery(val);
3970
+ }
3971
+ }, id: id, ref: inputRef, onKeyDown: (e) => {
3972
+ if (allowFreeText && (e.key === 'Enter' || e.key === ',') && query.trim()) {
3973
+ e.preventDefault();
3974
+ handleFreeTextCommit(query.replace(/,/g, ''));
3975
+ }
3976
+ else if (multiple && e.key === 'Backspace' && !query) {
3977
+ if (Array.isArray(normalizedSelected) && normalizedSelected.length > 0) {
3978
+ removeSelection(normalizedSelected.length - 1);
2293
3979
  }
2294
3980
  }
2295
- }, "data-testid": "combobox-input" }), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxRuntime.jsxs("div", { className: "relative", ref: forwardedRef, children: [hasLeftGroup && (jsxRuntime.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 })), jsxRuntime.jsx(react.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) && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4 stroke-gray-500 dark:stroke-gray-300" }) })), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxRuntime.jsxs(react.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 && (jsxRuntime.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: [jsxRuntime.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' }), jsxRuntime.jsxs("span", { className: "text-[11px] font-medium text-gray-400", children: [Array.isArray(selected) ? selected.length : 0, " of ", allOptions.length] })] })), optionsLoading ? (jsxRuntime.jsx(BodyText, { "data-testid": "options-loading", className: "flex items-center justify-center py-2 px-3 select-none", children: jsxRuntime.jsx(Loader, { size: "sm" }) })) : shouldShowTypeToSearch ? (jsxRuntime.jsx(BodyText, { className: "flex items-center justify-between py-2 px-3 select-none", children: "Type to search..." })) : (jsxRuntime.jsxs("div", { children: [filteredGroups
3981
+ }, onBlur: () => {
3982
+ if (allowFreeText && query.trim()) {
3983
+ handleFreeTextCommit(query.replace(/,/g, ''));
3984
+ }
3985
+ }, "data-testid": "combobox-input" }), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxRuntime.jsxs("div", { className: "relative", ref: forwardedRef, children: [hasLeftGroup && (jsxRuntime.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 })), jsxRuntime.jsx(react.ComboboxInput, { "aria-label": name, displayValue: (option) => (option ? getDisplayValue(option) : null), autoComplete: "off", placeholder: placeholder, onChange: (event) => setQuery(event.target.value), onKeyDown: (e) => {
3986
+ if (allowFreeText && e.key === 'Enter' && query.trim()) {
3987
+ e.preventDefault();
3988
+ handleFreeTextCommit(query);
3989
+ }
3990
+ }, onBlur: () => {
3991
+ if (allowFreeText && query.trim()) {
3992
+ handleFreeTextCommit(query);
3993
+ }
3994
+ }, onFocus: () => {
3995
+ setQuery('');
3996
+ }, 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) && (jsxRuntime.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: jsxRuntime.jsx(SvgX, { className: "size-4 stroke-gray-500 dark:stroke-gray-300" }) })), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5 flex items-center justify-center", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxRuntime.jsxs(react.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 && (jsxRuntime.jsxs("div", { className: "pb-1 mb-1 border-b border-[var(--ui-border-muted)] px-3 pt-1 flex items-center justify-between", children: [jsxRuntime.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' }), jsxRuntime.jsxs("span", { className: "text-[11px] font-medium text-gray-400", children: [Array.isArray(normalizedSelected) ? normalizedSelected.length : 0, " of", ' ', allOptions.length] })] })), optionsLoading ? (jsxRuntime.jsx(BodyText, { "data-testid": "options-loading", className: "flex items-center justify-center py-2 px-3 select-none", children: jsxRuntime.jsx(Loader, { size: "sm" }) })) : shouldShowTypeToSearch ? (jsxRuntime.jsx(BodyText, { className: "flex items-center justify-between py-2 px-3 select-none", children: "Type to search..." })) : (jsxRuntime.jsxs("div", { children: [allowFreeText &&
3997
+ query.trim() &&
3998
+ !allOptions.some((opt) => { var _a; return ((_a = getDisplayValue(opt)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === query.trim().toLowerCase(); }) && (jsxRuntime.jsx(react.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: jsxRuntime.jsxs("span", { children: ["Use \"", query.trim(), "\""] }) }, `freetext-${query.trim()}`)), filteredGroups
2296
3999
  ? filteredGroups.map((grp, gIdx) => (jsxRuntime.jsxs("div", { children: [jsxRuntime.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) => {
2297
4000
  const optVal = getValue(option);
2298
4001
  const isOptSelected = multiple
2299
- ? isArray(selected) && selected.some((s) => getValue(s) === optVal)
2300
- : selected && getValue(selected) === optVal;
2301
- return (jsxRuntime.jsx(react.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))) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 dark:text-white group-data-[selected]:text-blue-600", children: [jsxRuntime.jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsxRuntime.jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
4002
+ ? isArray(normalizedSelected) &&
4003
+ normalizedSelected.some((s) => getValue(s) === optVal)
4004
+ : normalizedSelected && getValue(normalizedSelected) === optVal;
4005
+ return (jsxRuntime.jsx(react.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))) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 text-gray-900 dark:text-white group-data-[selected]:text-blue-600", children: [jsxRuntime.jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsxRuntime.jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
2302
4006
  })] }, gIdx)))
2303
4007
  : /* Render Standard Flat Options */
2304
4008
  filteredOptions.map((option) => {
2305
4009
  const optVal = getValue(option);
2306
4010
  const isOptSelected = multiple
2307
- ? isArray(selected) && selected.some((s) => getValue(s) === optVal)
2308
- : selected && getValue(selected) === optVal;
2309
- return (jsxRuntime.jsx(react.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))) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 dark:text-white group-data-[selected]:text-blue-600", children: [jsxRuntime.jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsxRuntime.jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
2310
- }), filteredOptions.length === 0 && !(filteredGroups === null || filteredGroups === void 0 ? void 0 : filteredGroups.length) && (jsxRuntime.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 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: ["No results found for ", jsxRuntime.jsx("span", { className: "font-semibold", children: query })] })) : (noOptionsText) })), allowAdd && (jsxRuntime.jsx(react.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: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(SvgCirclePlus, { className: "size-4.5" }), jsxRuntime.jsxs(TextContent, { children: [addNewText, " \"", query, "\""] })] }) }))] }))] })] }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText }) }))] }));
4011
+ ? isArray(normalizedSelected) &&
4012
+ normalizedSelected.some((s) => getValue(s) === optVal)
4013
+ : normalizedSelected && getValue(normalizedSelected) === optVal;
4014
+ return (jsxRuntime.jsx(react.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))) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 text-gray-900 dark:text-white group-data-[selected]:text-blue-600", children: [jsxRuntime.jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsxRuntime.jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] })) }, optVal));
4015
+ }), filteredOptions.length === 0 &&
4016
+ !(filteredGroups === null || filteredGroups === void 0 ? void 0 : filteredGroups.length) &&
4017
+ !allowFreeText &&
4018
+ !(allowAdd && query.trim()) && (jsxRuntime.jsxs("div", { "data-testid": "no-result-found", className: "flex items-center gap-2 py-1.5 px-3 select-none", children: [jsxRuntime.jsx(TextContent, { muted: true, small: true, children: noOptionsText }), jsxRuntime.jsx(TextContent, { strong: true, small: true, children: query })] })), !allowFreeText && allowAdd && Boolean(query.trim()) && (jsxRuntime.jsx(react.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: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(SvgCirclePlus, { className: "size-4.5" }), jsxRuntime.jsxs(TextContent, { children: [addNewText, " \"", query, "\""] })] }) }, `add-${query.trim()}`))] }))] })] }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { error: true, small: true, children: error }) })), !error && helperText && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText }) }))] }));
2311
4019
  });
2312
4020
  SelectBox.displayName = 'SelectBox';
2313
4021
 
@@ -2341,10 +4049,15 @@ Skeleton.displayName = 'Skeleton';
2341
4049
 
2342
4050
  const MinusIcon = ({ className }) => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": "true", children: jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) }));
2343
4051
  const PlusIcon = ({ className }) => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": "true", children: [jsxRuntime.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
4052
+ const CONTAINER_SIZE_CLASS = {
4053
+ sm: 'h-8 text-xs',
4054
+ md: 'h-10 text-sm',
4055
+ lg: 'h-12 text-base',
4056
+ };
2344
4057
  const BUTTON_SIZE_CLASS = {
2345
- sm: 'size-7',
2346
- md: 'size-9',
2347
- lg: 'size-10',
4058
+ sm: 'w-7.5 h-full',
4059
+ md: 'w-9.5 h-full',
4060
+ lg: 'w-11 h-full',
2348
4061
  };
2349
4062
  const ICON_SIZE_CLASS = {
2350
4063
  sm: 'size-3.5',
@@ -2352,12 +4065,15 @@ const ICON_SIZE_CLASS = {
2352
4065
  lg: 'size-4.5',
2353
4066
  };
2354
4067
  const INPUT_TEXT_CLASS = {
2355
- sm: 'w-12 text-xs py-1',
2356
- md: 'w-16 text-sm py-1.5',
2357
- lg: 'w-20 text-base py-2',
4068
+ sm: 'w-12 text-xs',
4069
+ md: 'w-16 text-sm',
4070
+ lg: 'w-20 text-base',
2358
4071
  };
2359
4072
  const QuantityStepper = React.forwardRef((props, ref) => {
2360
- const { value, onChange, min = 0, max = 99999, step = 1, label, size = 'md', prefix, suffix, disabled = false, className, onFocus, ...restProps } = props;
4073
+ 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;
4074
+ const autoId = React.useId();
4075
+ const stepperId = customId || `stepper-${autoId}`;
4076
+ const hasError = Boolean(error);
2361
4077
  const handleDecrement = () => {
2362
4078
  if (disabled)
2363
4079
  return;
@@ -2383,10 +4099,18 @@ const QuantityStepper = React.forwardRef((props, ref) => {
2383
4099
  };
2384
4100
  const isAtMin = disabled || value <= min;
2385
4101
  const isAtMax = disabled || value >= max;
2386
- return (jsxRuntime.jsxs("div", { className: buildClassName('flex flex-col gap-1 inline-flex', className), children: [label && (jsxRuntime.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300", children: label })), jsxRuntime.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: [jsxRuntime.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: jsxRuntime.jsx(MinusIcon, { className: ICON_SIZE_CLASS[size] }) }), prefix && jsxRuntime.jsx("span", { className: "pl-1 text-gray-400 dark:text-gray-500", children: prefix }), jsxRuntime.jsx("input", { ref: ref, type: "number", min: min, max: max, step: step, value: value === 0 ? '' : value, placeholder: "0", disabled: disabled, onFocus: (e) => {
4102
+ return (jsxRuntime.jsxs("div", { className: buildClassName('flex flex-col gap-1 inline-flex', className), children: [label && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxRuntime.jsx(Label, { htmlFor: stepperId, className: disabled ? 'opacity-70 cursor-not-allowed' : '', children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.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
4103
+ ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
4104
+ : 'outline-[var(--ui-border)]', disabled
4105
+ ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 outline-[var(--ui-border-muted)]'
4106
+ : '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: [jsxRuntime.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
4107
+ ? 'opacity-30 hover:bg-transparent cursor-not-allowed'
4108
+ : 'cursor-pointer hover:bg-gray-100/80 dark:hover:bg-gray-600/60'), "data-testid": "stepper-decrement", children: jsxRuntime.jsx(MinusIcon, { className: ICON_SIZE_CLASS[size] }) }), prefix && (jsxRuntime.jsx("span", { className: "pl-1 text-gray-400 dark:text-gray-400 select-none text-xs shrink-0", children: prefix })), jsxRuntime.jsx("input", { ref: ref, id: stepperId, type: "number", min: min, max: max, step: step, value: value === 0 ? '' : value, placeholder: "0", disabled: disabled, onFocus: (e) => {
2387
4109
  e.target.select();
2388
4110
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(e);
2389
- }, 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 && jsxRuntime.jsx("span", { className: "pr-1 text-xs text-gray-500 dark:text-gray-400", children: suffix }), jsxRuntime.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: jsxRuntime.jsx(PlusIcon, { className: ICON_SIZE_CLASS[size] }) })] })] }));
4111
+ }, 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 && (jsxRuntime.jsx("span", { className: "pr-1 text-gray-500 dark:text-gray-400 select-none text-xs shrink-0", children: suffix })), jsxRuntime.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
4112
+ ? 'opacity-30 hover:bg-transparent cursor-not-allowed'
4113
+ : 'cursor-pointer hover:bg-gray-100/80 dark:hover:bg-gray-600/60'), "data-testid": "stepper-increment", children: jsxRuntime.jsx(PlusIcon, { className: ICON_SIZE_CLASS[size] }) })] }), (showErrorMessage && error) || helperText ? (jsxRuntime.jsx("div", { className: "flex items-center justify-between gap-2 mt-0.5", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent, { xsmall: true, className: "text-red-500 dark:text-red-400 font-medium", children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { xsmall: true, muted: true, children: helperText })) : null })) : null] }));
2390
4114
  });
2391
4115
  QuantityStepper.displayName = 'QuantityStepper';
2392
4116
 
@@ -2432,7 +4156,7 @@ const SegmentedControl = React.forwardRef((props, ref) => {
2432
4156
  onChange(enabledOptions[enabledOptions.length - 1].value);
2433
4157
  }
2434
4158
  };
2435
- return (jsxRuntime.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) => {
4159
+ return (jsxRuntime.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) => {
2436
4160
  const isSelected = value === option.value;
2437
4161
  const isOptionDisabled = disabled || option.disabled;
2438
4162
  return (jsxRuntime.jsxs("button", { type: "button", role: "tab", "aria-selected": isSelected, "aria-disabled": isOptionDisabled, tabIndex: isSelected && !isOptionDisabled ? 0 : -1, disabled: isOptionDisabled, title: option.title, onClick: () => {
@@ -2493,7 +4217,7 @@ const StickyActionBar = React.forwardRef((props, ref) => {
2493
4217
  : position === 'sticky'
2494
4218
  ? 'sticky bottom-0 z-30'
2495
4219
  : 'relative z-10';
2496
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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: jsxRuntime.jsxs("div", { className: buildClassName('mx-auto flex items-center justify-between gap-3', containerMaxWidth), children: [summaryContent && (jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: drawerContent ? (jsxRuntime.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: [jsxRuntime.jsx("div", { children: summaryContent }), jsxRuntime.jsx(ChevronUpIcon, { className: "size-4 text-[var(--ui-primary)] dark:text-blue-400 shrink-0" })] })) : (jsxRuntime.jsx("div", { children: summaryContent })) })), actionsContent && (jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0 ml-auto", "data-testid": "actions-stack", children: actionsContent }))] }) }), drawerContent && (jsxRuntime.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 }))] }));
4220
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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: jsxRuntime.jsxs("div", { className: buildClassName('mx-auto flex items-center justify-between gap-3', containerMaxWidth), children: [summaryContent && (jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: drawerContent ? (jsxRuntime.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: [jsxRuntime.jsx("div", { children: summaryContent }), jsxRuntime.jsx(ChevronUpIcon, { className: "size-4 text-[var(--ui-primary)] dark:text-blue-400 shrink-0" })] })) : (jsxRuntime.jsx("div", { children: summaryContent })) })), actionsContent && (jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0 ml-auto", "data-testid": "actions-stack", children: actionsContent }))] }) }), drawerContent && (jsxRuntime.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 }))] }));
2497
4221
  });
2498
4222
  StickyActionBar.displayName = 'StickyActionBar';
2499
4223
 
@@ -2523,7 +4247,7 @@ function buildTabClass({ selected, variant, stretch, isVertical, tabClass, }) {
2523
4247
  variantClass = isVertical
2524
4248
  ? buildClassName('px-3 py-2 w-full text-left border-l-2', selected
2525
4249
  ? 'border-[var(--ui-primary)] text-gray-900 dark:text-white'
2526
- : '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')
4250
+ : 'border-transparent text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:border-[var(--ui-border)]')
2527
4251
  : buildClassName('px-3 py-1.5 relative text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white', selected &&
2528
4252
  '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)]');
2529
4253
  break;
@@ -2541,6 +4265,89 @@ function buildTabClass({ selected, variant, stretch, isVertical, tabClass, }) {
2541
4265
  return buildClassName(base, variantClass, tabClass);
2542
4266
  }
2543
4267
 
4268
+ function SwipeableTabs({ items, activeId: externalActiveId, defaultActiveId, onChange, swipeable = true, threshold = 50, headerVariant = 'default', containerClass = '', headerClass = '', contentClass = '', }) {
4269
+ var _a;
4270
+ const [internalActiveId, setInternalActiveId] = React.useState(defaultActiveId || ((_a = items[0]) === null || _a === void 0 ? void 0 : _a.id) || '');
4271
+ const activeId = externalActiveId !== undefined ? externalActiveId : internalActiveId;
4272
+ const activeIndex = Math.max(0, items.findIndex((item) => item.id === activeId));
4273
+ const touchStartX = React.useRef(0);
4274
+ const touchStartY = React.useRef(0);
4275
+ const touchDeltaX = React.useRef(0);
4276
+ const isSwipingHorizontal = React.useRef(null);
4277
+ const handleTabChange = (item) => {
4278
+ if (item.disabled)
4279
+ return;
4280
+ setInternalActiveId(item.id);
4281
+ onChange === null || onChange === void 0 ? void 0 : onChange(item.id);
4282
+ };
4283
+ const handleTouchStart = (e) => {
4284
+ if (!swipeable)
4285
+ return;
4286
+ touchStartX.current = e.touches[0].clientX;
4287
+ touchStartY.current = e.touches[0].clientY;
4288
+ touchDeltaX.current = 0;
4289
+ isSwipingHorizontal.current = null;
4290
+ };
4291
+ const handleTouchMove = (e) => {
4292
+ if (!swipeable)
4293
+ return;
4294
+ const currentX = e.touches[0].clientX;
4295
+ const currentY = e.touches[0].clientY;
4296
+ const deltaX = currentX - touchStartX.current;
4297
+ const deltaY = currentY - touchStartY.current;
4298
+ if (isSwipingHorizontal.current === null) {
4299
+ if (Math.abs(deltaX) > 8 || Math.abs(deltaY) > 8) {
4300
+ isSwipingHorizontal.current = Math.abs(deltaX) > Math.abs(deltaY);
4301
+ }
4302
+ }
4303
+ if (isSwipingHorizontal.current) {
4304
+ touchDeltaX.current = deltaX;
4305
+ }
4306
+ };
4307
+ const handleTouchEnd = () => {
4308
+ if (!swipeable || !isSwipingHorizontal.current)
4309
+ return;
4310
+ const deltaX = touchDeltaX.current;
4311
+ if (Math.abs(deltaX) >= threshold) {
4312
+ if (deltaX < 0 && activeIndex < items.length - 1) {
4313
+ // Swiped Left -> Go to Next Tab
4314
+ const nextItem = items[activeIndex + 1];
4315
+ if (nextItem && !nextItem.disabled) {
4316
+ handleTabChange(nextItem);
4317
+ }
4318
+ }
4319
+ else if (deltaX > 0 && activeIndex > 0) {
4320
+ // Swiped Right -> Go to Previous Tab
4321
+ const prevItem = items[activeIndex - 1];
4322
+ if (prevItem && !prevItem.disabled) {
4323
+ handleTabChange(prevItem);
4324
+ }
4325
+ }
4326
+ }
4327
+ touchDeltaX.current = 0;
4328
+ isSwipingHorizontal.current = null;
4329
+ };
4330
+ return (jsxRuntime.jsxs("div", { className: buildClassName('w-full flex flex-col', containerClass), "data-testid": "swipeable-tabs", children: [jsxRuntime.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' &&
4331
+ '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) => {
4332
+ const isActive = item.id === activeId;
4333
+ if (headerVariant === 'segmented') {
4334
+ return (jsxRuntime.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
4335
+ ? 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow-xs'
4336
+ : '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 && jsxRuntime.jsx("span", { className: "text-sm", children: item.icon }), jsxRuntime.jsx("span", { children: item.label }), item.badge !== undefined && (jsxRuntime.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));
4337
+ }
4338
+ if (headerVariant === 'pills') {
4339
+ return (jsxRuntime.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
4340
+ ? 'bg-blue-600 text-white shadow-xs'
4341
+ : '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 && jsxRuntime.jsx("span", { className: "text-sm", children: item.icon }), jsxRuntime.jsx("span", { children: item.label }), item.badge !== undefined && (jsxRuntime.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));
4342
+ }
4343
+ // Default Underline Tab Header
4344
+ return (jsxRuntime.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
4345
+ ? 'border-blue-600 dark:border-blue-400 text-blue-600 dark:text-blue-400'
4346
+ : '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 && jsxRuntime.jsx("span", { className: "text-sm", children: item.icon }), jsxRuntime.jsx("span", { children: item.label }), item.badge !== undefined && (jsxRuntime.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));
4347
+ }) }), jsxRuntime.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: jsxRuntime.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) => (jsxRuntime.jsx("div", { className: "w-full shrink-0 min-w-full", "data-testid": `swipeable-tab-panel-${item.id}`, children: item.content }, item.id))) }) })] }));
4348
+ }
4349
+ SwipeableTabs.displayName = 'SwipeableTabs';
4350
+
2544
4351
  const sizeClasses = {
2545
4352
  sm: {
2546
4353
  textarea: 'px-2.5 py-1.5 text-xs leading-5 min-h-[60px]',
@@ -2588,7 +4395,7 @@ const Textarea = React.forwardRef((props, ref) => {
2588
4395
  const currentSize = sizeClasses[size] || sizeClasses.md;
2589
4396
  return (jsxRuntime.jsxs("div", { className: buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsxRuntime.jsx(Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsxRuntime.jsx(TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs("div", { className: "relative", children: [hasLeftGroup && (jsxRuntime.jsx("span", { className: "absolute top-2.5 left-3 flex items-center justify-center text-gray-400 dark:text-gray-500", children: leftGroup })), jsxRuntime.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
2590
4397
  ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'
2591
- : '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 && (jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
4398
+ : '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 && (jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
2592
4399
  ? 'text-red-500 font-semibold'
2593
4400
  : 'text-gray-400 dark:text-gray-500'), children: [charLength, maxLength ? ` / ${maxLength}` : ''] }))] })) : null] }));
2594
4401
  });
@@ -2623,10 +4430,10 @@ const progressBarColorMap = {
2623
4430
  };
2624
4431
  const variantStyleMap = {
2625
4432
  accent: {
2626
- 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',
2627
- 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',
2628
- 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',
2629
- 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',
4433
+ 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)]',
4434
+ 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)]',
4435
+ 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)]',
4436
+ 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)]',
2630
4437
  },
2631
4438
  filled: {
2632
4439
  success: 'bg-[var(--ui-success)] text-white shadow-lg',
@@ -2966,7 +4773,10 @@ const useIsMobile = () => {
2966
4773
  React.useEffect(() => {
2967
4774
  const detect = () => {
2968
4775
  const width = window.innerWidth;
2969
- const isTouch = navigator.maxTouchPoints > 1 || window.matchMedia('(pointer: coarse)').matches;
4776
+ const isTouch = (typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1) ||
4777
+ (typeof window !== 'undefined' &&
4778
+ typeof window.matchMedia === 'function' &&
4779
+ window.matchMedia('(pointer: coarse)').matches);
2970
4780
  setIsMobile(width < 600 && isTouch);
2971
4781
  };
2972
4782
  detect();
@@ -2998,10 +4808,12 @@ const useIsTabletOrMobile = () => {
2998
4808
  };
2999
4809
 
3000
4810
  exports.Accordion = Accordion;
4811
+ exports.ActionSheet = ActionSheet;
3001
4812
  exports.Alert = Alert;
3002
4813
  exports.Badge = Badge;
3003
4814
  exports.Banner = Banner;
3004
4815
  exports.BodyText = BodyText;
4816
+ exports.BottomNavigation = BottomNavigation;
3005
4817
  exports.Breadcrumb = Breadcrumb;
3006
4818
  exports.Button = Button;
3007
4819
  exports.ButtonGroup = ButtonGroup;
@@ -3015,6 +4827,7 @@ exports.CardTitle = CardTitle;
3015
4827
  exports.Checkbox = Checkbox;
3016
4828
  exports.CheckboxGroup = CheckboxGroup;
3017
4829
  exports.DOTS = DOTS;
4830
+ exports.DataList = DataList;
3018
4831
  exports.DataTable = DataTable;
3019
4832
  exports.DetailedInformation = DetailedInformation;
3020
4833
  exports.Dot = Dot;
@@ -3022,14 +4835,24 @@ exports.Drawer = Drawer;
3022
4835
  exports.Dropdown = Dropdown;
3023
4836
  exports.EmptyState = EmptyState;
3024
4837
  exports.EmptyTableRow = EmptyTableRow;
4838
+ exports.Flex = Flex;
4839
+ exports.FlexItem = FlexItem;
4840
+ exports.FloatingActionButton = FloatingActionButton;
4841
+ exports.Grid = Grid;
4842
+ exports.GridCol = GridCol;
3025
4843
  exports.HeadingText = HeadingText;
3026
4844
  exports.Input = Input;
3027
4845
  exports.Label = Label;
3028
4846
  exports.Loader = Loader;
4847
+ exports.MobileHeader = MobileHeader;
4848
+ exports.MobilePicker = MobilePicker;
4849
+ exports.MobileStepper = MobileStepper;
3029
4850
  exports.PASSWORD_PLACEHOLDER = PASSWORD_PLACEHOLDER;
3030
4851
  exports.PASSWORD_TYPE = PASSWORD_TYPE;
3031
4852
  exports.Pagination = Pagination;
3032
4853
  exports.PasswordInput = PasswordInput;
4854
+ exports.PinInput = PinInput;
4855
+ exports.PullToRefresh = PullToRefresh;
3033
4856
  exports.QuantityStepper = QuantityStepper;
3034
4857
  exports.Radio = Radio;
3035
4858
  exports.RadioGroup = RadioGroup;
@@ -3042,6 +4865,8 @@ exports.Skeleton = Skeleton;
3042
4865
  exports.SortIconMap = SortIconMap;
3043
4866
  exports.StatusPill = StatusPill;
3044
4867
  exports.StickyActionBar = StickyActionBar;
4868
+ exports.SwipeableRow = SwipeableRow;
4869
+ exports.SwipeableTabs = SwipeableTabs;
3045
4870
  exports.Table = Table;
3046
4871
  exports.TableBody = TableBody;
3047
4872
  exports.TableCell = TableCell;
@@ -3055,6 +4880,7 @@ exports.Textarea = Textarea;
3055
4880
  exports.Toast = Toast;
3056
4881
  exports.ToastProvider = ToastProvider;
3057
4882
  exports.VirtualizedDataTable = VirtualizedDataTable;
4883
+ exports.WheelPicker = WheelPicker;
3058
4884
  exports.buildClassName = buildClassName;
3059
4885
  exports.buildInputClass = buildInputClass;
3060
4886
  exports.evaluatePasswordStrength = evaluatePasswordStrength;