@plexui/ui 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/README.md +1 -3
  2. package/dist/es/components/Accordion/Accordion.js +2 -2
  3. package/dist/es/components/Accordion/Accordion.js.map +1 -1
  4. package/dist/es/components/Accordion/index.js +1 -1
  5. package/dist/es/components/Alert/Alert.js +6 -6
  6. package/dist/es/components/Alert/Alert.js.map +1 -1
  7. package/dist/es/components/Alert/index.js +1 -1
  8. package/dist/es/components/Avatar/Avatar.js +12 -5
  9. package/dist/es/components/Avatar/Avatar.js.map +1 -1
  10. package/dist/es/components/Avatar/AvatarGroup.js +2 -2
  11. package/dist/es/components/Avatar/AvatarGroup.js.map +1 -1
  12. package/dist/es/components/Avatar/index.js +2 -2
  13. package/dist/es/components/Badge/index.js +3 -3
  14. package/dist/es/components/Badge/index.js.map +1 -1
  15. package/dist/es/components/Breadcrumb/Breadcrumb.js +34 -0
  16. package/dist/es/components/Breadcrumb/Breadcrumb.js.map +1 -0
  17. package/dist/es/components/Breadcrumb/index.js +2 -0
  18. package/dist/es/components/Breadcrumb/index.js.map +1 -0
  19. package/dist/es/components/Button/Button.js +7 -7
  20. package/dist/es/components/Button/Button.js.map +1 -1
  21. package/dist/es/components/Button/CopyButton.js +25 -13
  22. package/dist/es/components/Button/CopyButton.js.map +1 -1
  23. package/dist/es/components/Button/index.js +2 -2
  24. package/dist/es/components/ButtonGroup/ButtonGroup.js +2 -2
  25. package/dist/es/components/ButtonGroup/ButtonGroup.js.map +1 -1
  26. package/dist/es/components/ButtonGroup/index.js +1 -1
  27. package/dist/es/components/Card/Card.js +4 -3
  28. package/dist/es/components/Card/Card.js.map +1 -1
  29. package/dist/es/components/Card/index.js +1 -1
  30. package/dist/es/components/Checkbox/Checkbox.js +12 -6
  31. package/dist/es/components/Checkbox/Checkbox.js.map +1 -1
  32. package/dist/es/components/Checkbox/index.js +1 -1
  33. package/dist/es/components/CodeBlock/CodeBlock.js +25 -25
  34. package/dist/es/components/CodeBlock/CodeBlock.js.map +1 -1
  35. package/dist/es/components/CodeBlock/CollapsibleCodeBlock.js +6 -4
  36. package/dist/es/components/CodeBlock/CollapsibleCodeBlock.js.map +1 -1
  37. package/dist/es/components/CodeBlock/index.js +2 -2
  38. package/dist/es/components/DataTable/DataTable.js +108 -27
  39. package/dist/es/components/DataTable/DataTable.js.map +1 -1
  40. package/dist/es/components/DataTable/DataTableColumnHeader.js +2 -2
  41. package/dist/es/components/DataTable/DataTableColumnHeader.js.map +1 -1
  42. package/dist/es/components/DataTable/DataTablePagination.js +8 -4
  43. package/dist/es/components/DataTable/DataTablePagination.js.map +1 -1
  44. package/dist/es/components/DataTable/columnHelpers.js +3 -3
  45. package/dist/es/components/DataTable/index.js +4 -4
  46. package/dist/es/components/DateInput/DateInput.js +21 -13
  47. package/dist/es/components/DateInput/DateInput.js.map +1 -1
  48. package/dist/es/components/DateInput/index.js +1 -1
  49. package/dist/es/components/DatePicker/Calendar.js +136 -32
  50. package/dist/es/components/DatePicker/Calendar.js.map +1 -1
  51. package/dist/es/components/DatePicker/DatePicker.js +15 -11
  52. package/dist/es/components/DatePicker/DatePicker.js.map +1 -1
  53. package/dist/es/components/DatePicker/index.js +1 -1
  54. package/dist/es/components/DateRangePicker/Calendar.js +125 -22
  55. package/dist/es/components/DateRangePicker/Calendar.js.map +1 -1
  56. package/dist/es/components/DateRangePicker/DateRangePicker.js +10 -9
  57. package/dist/es/components/DateRangePicker/DateRangePicker.js.map +1 -1
  58. package/dist/es/components/DateRangePicker/Trigger.js +12 -9
  59. package/dist/es/components/DateRangePicker/Trigger.js.map +1 -1
  60. package/dist/es/components/DateRangePicker/index.js +2 -2
  61. package/dist/es/components/Dialog/Dialog.js +11 -6
  62. package/dist/es/components/Dialog/Dialog.js.map +1 -1
  63. package/dist/es/components/Dialog/index.js +1 -1
  64. package/dist/es/components/Dialog/index.js.map +1 -1
  65. package/dist/es/components/EmptyMessage/EmptyMessage.js +4 -4
  66. package/dist/es/components/EmptyMessage/EmptyMessage.js.map +1 -1
  67. package/dist/es/components/EmptyMessage/index.js +1 -1
  68. package/dist/es/components/Field/Field.js +22 -7
  69. package/dist/es/components/Field/Field.js.map +1 -1
  70. package/dist/es/components/Field/index.js +1 -1
  71. package/dist/es/components/FieldError/FieldError.js +4 -4
  72. package/dist/es/components/FieldError/FieldError.js.map +1 -1
  73. package/dist/es/components/FieldError/index.js +1 -1
  74. package/dist/es/components/FileUpload/FileUpload.js +12 -9
  75. package/dist/es/components/FileUpload/FileUpload.js.map +1 -1
  76. package/dist/es/components/FileUpload/index.js +1 -1
  77. package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js +31 -4
  78. package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js.map +1 -1
  79. package/dist/es/components/FloatingLabelInput/index.js +1 -1
  80. package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js +28 -8
  81. package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js.map +1 -1
  82. package/dist/es/components/FloatingLabelSelect/index.js +1 -1
  83. package/dist/es/components/Icon/aliases.js +20 -20
  84. package/dist/es/components/Icon/index.js +653 -653
  85. package/dist/es/components/Image/Image.js +19 -7
  86. package/dist/es/components/Image/Image.js.map +1 -1
  87. package/dist/es/components/Image/index.js +1 -1
  88. package/dist/es/components/Indicator/CircularProgress.js +3 -3
  89. package/dist/es/components/Indicator/CircularProgress.js.map +1 -1
  90. package/dist/es/components/Indicator/LoadingDots.js +1 -1
  91. package/dist/es/components/Indicator/LoadingDots.js.map +1 -1
  92. package/dist/es/components/Indicator/LoadingIndicator.js +2 -2
  93. package/dist/es/components/Indicator/LoadingIndicator.js.map +1 -1
  94. package/dist/es/components/Indicator/index.js +3 -3
  95. package/dist/es/components/Input/Input.js +16 -5
  96. package/dist/es/components/Input/Input.js.map +1 -1
  97. package/dist/es/components/Input/index.js +1 -1
  98. package/dist/es/components/InputGroup/InputGroup.js +60 -0
  99. package/dist/es/components/InputGroup/InputGroup.js.map +1 -0
  100. package/dist/es/components/InputGroup/index.js +2 -0
  101. package/dist/es/components/InputGroup/index.js.map +1 -0
  102. package/dist/es/components/Kbd/Kbd.js +13 -0
  103. package/dist/es/components/Kbd/Kbd.js.map +1 -0
  104. package/dist/es/components/Kbd/index.js +2 -0
  105. package/dist/es/components/Kbd/index.js.map +1 -0
  106. package/dist/es/components/Label/Label.js +1 -1
  107. package/dist/es/components/Label/Label.js.map +1 -1
  108. package/dist/es/components/Label/index.js +1 -1
  109. package/dist/es/components/Markdown/Markdown.js +8 -8
  110. package/dist/es/components/Markdown/Markdown.js.map +1 -1
  111. package/dist/es/components/Markdown/directives.js +2 -2
  112. package/dist/es/components/Markdown/index.js +4 -5
  113. package/dist/es/components/Markdown/index.js.map +1 -1
  114. package/dist/es/components/MarkdownEditor/MarkdownEditor.js +35 -11
  115. package/dist/es/components/MarkdownEditor/MarkdownEditor.js.map +1 -1
  116. package/dist/es/components/MarkdownEditor/index.js +1 -1
  117. package/dist/es/components/Menu/Menu.js +26 -18
  118. package/dist/es/components/Menu/Menu.js.map +1 -1
  119. package/dist/es/components/Menu/index.js +1 -1
  120. package/dist/es/components/OTPInput/OTPInput.js +51 -34
  121. package/dist/es/components/OTPInput/OTPInput.js.map +1 -1
  122. package/dist/es/components/OTPInput/index.js +1 -1
  123. package/dist/es/components/PlexUIProvider/PlexUIProvider.js +3 -1
  124. package/dist/es/components/PlexUIProvider/PlexUIProvider.js.map +1 -1
  125. package/dist/es/components/PlexUIProvider/index.js +1 -1
  126. package/dist/es/components/PlexUIProvider/internal.js +1 -1
  127. package/dist/es/components/Popover/Popover.js +7 -7
  128. package/dist/es/components/Popover/Popover.js.map +1 -1
  129. package/dist/es/components/Popover/index.js +2 -3
  130. package/dist/es/components/Popover/index.js.map +1 -1
  131. package/dist/es/components/Popover/usePopoverController.js +2 -2
  132. package/dist/es/components/Progress/Progress.js +1 -1
  133. package/dist/es/components/Progress/Progress.js.map +1 -1
  134. package/dist/es/components/Progress/index.js +1 -1
  135. package/dist/es/components/ProgressSteps/ProgressSteps.js +6 -4
  136. package/dist/es/components/ProgressSteps/ProgressSteps.js.map +1 -1
  137. package/dist/es/components/ProgressSteps/index.js +1 -1
  138. package/dist/es/components/RadioGroup/RadioGroup.js +10 -6
  139. package/dist/es/components/RadioGroup/RadioGroup.js.map +1 -1
  140. package/dist/es/components/RadioGroup/index.js +1 -1
  141. package/dist/es/components/SegmentedControl/index.js +1 -1
  142. package/dist/es/components/Select/Select.js +104 -67
  143. package/dist/es/components/Select/Select.js.map +1 -1
  144. package/dist/es/components/Select/index.js +1 -1
  145. package/dist/es/components/SelectControl/SelectControl.js +10 -5
  146. package/dist/es/components/SelectControl/SelectControl.js.map +1 -1
  147. package/dist/es/components/SelectControl/index.js +1 -1
  148. package/dist/es/components/Separator/Separator.js +1 -1
  149. package/dist/es/components/Separator/Separator.js.map +1 -1
  150. package/dist/es/components/Separator/index.js +1 -1
  151. package/dist/es/components/ShimmerText/ShimmerText.js +1 -1
  152. package/dist/es/components/ShimmerText/ShimmerText.js.map +1 -1
  153. package/dist/es/components/ShimmerText/index.js +1 -1
  154. package/dist/es/components/Sidebar/Sidebar.js +37 -29
  155. package/dist/es/components/Sidebar/Sidebar.js.map +1 -1
  156. package/dist/es/components/Sidebar/index.js +2 -2
  157. package/dist/es/components/Sidebar/useSidebarContext.js +17 -19
  158. package/dist/es/components/Sidebar/useSidebarContext.js.map +1 -1
  159. package/dist/es/components/Skeleton/index.js +1 -1
  160. package/dist/es/components/Skeleton/index.js.map +1 -1
  161. package/dist/es/components/Slider/Slider.js +48 -19
  162. package/dist/es/components/Slider/Slider.js.map +1 -1
  163. package/dist/es/components/Slider/index.js +1 -1
  164. package/dist/es/components/StatCard/StatCard.js +5 -5
  165. package/dist/es/components/StatCard/StatCard.js.map +1 -1
  166. package/dist/es/components/StatCard/index.js +1 -1
  167. package/dist/es/components/Switch/Switch.js +7 -3
  168. package/dist/es/components/Switch/Switch.js.map +1 -1
  169. package/dist/es/components/Switch/index.js +1 -1
  170. package/dist/es/components/Table/Table.js +1 -1
  171. package/dist/es/components/Table/Table.js.map +1 -1
  172. package/dist/es/components/Table/index.js +1 -1
  173. package/dist/es/components/Tabs/Tabs.js +154 -6
  174. package/dist/es/components/Tabs/Tabs.js.map +1 -1
  175. package/dist/es/components/Tabs/index.js +1 -1
  176. package/dist/es/components/Tabs/overflow.js +44 -0
  177. package/dist/es/components/Tabs/overflow.js.map +1 -0
  178. package/dist/es/components/TagInput/TagInput.js +47 -23
  179. package/dist/es/components/TagInput/TagInput.js.map +1 -1
  180. package/dist/es/components/TagInput/index.js +1 -1
  181. package/dist/es/components/TextLink/TextLink.js +16 -5
  182. package/dist/es/components/TextLink/TextLink.js.map +1 -1
  183. package/dist/es/components/TextLink/index.js +1 -1
  184. package/dist/es/components/Textarea/Textarea.js +4 -4
  185. package/dist/es/components/Textarea/Textarea.js.map +1 -1
  186. package/dist/es/components/Textarea/index.js +1 -1
  187. package/dist/es/components/Toast/Toaster.js +2 -2
  188. package/dist/es/components/Toast/Toaster.js.map +1 -1
  189. package/dist/es/components/Toast/index.js +1 -1
  190. package/dist/es/components/Tooltip/CopyTooltip.js +30 -9
  191. package/dist/es/components/Tooltip/CopyTooltip.js.map +1 -1
  192. package/dist/es/components/Tooltip/Tooltip.js +3 -3
  193. package/dist/es/components/Tooltip/Tooltip.js.map +1 -1
  194. package/dist/es/components/Tooltip/index.js +2 -2
  195. package/dist/es/components/Transition/Animate.js +4 -4
  196. package/dist/es/components/Transition/Animate.js.map +1 -1
  197. package/dist/es/components/Transition/AnimateLayout.js +4 -4
  198. package/dist/es/components/Transition/AnimateLayout.js.map +1 -1
  199. package/dist/es/components/Transition/AnimateLayoutGroup.js +12 -8
  200. package/dist/es/components/Transition/AnimateLayoutGroup.js.map +1 -1
  201. package/dist/es/components/Transition/SlotTransitionGroup.js +4 -4
  202. package/dist/es/components/Transition/TransitionGroup.js +5 -5
  203. package/dist/es/components/Transition/TransitionGroup.js.map +1 -1
  204. package/dist/es/components/Transition/getDisableAnimations.js +1 -1
  205. package/dist/es/components/Transition/index.js +5 -5
  206. package/dist/es/components/Transition/shared.js +7 -5
  207. package/dist/es/components/Transition/shared.js.map +1 -1
  208. package/dist/es/components/UIProvider/UIProvider.js +1 -1
  209. package/dist/es/components/UIProvider/index.js +1 -1
  210. package/dist/es/components/UIProvider/internal.js +1 -1
  211. package/dist/es/hooks/useAnimatedScrollTo.js +1 -1
  212. package/dist/es/hooks/useBreakpoints.js +8 -2
  213. package/dist/es/hooks/useBreakpoints.js.map +1 -1
  214. package/dist/es/hooks/useEscCloseStack.js +1 -1
  215. package/dist/es/hooks/usePrevious.js +7 -5
  216. package/dist/es/hooks/usePrevious.js.map +1 -1
  217. package/dist/es/hooks/useTextSelection.js +2 -2
  218. package/dist/es/hooks/useTrailingValue.js +1 -1
  219. package/dist/es/lib/constants.js +1 -1
  220. package/dist/es/lib/helpers.js +1 -1
  221. package/dist/es/lib/helpers.js.map +1 -1
  222. package/dist/es/lib/renderHelpers.js +15 -6
  223. package/dist/es/lib/renderHelpers.js.map +1 -1
  224. package/dist/es/lib/theme.js +16 -16
  225. package/dist/es/lib/theme.js.map +1 -1
  226. package/dist/es/lib/userAgent.js +3 -2
  227. package/dist/es/lib/userAgent.js.map +1 -1
  228. package/dist/es/styles/base.css +1 -102
  229. package/dist/es/styles/globals.css +1 -50
  230. package/dist/es/styles/index.css +1 -25
  231. package/dist/es/styles/katex.min.css +1 -1296
  232. package/dist/es/styles/tailwind-utilities.css +1 -1316
  233. package/dist/es/styles/variables-components.css +1 -626
  234. package/dist/es/styles/variables-primitive.css +1 -327
  235. package/dist/es/styles/variables-semantic.css +1 -609
  236. package/dist/es/styles/variables-tailwind-theme.css +1 -34
  237. package/dist/es/styles/variables-tokens-root.css +1 -41
  238. package/dist/es/types.js +1 -1
  239. package/dist/es/types.js.map +1 -1
  240. package/dist/es/vite/index.js +3 -53
  241. package/dist/es/vite/index.js.map +1 -1
  242. package/dist/types/components/Accordion/index.d.ts +1 -1
  243. package/dist/types/components/Alert/Alert.d.ts +8 -2
  244. package/dist/types/components/Alert/index.d.ts +1 -1
  245. package/dist/types/components/Avatar/Avatar.d.ts +1 -1
  246. package/dist/types/components/Avatar/index.d.ts +2 -2
  247. package/dist/types/components/Badge/index.d.ts +1 -1
  248. package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +34 -0
  249. package/dist/types/components/Breadcrumb/index.d.ts +1 -0
  250. package/dist/types/components/Button/Button.d.ts +3 -3
  251. package/dist/types/components/Button/CopyButton.d.ts +9 -4
  252. package/dist/types/components/Button/index.d.ts +2 -2
  253. package/dist/types/components/ButtonGroup/ButtonGroup.d.ts +4 -3
  254. package/dist/types/components/ButtonGroup/index.d.ts +1 -1
  255. package/dist/types/components/Card/index.d.ts +1 -1
  256. package/dist/types/components/Checkbox/Checkbox.d.ts +3 -1
  257. package/dist/types/components/Checkbox/index.d.ts +1 -1
  258. package/dist/types/components/CodeBlock/index.d.ts +2 -2
  259. package/dist/types/components/DataTable/DataTable.d.ts +3 -2
  260. package/dist/types/components/DataTable/index.d.ts +4 -4
  261. package/dist/types/components/DateInput/DateInput.d.ts +1 -1
  262. package/dist/types/components/DateInput/index.d.ts +1 -1
  263. package/dist/types/components/DatePicker/DatePicker.d.ts +7 -6
  264. package/dist/types/components/DatePicker/context.d.ts +1 -1
  265. package/dist/types/components/DatePicker/index.d.ts +2 -2
  266. package/dist/types/components/DateRangePicker/Calendar.d.ts +1 -1
  267. package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +5 -5
  268. package/dist/types/components/DateRangePicker/context.d.ts +2 -2
  269. package/dist/types/components/DateRangePicker/index.d.ts +2 -2
  270. package/dist/types/components/Dialog/Dialog.d.ts +19 -1
  271. package/dist/types/components/Dialog/index.d.ts +1 -1
  272. package/dist/types/components/EmptyMessage/EmptyMessage.d.ts +15 -3
  273. package/dist/types/components/EmptyMessage/index.d.ts +1 -1
  274. package/dist/types/components/Field/Field.d.ts +14 -4
  275. package/dist/types/components/Field/index.d.ts +1 -1
  276. package/dist/types/components/FieldError/FieldError.d.ts +7 -1
  277. package/dist/types/components/FieldError/index.d.ts +1 -1
  278. package/dist/types/components/FileUpload/index.d.ts +1 -1
  279. package/dist/types/components/FloatingLabelInput/index.d.ts +1 -1
  280. package/dist/types/components/FloatingLabelSelect/index.d.ts +1 -1
  281. package/dist/types/components/Icon/aliases.d.ts +20 -20
  282. package/dist/types/components/Icon/index.d.ts +653 -653
  283. package/dist/types/components/Image/Image.d.ts +1 -1
  284. package/dist/types/components/Image/index.d.ts +1 -1
  285. package/dist/types/components/Indicator/index.d.ts +3 -3
  286. package/dist/types/components/Input/Input.d.ts +2 -2
  287. package/dist/types/components/Input/index.d.ts +1 -1
  288. package/dist/types/components/InputGroup/InputGroup.d.ts +78 -0
  289. package/dist/types/components/InputGroup/index.d.ts +1 -0
  290. package/dist/types/components/Kbd/Kbd.d.ts +20 -0
  291. package/dist/types/components/Kbd/index.d.ts +1 -0
  292. package/dist/types/components/Label/index.d.ts +1 -1
  293. package/dist/types/components/Markdown/Markdown.d.ts +1 -1
  294. package/dist/types/components/Markdown/index.d.ts +4 -4
  295. package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts +6 -2
  296. package/dist/types/components/MarkdownEditor/index.d.ts +1 -1
  297. package/dist/types/components/Menu/Menu.d.ts +11 -3
  298. package/dist/types/components/Menu/index.d.ts +1 -1
  299. package/dist/types/components/OTPInput/index.d.ts +1 -1
  300. package/dist/types/components/PlexUIProvider/PlexUIProvider.d.ts +0 -11
  301. package/dist/types/components/PlexUIProvider/index.d.ts +1 -1
  302. package/dist/types/components/Popover/index.d.ts +2 -2
  303. package/dist/types/components/Progress/index.d.ts +1 -1
  304. package/dist/types/components/ProgressSteps/ProgressSteps.d.ts +1 -1
  305. package/dist/types/components/ProgressSteps/index.d.ts +1 -1
  306. package/dist/types/components/RadioGroup/RadioGroup.d.ts +3 -1
  307. package/dist/types/components/RadioGroup/index.d.ts +1 -1
  308. package/dist/types/components/SegmentedControl/index.d.ts +2 -2
  309. package/dist/types/components/Select/Select.d.ts +8 -1
  310. package/dist/types/components/Select/index.d.ts +1 -1
  311. package/dist/types/components/SelectControl/SelectControl.d.ts +1 -1
  312. package/dist/types/components/SelectControl/index.d.ts +1 -1
  313. package/dist/types/components/Separator/index.d.ts +1 -1
  314. package/dist/types/components/ShimmerText/index.d.ts +1 -1
  315. package/dist/types/components/Sidebar/Sidebar.d.ts +4 -8
  316. package/dist/types/components/Sidebar/index.d.ts +4 -4
  317. package/dist/types/components/Slider/Slider.d.ts +8 -0
  318. package/dist/types/components/Slider/index.d.ts +2 -2
  319. package/dist/types/components/StatCard/index.d.ts +1 -1
  320. package/dist/types/components/Switch/index.d.ts +1 -1
  321. package/dist/types/components/Table/index.d.ts +1 -1
  322. package/dist/types/components/Tabs/Tabs.d.ts +15 -2
  323. package/dist/types/components/Tabs/index.d.ts +2 -2
  324. package/dist/types/components/Tabs/overflow.d.ts +17 -0
  325. package/dist/types/components/TagInput/TagInput.d.ts +1 -1
  326. package/dist/types/components/TagInput/index.d.ts +1 -1
  327. package/dist/types/components/TextLink/index.d.ts +1 -1
  328. package/dist/types/components/Textarea/Textarea.d.ts +1 -1
  329. package/dist/types/components/Textarea/index.d.ts +1 -1
  330. package/dist/types/components/Toast/index.d.ts +1 -1
  331. package/dist/types/components/Tooltip/CopyTooltip.d.ts +6 -1
  332. package/dist/types/components/Tooltip/index.d.ts +2 -2
  333. package/dist/types/components/Transition/Animate.d.ts +2 -2
  334. package/dist/types/components/Transition/AnimateLayout.d.ts +2 -2
  335. package/dist/types/components/Transition/AnimateLayoutGroup.d.ts +2 -2
  336. package/dist/types/components/Transition/SlotTransitionGroup.d.ts +1 -1
  337. package/dist/types/components/Transition/TransitionGroup.d.ts +1 -1
  338. package/dist/types/components/Transition/index.d.ts +5 -5
  339. package/dist/types/components/UIProvider/index.d.ts +1 -1
  340. package/dist/types/global.d.ts +5 -1
  341. package/dist/types/lib/constants.d.ts +1 -1
  342. package/dist/types/lib/helpers.d.ts +4 -4
  343. package/dist/types/lib/theme.d.ts +1 -1
  344. package/dist/types/types.d.ts +2 -15
  345. package/dist/types/vite/index.d.ts +2 -55
  346. package/package.json +10 -18
  347. package/dist/es/components/Accordion/Accordion.module.css +0 -89
  348. package/dist/es/components/Alert/Alert.module.css +0 -187
  349. package/dist/es/components/Avatar/Avatar.module.css +0 -168
  350. package/dist/es/components/Avatar/AvatarGroup.module.css +0 -26
  351. package/dist/es/components/Badge/Badge.module.css +0 -196
  352. package/dist/es/components/Button/Button.module.css +0 -859
  353. package/dist/es/components/ButtonGroup/ButtonGroup.module.css +0 -159
  354. package/dist/es/components/Card/Card.module.css +0 -125
  355. package/dist/es/components/Checkbox/Checkbox.module.css +0 -198
  356. package/dist/es/components/CodeBlock/CodeBlock.module.css +0 -137
  357. package/dist/es/components/DataTable/DataTable.module.css +0 -108
  358. package/dist/es/components/DatePicker/Calendar.module.css +0 -271
  359. package/dist/es/components/DateRangePicker/Calendar.module.css +0 -295
  360. package/dist/es/components/DateRangePicker/Trigger.module.css +0 -25
  361. package/dist/es/components/Dialog/Dialog.module.css +0 -133
  362. package/dist/es/components/EmptyMessage/EmptyMessage.module.css +0 -82
  363. package/dist/es/components/Field/Field.module.css +0 -137
  364. package/dist/es/components/FieldError/FieldError.module.css +0 -22
  365. package/dist/es/components/FileUpload/FileUpload.module.css +0 -133
  366. package/dist/es/components/FloatingLabelInput/FloatingLabelInput.module.css +0 -220
  367. package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.module.css +0 -146
  368. package/dist/es/components/Image/Image.module.css +0 -9
  369. package/dist/es/components/Indicator/CircularProgress.module.css +0 -28
  370. package/dist/es/components/Indicator/LoadingDots.module.css +0 -35
  371. package/dist/es/components/Indicator/LoadingIndicator.module.css +0 -41
  372. package/dist/es/components/Input/Input.module.css +0 -507
  373. package/dist/es/components/Label/Label.module.css +0 -16
  374. package/dist/es/components/Markdown/Markdown.module.css +0 -233
  375. package/dist/es/components/MarkdownEditor/MarkdownEditor.module.css +0 -297
  376. package/dist/es/components/Menu/Menu.module.css +0 -377
  377. package/dist/es/components/OTPInput/OTPInput.module.css +0 -66
  378. package/dist/es/components/Popover/Popover.module.css +0 -82
  379. package/dist/es/components/Progress/Progress.module.css +0 -34
  380. package/dist/es/components/ProgressSteps/ProgressSteps.module.css +0 -246
  381. package/dist/es/components/RadioGroup/RadioGroup.module.css +0 -137
  382. package/dist/es/components/Select/Select.module.css +0 -310
  383. package/dist/es/components/SelectControl/SelectControl.module.css +0 -558
  384. package/dist/es/components/Separator/Separator.module.css +0 -16
  385. package/dist/es/components/ShimmerText/ShimmerText.module.css +0 -43
  386. package/dist/es/components/Sidebar/Sidebar.module.css +0 -909
  387. package/dist/es/components/Skeleton/Skeleton.module.css +0 -17
  388. package/dist/es/components/Slider/Slider.module.css +0 -203
  389. package/dist/es/components/StatCard/StatCard.module.css +0 -234
  390. package/dist/es/components/Switch/Switch.module.css +0 -121
  391. package/dist/es/components/Table/Table.module.css +0 -56
  392. package/dist/es/components/Tabs/Tabs.module.css +0 -672
  393. package/dist/es/components/TagInput/TagInput.module.css +0 -320
  394. package/dist/es/components/TextLink/TextLink.module.css +0 -50
  395. package/dist/es/components/Textarea/Textarea.module.css +0 -272
  396. package/dist/es/components/Toast/Toast.module.css +0 -84
  397. package/dist/es/components/Tooltip/Tooltip.module.css +0 -91
  398. package/dist/es/components/Transition/Animate.module.css +0 -54
  399. package/dist/es/components/Transition/AnimateLayout.module.css +0 -101
  400. package/dist/es/components/Transition/AnimateLayoutGroup.module.css +0 -72
  401. package/dist/es/components/Transition/TransitionGroup.module.css +0 -4
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import clsx from "clsx";
4
4
  import { RadioGroup as RadixRadioGroup } from "radix-ui";
5
5
  import React, { createContext, use, useId, useMemo } from "react";
6
- import s from "./RadioGroup.module.css";
6
+ import s from "@plexui/styles/components/RadioGroup/RadioGroup.module.css";
7
7
  const RadioGroupContext = createContext(null);
8
8
  const useRadioGroupContext = () => {
9
9
  const context = use(RadioGroupContext);
@@ -19,19 +19,23 @@ export const RadioGroup = ({ onChange, children, className, direction = "row", d
19
19
  }), [disabled, direction]);
20
20
  return (_jsx(RadioGroupContext, { value: store, children: _jsx(RadixRadioGroup.Root, { className: clsx(s.RadioGroup, className), "data-direction": direction, onValueChange: onChange, disabled: disabled, ...restProps, children: children }) }));
21
21
  };
22
- const Item = ({ value, disabled: itemDisabled = false, required, children, className, block = false, orientation = "left", ...restProps }) => {
22
+ const Item = ({ value, disabled: itemDisabled = false, required, children, description, className, block = false, orientation = "left", ...restProps }) => {
23
23
  const { disabled: groupDisabled } = useRadioGroupContext();
24
24
  const disabled = groupDisabled || itemDisabled;
25
25
  const id = useId();
26
26
  const itemId = `${value}-${id}`;
27
+ const descriptionId = description ? `${itemId}-description` : undefined;
28
+ const label = (_jsxs("label", { htmlFor: itemId, className: clsx(s.RadioLabel, className), "data-disabled": disabled ? "" : undefined, "data-block": block ? "" : undefined, "data-orientation": orientation, onMouseDown: (event) => {
29
+ if (!event.defaultPrevented && event.detail > 1)
30
+ event.preventDefault();
31
+ }, children: [_jsx("div", { className: s.RadioIndicatorWrapper, children: _jsx(RadixRadioGroup.Item, { id: itemId, value: value, disabled: disabled, required: required, className: s.RadioItem, "aria-describedby": descriptionId, children: _jsx(RadixRadioGroup.Indicator, { className: s.RadioIndicator }) }) }), children] }));
27
32
  return (
28
33
  // Providing an extra wrapper enables `label` to be inline-flex, avoiding clickable whitespace
29
34
  // when radio options are of varied lengths.
30
35
  // NOTE: Important that this is `flex` to prevent the `inline-flex` label from extra, unintentional whitespace.
31
- _jsx("div", { className: clsx("flex", block && "w-full"), ...restProps, children: _jsxs("label", { htmlFor: itemId, className: clsx(s.RadioLabel, className), "data-disabled": disabled ? "" : undefined, "data-block": block ? "" : undefined, "data-orientation": orientation, onMouseDown: (event) => {
32
- if (!event.defaultPrevented && event.detail > 1)
33
- event.preventDefault();
34
- }, children: [_jsx("div", { className: s.RadioIndicatorWrapper, children: _jsx(RadixRadioGroup.Item, { id: itemId, value: value, disabled: disabled, required: required, className: s.RadioItem, children: _jsx(RadixRadioGroup.Indicator, { className: s.RadioIndicator }) }) }), children] }) }));
36
+ _jsx("div", { className: clsx("flex", block && "w-full"), ...restProps, children: description ? (
37
+ // The description stays outside the label, so it describes the radio instead of naming it
38
+ _jsxs("div", { className: s.RadioItemGroup, "data-block": block ? "" : undefined, "data-orientation": orientation, children: [label, _jsx("span", { id: descriptionId, className: s.RadioDescription, "data-disabled": disabled ? "" : undefined, children: description })] })) : (label) }));
35
39
  };
36
40
  RadioGroup.Item = Item;
37
41
  //# sourceMappingURL=RadioGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../../../src/components/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\"\nimport React, { createContext, use, useId, useMemo } from \"react\"\nimport s from \"./RadioGroup.module.css\"\n\ntype Direction = \"col\" | \"row\"\n\ntype RadioGroupContextValue = {\n disabled: boolean\n direction: Direction\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null)\n\nconst useRadioGroupContext = () => {\n const context = use(RadioGroupContext)\n\n if (!context) {\n throw new Error(\"RadioGroup components must be wrapped in <RadioGroup />\")\n }\n\n return context\n}\n\nexport type RadioGroupProps<T extends string> = {\n \"defaultValue\"?: T\n \"value\"?: T\n \"name\"?: string\n \"onChange\"?: (value: T) => void\n /** Accessible label for the radio options */\n \"aria-label\"?: string\n /** Determines the layout direction of the radio items\n * @default row\n */\n \"direction\"?: Direction\n /** Controls whether the entire radio group is disabled */\n \"disabled\"?: boolean\n /** Class applied to the radio group container */\n \"className\"?: string\n \"children\": React.ReactNode\n \"required\"?: boolean\n}\n\nexport const RadioGroup = <T extends string>({\n onChange,\n children,\n className,\n direction = \"row\",\n disabled = false,\n ...restProps\n}: RadioGroupProps<T>) => {\n const store = useMemo<RadioGroupContextValue>(\n () => ({\n disabled,\n direction,\n }),\n [disabled, direction],\n )\n\n return (\n <RadioGroupContext value={store}>\n <RadixRadioGroup.Root\n className={clsx(s.RadioGroup, className)}\n data-direction={direction}\n onValueChange={onChange}\n disabled={disabled}\n {...restProps}\n >\n {children}\n </RadixRadioGroup.Root>\n </RadioGroupContext>\n )\n}\n\nexport type RadioGroupItemProps<T extends string> = {\n value: T\n /** Determines if a given radio item is disabled */\n disabled?: boolean\n required?: boolean\n block?: boolean\n className?: string\n /**\n * The orientation of the radio indicator relative to the label.\n *\n * @default \"left\"\n */\n orientation?: \"left\" | \"right\"\n children: React.ReactNode\n}\n\nconst Item = <T extends string>({\n value,\n disabled: itemDisabled = false,\n required,\n children,\n className,\n block = false,\n orientation = \"left\",\n ...restProps\n}: RadioGroupItemProps<T>) => {\n const { disabled: groupDisabled } = useRadioGroupContext()\n const disabled = groupDisabled || itemDisabled\n\n const id = useId()\n const itemId = `${value}-${id}`\n\n return (\n // Providing an extra wrapper enables `label` to be inline-flex, avoiding clickable whitespace\n // when radio options are of varied lengths.\n // NOTE: Important that this is `flex` to prevent the `inline-flex` label from extra, unintentional whitespace.\n <div className={clsx(\"flex\", block && \"w-full\")} {...restProps}>\n <label\n htmlFor={itemId}\n className={clsx(s.RadioLabel, className)}\n data-disabled={disabled ? \"\" : undefined}\n data-block={block ? \"\" : undefined}\n data-orientation={orientation}\n onMouseDown={(event) => {\n if (!event.defaultPrevented && event.detail > 1) event.preventDefault()\n }}\n >\n <div className={s.RadioIndicatorWrapper}>\n <RadixRadioGroup.Item\n id={itemId}\n value={value}\n disabled={disabled}\n required={required}\n className={s.RadioItem}\n >\n <RadixRadioGroup.Indicator className={s.RadioIndicator} />\n </RadixRadioGroup.Item>\n </div>\n {children}\n </label>\n </div>\n )\n}\n\nRadioGroup.Item = Item\n"]}
1
+ {"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../../../src/components/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\"\nimport React, { createContext, use, useId, useMemo } from \"react\"\nimport s from \"@plexui/styles/components/RadioGroup/RadioGroup.module.css\"\n\ntype Direction = \"col\" | \"row\"\n\ntype RadioGroupContextValue = {\n disabled: boolean\n direction: Direction\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null)\n\nconst useRadioGroupContext = () => {\n const context = use(RadioGroupContext)\n\n if (!context) {\n throw new Error(\"RadioGroup components must be wrapped in <RadioGroup />\")\n }\n\n return context\n}\n\nexport type RadioGroupProps<T extends string> = {\n \"defaultValue\"?: T\n \"value\"?: T\n \"name\"?: string\n \"onChange\"?: (value: T) => void\n /** Accessible label for the radio options */\n \"aria-label\"?: string\n /** Determines the layout direction of the radio items\n * @default row\n */\n \"direction\"?: Direction\n /** Controls whether the entire radio group is disabled */\n \"disabled\"?: boolean\n /** Class applied to the radio group container */\n \"className\"?: string\n \"children\": React.ReactNode\n \"required\"?: boolean\n}\n\nexport const RadioGroup = <T extends string>({\n onChange,\n children,\n className,\n direction = \"row\",\n disabled = false,\n ...restProps\n}: RadioGroupProps<T>) => {\n const store = useMemo<RadioGroupContextValue>(\n () => ({\n disabled,\n direction,\n }),\n [disabled, direction],\n )\n\n return (\n <RadioGroupContext value={store}>\n <RadixRadioGroup.Root\n className={clsx(s.RadioGroup, className)}\n data-direction={direction}\n onValueChange={onChange}\n disabled={disabled}\n {...restProps}\n >\n {children}\n </RadixRadioGroup.Root>\n </RadioGroupContext>\n )\n}\n\nexport type RadioGroupItemProps<T extends string> = {\n value: T\n /** Determines if a given radio item is disabled */\n disabled?: boolean\n required?: boolean\n block?: boolean\n className?: string\n /**\n * The orientation of the radio indicator relative to the label.\n *\n * @default \"left\"\n */\n orientation?: \"left\" | \"right\"\n children: React.ReactNode\n /** Optional second line below the option's label. Linked via `aria-describedby`. */\n description?: React.ReactNode\n}\n\nconst Item = <T extends string>({\n value,\n disabled: itemDisabled = false,\n required,\n children,\n description,\n className,\n block = false,\n orientation = \"left\",\n ...restProps\n}: RadioGroupItemProps<T>) => {\n const { disabled: groupDisabled } = useRadioGroupContext()\n const disabled = groupDisabled || itemDisabled\n\n const id = useId()\n const itemId = `${value}-${id}`\n const descriptionId = description ? `${itemId}-description` : undefined\n\n const label = (\n <label\n htmlFor={itemId}\n className={clsx(s.RadioLabel, className)}\n data-disabled={disabled ? \"\" : undefined}\n data-block={block ? \"\" : undefined}\n data-orientation={orientation}\n onMouseDown={(event) => {\n if (!event.defaultPrevented && event.detail > 1) event.preventDefault()\n }}\n >\n <div className={s.RadioIndicatorWrapper}>\n <RadixRadioGroup.Item\n id={itemId}\n value={value}\n disabled={disabled}\n required={required}\n className={s.RadioItem}\n aria-describedby={descriptionId}\n >\n <RadixRadioGroup.Indicator className={s.RadioIndicator} />\n </RadixRadioGroup.Item>\n </div>\n {children}\n </label>\n )\n\n return (\n // Providing an extra wrapper enables `label` to be inline-flex, avoiding clickable whitespace\n // when radio options are of varied lengths.\n // NOTE: Important that this is `flex` to prevent the `inline-flex` label from extra, unintentional whitespace.\n <div className={clsx(\"flex\", block && \"w-full\")} {...restProps}>\n {description ? (\n // The description stays outside the label, so it describes the radio instead of naming it\n <div className={s.RadioItemGroup} data-block={block ? \"\" : undefined} data-orientation={orientation}>\n {label}\n <span id={descriptionId} className={s.RadioDescription} data-disabled={disabled ? \"\" : undefined}>\n {description}\n </span>\n </div>\n ) : (\n label\n )}\n </div>\n )\n}\n\nRadioGroup.Item = Item\n"]}
@@ -1,2 +1,2 @@
1
- export { RadioGroup } from "./RadioGroup";
1
+ export { RadioGroup } from "./RadioGroup.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- export { Tabs as SegmentedControl } from "../Tabs";
1
+ export { Tabs as SegmentedControl } from "../Tabs/index.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -3,15 +3,15 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
3
3
  import clsx from "clsx";
4
4
  import { Popover } from "radix-ui";
5
5
  import React, { createContext, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, } from "react";
6
- import { useEscCloseStack } from "../../hooks/useEscCloseStack";
7
- import { useLatestValue } from "../../hooks/useLatestValue";
8
- import { preventDefaultHandler, toCssVariables, waitForAnimationFrame } from "../../lib/helpers";
9
- import { Check, Info, Search } from "../Icon";
10
- import { Input } from "../Input";
11
- import { SelectControl } from "../SelectControl";
12
- import { Tooltip } from "../Tooltip";
13
- import { TransitionGroup } from "../Transition";
14
- import s from "./Select.module.css";
6
+ import { useEscCloseStack } from "../../hooks/useEscCloseStack.js";
7
+ import { useLatestValue } from "../../hooks/useLatestValue.js";
8
+ import { preventDefaultHandler, toCssVariables, waitForAnimationFrame } from "../../lib/helpers.js";
9
+ import { Check, Info, Search } from "../Icon/index.js";
10
+ import { Input } from "../Input/index.js";
11
+ import { SelectControl } from "../SelectControl/index.js";
12
+ import { Tooltip } from "../Tooltip/index.js";
13
+ import { TransitionGroup } from "../Transition/index.js";
14
+ import s from "@plexui/styles/components/Select/Select.module.css";
15
15
  const SelectContext = createContext(null);
16
16
  const useSelectContext = () => {
17
17
  const context = use(SelectContext);
@@ -34,7 +34,7 @@ const DefaultMultiTriggerView = ({ values, selectedAll, }) => {
34
34
  return _jsx(_Fragment, { children: displayValue });
35
35
  };
36
36
  export const Select = (props) => {
37
- const { id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, required, value, name, multiple, variant = "outline", size = "md", dropdownIconType = "dropdown", loading = false, clearable = false, disabled = false, placeholder = "Select...", loadingPlaceholder = "Loading...", pill = false, listWidth, options, actions: propActions = [], side = "bottom", avoidCollisions = true, onChange, optionClassName, OptionView = DefaultOptionView, TriggerStartIcon, triggerClassName, opticallyAlign, TriggerView: TriggerViewFromProps, searchPlaceholder = "", searchAriaLabel = "Search options", searchPredicate = defaultSearchPredicate, searchEmptyMessage = "No results found.", listMaxWidth = "auto", trigger, checkPosition = 'start', } = props;
37
+ const { id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, required, value, name, multiple, variant = "outline", size = "md", dropdownIconType = "dropdown", loading = false, clearable = false, disabled = false, placeholder = "Select...", loadingPlaceholder = "Loading...", pill = false, listWidth, options, actions: propActions = [], side = "bottom", avoidCollisions = true, onChange, optionClassName, OptionView = DefaultOptionView, TriggerStartIcon, triggerClassName, opticallyAlign, TriggerView: TriggerViewFromProps, searchPlaceholder = "", searchAriaLabel = "Search options", searchSize, searchPredicate = defaultSearchPredicate, searchEmptyMessage = "No results found.", listMaxWidth = "auto", trigger, checkPosition = 'start', } = props;
38
38
  // Block default is dynamic, based on `variant`
39
39
  const block = props.block ?? variant !== "ghost";
40
40
  // Align default is dynamic, based on `block`
@@ -136,6 +136,7 @@ export const Select = (props) => {
136
136
  listMaxWidth,
137
137
  searchPlaceholder,
138
138
  searchAriaLabel,
139
+ searchSize,
139
140
  searchEmptyMessage,
140
141
  TriggerStartIcon,
141
142
  triggerClassName,
@@ -180,6 +181,7 @@ export const Select = (props) => {
180
181
  listMaxWidth,
181
182
  searchPlaceholder,
182
183
  searchAriaLabel,
184
+ searchSize,
183
185
  searchEmptyMessage,
184
186
  TriggerStartIcon,
185
187
  triggerClassName,
@@ -236,7 +238,7 @@ export const SelectTrigger = (props) => {
236
238
  const key = evt.key;
237
239
  // If not a command, check for typeahead
238
240
  // NOTE: Typeahead not supported in multi-select
239
- if (!multiple && isValidTypeaheadChar(key)) {
241
+ if (!multiple && isTypeaheadKey(evt)) {
240
242
  const currentTypeaheadValue = typeahead(key);
241
243
  // Stop other listeners from reacting
242
244
  evt.stopPropagation();
@@ -253,39 +255,47 @@ export const SelectTrigger = (props) => {
253
255
  // Ensure open state is closed
254
256
  onOpenChange?.(false);
255
257
  };
256
- return (_jsxs(SelectControl, { id: triggerId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy ? `${ariaLabelledBy} ${triggerId}-value` : undefined, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, className: triggerClassName, selected: !isPlaceholder, variant: variant, pill: pill, block: block, size: size, disabled: disabled, loading: loading, StartIcon: TriggerStartIcon, opticallyAlign: opticallyAlign, dropdownIconType: dropdownIconType, onClearClick: clearable ? handleClearClick : undefined, onInteract: onOpenChange, onKeyDown: handleKeyDown, ...restProps, children: [ariaLabelledBy ? (_jsx("span", { id: `${triggerId}-value`, children: multiple ? _jsx(TriggerView, { ...multipleTriggerViewProps }) : _jsx(TriggerView, { ...selectedItem }) })) : multiple ? _jsx(TriggerView, { ...multipleTriggerViewProps }) : _jsx(TriggerView, { ...selectedItem }), (name || id) && (_jsx("input", { id: id, name: name, value: firstValue, tabIndex: -1, onFocus: () => {
257
- document.getElementById(triggerId)?.focus();
258
- },
259
- // keep react from complaining - don't make this readOnly because that
260
- // prevents the value from being required
261
- onChange: () => { }, required: required, className: "sr-only w-full h-0 left-0 bottom-0 pointer-events-none", "aria-hidden": "true" }))] }));
258
+ return (_jsxs(SelectControl, { id: triggerId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy ? `${ariaLabelledBy} ${triggerId}-value` : undefined, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, className: triggerClassName, selected: !isPlaceholder, variant: variant, pill: pill, block: block, size: size, disabled: disabled, loading: loading, StartIcon: TriggerStartIcon, opticallyAlign: opticallyAlign, dropdownIconType: dropdownIconType, onClearClick: clearable ? handleClearClick : undefined, onInteract: onOpenChange, onKeyDown: handleKeyDown, ...restProps, children: [ariaLabelledBy ? (_jsx("span", { id: `${triggerId}-value`, children: multiple ? _jsx(TriggerView, { ...multipleTriggerViewProps }) : _jsx(TriggerView, { ...selectedItem }) })) : multiple ? _jsx(TriggerView, { ...multipleTriggerViewProps }) : _jsx(TriggerView, { ...selectedItem }), (name || id) &&
259
+ // One input per selected value, so a form submits every value of a
260
+ // multi-select; an empty one keeps `id` and `required` working
261
+ (multiple && value.length ? value : [firstValue ?? ""]).map((formValue, index) => (_jsx("input", { id: index === 0 ? id : undefined, name: name, value: formValue,
262
+ // A disabled select is neither validated nor submitted
263
+ disabled: disabled, tabIndex: -1, onFocus: () => {
264
+ document.getElementById(triggerId)?.focus();
265
+ },
266
+ // keep react from complaining - don't make this readOnly because that
267
+ // prevents the value from being required
268
+ onChange: () => { }, required: required, className: s.FormInput, "aria-hidden": "true" }, index)))] }));
262
269
  };
263
270
  // ============================================================
264
271
  // Custom Select
265
272
  // ============================================================
266
273
  const CustomSelect = () => {
267
- const { triggerId, loading, side, align, alignOffset, avoidCollisions, listWidth, listMinWidth, listMaxWidth, trigger, } = useSelectContext();
274
+ const { loading, side, align, alignOffset, avoidCollisions, listWidth, listMinWidth, listMaxWidth, trigger, } = useSelectContext();
268
275
  const [open, setOpen] = useState(false);
269
276
  const selectContentRef = useRef(null);
277
+ // The trigger element, the default one or a custom `trigger` (which has no `triggerId`)
278
+ const popoverTriggerRef = useRef(null);
270
279
  const handleOpenChange = (maybeNextState) => {
271
280
  // Toggle the current state when called without a specific state
272
281
  const nextState = maybeNextState === undefined ? !open : maybeNextState;
273
282
  setOpen(nextState);
274
283
  // When we're closing, manage focus back to trigger manually
275
284
  if (!nextState) {
285
+ // Read this now: with animations disabled the menu unmounts before the
286
+ // timeout below runs, so selectContentRef is already null by then
287
+ const focusWasInMenu = !!selectContentRef.current?.contains(document.activeElement);
276
288
  // Wait until the next tick to determine if another element has become focused
277
289
  setTimeout(() => {
278
- // This should never happen because TransitionGroup should keep the select content in the DOM long
279
- // enough for this callback to run. However, in the event that the ref is null, not focusing is safer.
280
- if (!selectContentRef.current) {
281
- return;
282
- }
283
290
  const activeElement = document.activeElement;
284
- // Don't restore focus to the trigger if focus has moved outside of the select menu
285
- if (activeElement && !selectContentRef.current.contains(activeElement)) {
286
- return;
291
+ const menu = selectContentRef.current;
292
+ const focusInMenu = !!menu && !!activeElement && menu.contains(activeElement);
293
+ // Focus dropped with the closing menu lands on <body>: it was lost, not moved
294
+ const focusLost = !activeElement || activeElement === document.body;
295
+ // Focus that moved to another element outside the menu stays there
296
+ if (focusInMenu || (focusWasInMenu && focusLost)) {
297
+ popoverTriggerRef.current?.focus();
287
298
  }
288
- document.getElementById(triggerId)?.focus();
289
299
  });
290
300
  }
291
301
  };
@@ -298,7 +308,7 @@ const CustomSelect = () => {
298
308
  return;
299
309
  }
300
310
  handleOpenChange(nextState);
301
- }, modal: false, children: [_jsx(Popover.Trigger, { asChild: true, children: trigger ? trigger({ open, onToggle: () => setOpen((current) => !current) }) : _jsx(SelectTrigger, { onOpenChange: handleOpenChange }) }), _jsx(Popover.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(Popover.Content, { ref: selectContentRef, forceMount: true, className: s.MenuList, side: side, sideOffset: 5, align: align, alignOffset: alignOffset, avoidCollisions: avoidCollisions, collisionPadding: { bottom: 30, top: 30 },
311
+ }, modal: false, children: [_jsx(Popover.Trigger, { asChild: true, ref: popoverTriggerRef, children: trigger ? trigger({ open, onToggle: () => setOpen((current) => !current) }) : _jsx(SelectTrigger, { onOpenChange: handleOpenChange }) }), _jsx(Popover.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(Popover.Content, { ref: selectContentRef, forceMount: true, className: s.MenuList, side: side, sideOffset: 5, align: align, alignOffset: alignOffset, avoidCollisions: avoidCollisions, collisionPadding: { bottom: 30, top: 30 },
302
312
  // Prevent Radix auto focus so we can handle our own from within <CustomSelectMenu />
303
313
  onOpenAutoFocus: preventDefaultHandler,
304
314
  // Radix waits until the animation completes before directing focus, which is janky.
@@ -440,7 +450,7 @@ const CustomSelectMenu = ({ onOpenChange }) => {
440
450
  break;
441
451
  }
442
452
  // If not a command, check for typeahead
443
- if (isValidTypeaheadChar(key)) {
453
+ if (isTypeaheadKey(evt)) {
444
454
  // Skip typeahead logic when we're focused in the search input
445
455
  if (isFocusedInSearch) {
446
456
  return;
@@ -486,8 +496,9 @@ const CustomSelectMenu = ({ onOpenChange }) => {
486
496
  // Scroll the selected item into view, and its bottom edge.
487
497
  currentOption?.scrollIntoView({ block: "center" });
488
498
  });
489
- // Send initial focus to the menu container or search input, to capture key events
490
- const autoFocusTarget = searchInputRef.current || menuRef.current;
499
+ // Send initial focus to the search input, or the list without one (the
500
+ // menu container when there are no options), to capture key events
501
+ const autoFocusTarget = searchInputRef.current || listRef.current || menuRef.current;
491
502
  autoFocusTarget?.focus({ preventScroll: true });
492
503
  // Required for <StrictMode>, because we need to unset this token
493
504
  // when the hooks are re-run. It's an imperative effect that we need to manage.
@@ -516,15 +527,33 @@ const CustomSelectMenu = ({ onOpenChange }) => {
516
527
  if (maybeFirstOption)
517
528
  setHighlightedValue(maybeFirstOption.value);
518
529
  }, [filteredOptions]);
519
- return (_jsx(CustomSelectMenuContext, { value: store, children: _jsxs("div", { id: listId, className: s.MenuInner, onKeyDown: handleKeyDown, ref: menuRef, tabIndex: 0, children: [searchable && _jsx(CustomSelectSearch, { value: searchTerm, onChange: setSearchTerm }), _jsx(CustomSelectList, { filteredOptions: filteredOptions }), _jsx(CustomSelectActions, {})] }) }));
530
+ // The focused element (the search input, or the list without one) points
531
+ // assistive tech at the highlighted option, when that option is rendered
532
+ useLayoutEffect(() => {
533
+ const target = searchInputRef.current || listRef.current;
534
+ if (!target || !menuRef.current) {
535
+ return;
536
+ }
537
+ const highlightedOption = highlightedValue ? findOptionByValue(highlightedValue, menuRef.current) : null;
538
+ if (highlightedOption?.id) {
539
+ target.setAttribute("aria-activedescendant", highlightedOption.id);
540
+ }
541
+ else {
542
+ target.removeAttribute("aria-activedescendant");
543
+ }
544
+ }, [highlightedValue, filteredOptions]);
545
+ return (_jsx(CustomSelectMenuContext, { value: store, children: _jsxs("div", { className: s.MenuInner, onKeyDown: handleKeyDown, ref: menuRef,
546
+ // Without search, the list takes focus (and the tab stop); the container
547
+ // stays focusable so a click on it keeps the keys here
548
+ tabIndex: !searchable && filteredOptions.length ? -1 : 0, children: [searchable && (_jsx(CustomSelectSearch, { value: searchTerm, onChange: setSearchTerm, hasResults: !!filteredOptions.length })), _jsx(CustomSelectList, { filteredOptions: filteredOptions }), _jsx(CustomSelectActions, {})] }) }));
520
549
  };
521
- const CustomSelectSearch = ({ value, onChange }) => {
522
- const { searchPlaceholder, searchAriaLabel } = useSelectContext();
550
+ const CustomSelectSearch = ({ value, onChange, hasResults }) => {
551
+ const { searchPlaceholder, searchAriaLabel, searchSize } = useSelectContext();
523
552
  const { listId, searchInputRef } = useCustomSelectMenuContext();
524
553
  const handleChange = (evt) => {
525
554
  onChange(evt.target.value);
526
555
  };
527
- return (_jsx("div", { className: s.Search, children: _jsx(Input, { startAdornment: _jsx(Search, { width: 16, height: 16, className: "fill-secondary", fill: "var(--color-text-secondary)" }), ref: searchInputRef, value: value, placeholder: searchPlaceholder, "aria-label": searchAriaLabel, onChange: handleChange, autoComplete: "off", autoCorrect: "off", spellCheck: false, "aria-autocomplete": "list", role: "combobox", "aria-controls": listId, "aria-expanded": true }) }));
556
+ return (_jsx("div", { className: s.Search, children: _jsx(Input, { startAdornment: _jsx(Search, { width: 16, height: 16, className: "fill-secondary", fill: "var(--color-text-secondary)" }), ref: searchInputRef, size: searchSize, value: value, placeholder: searchPlaceholder, "aria-label": searchAriaLabel, onChange: handleChange, autoComplete: "off", autoCorrect: "off", spellCheck: false, "aria-autocomplete": "list", role: "combobox", "aria-controls": hasResults ? listId : undefined, "aria-expanded": true }) }));
528
557
  };
529
558
  const isOptionGroup = (mixedOption) => {
530
559
  return "options" in mixedOption;
@@ -534,8 +563,8 @@ const isOptionGroupArray = (arr) => {
534
563
  };
535
564
  const HARD_OPTIONS_LIMIT = 300;
536
565
  const CustomSelectList = ({ filteredOptions, }) => {
537
- const { searchEmptyMessage } = useSelectContext();
538
- const { listRef } = useCustomSelectMenuContext();
566
+ const { searchEmptyMessage, multiple, searchable, triggerId, trigger, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, } = useSelectContext();
567
+ const { listId, listRef } = useCustomSelectMenuContext();
539
568
  if (!filteredOptions.length) {
540
569
  return typeof searchEmptyMessage === "string" ? (_jsx("p", { className: s.SearchEmpty, "data-text-only": true, children: searchEmptyMessage })) : (_jsx("div", { className: s.SearchEmpty, children: searchEmptyMessage }));
541
570
  }
@@ -547,7 +576,9 @@ const CustomSelectList = ({ filteredOptions, }) => {
547
576
  : filteredOptions
548
577
  .slice(0, HARD_OPTIONS_LIMIT)
549
578
  .map((option) => _jsx(CustomSelectOption, { ...option }, option.value));
550
- return (_jsxs("div", { className: s.OptionsList, ref: listRef, children: [options, hasHardLimit && (_jsx(CustomSelectHardLimit, { numHidden: filteredOptions.length - HARD_OPTIONS_LIMIT }))] }));
579
+ return (_jsxs("div", { id: listId, className: s.OptionsList, ref: listRef, role: "listbox", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy ?? (ariaLabel || trigger ? undefined : triggerId), "aria-multiselectable": multiple || undefined,
580
+ // Without search, the list is the focused element
581
+ tabIndex: searchable ? undefined : 0, children: [options, hasHardLimit && (_jsx(CustomSelectHardLimit, { numHidden: filteredOptions.length - HARD_OPTIONS_LIMIT }))] }));
551
582
  };
552
583
  const DEFAULT_OPTIONS_LIMIT = {
553
584
  limit: 100,
@@ -555,6 +586,7 @@ const DEFAULT_OPTIONS_LIMIT = {
555
586
  };
556
587
  const CustomSelectGroup = ({ label, options, optionsLimit = DEFAULT_OPTIONS_LIMIT, }) => {
557
588
  const groupId = useId();
589
+ const headingId = useId();
558
590
  const { searchTerm, setHighlightedValue } = useCustomSelectMenuContext();
559
591
  const [limitExpanded, setLimitExpanded] = useState(false);
560
592
  const hasExpandableLimit = optionsLimit.limit < options.length && !searchTerm && !limitExpanded;
@@ -573,15 +605,18 @@ const CustomSelectGroup = ({ label, options, optionsLimit = DEFAULT_OPTIONS_LIMI
573
605
  setHighlightedValue(options[optionsLimit.limit].value);
574
606
  };
575
607
  return (
576
- // NOTE: Important for crawling that groups are flat
577
- _jsxs(_Fragment, { children: [_jsx("div", { className: s.OptionGroupHeading, children: label }), maybeLimitedOptions.map((limitedOptions) => (_jsx(CustomSelectOption, { ...limitedOptions }, limitedOptions.value))), hasExpandableLimit && (_jsx(CustomSelectExpandableLimit, { value: `group-limit-${groupId}`, label: optionsLimit.label, onPointerUp: handleLimitExpanded })), hasHardLimit && _jsx(CustomSelectHardLimit, { numHidden: options.length - HARD_OPTIONS_LIMIT })] }));
608
+ // A group named by its heading. NOTE: The arrow keys walk every option in
609
+ // document order (findNextOption), so they cross from group to group.
610
+ _jsxs("div", { role: "group", "aria-labelledby": headingId, className: s.OptionGroup, children: [_jsx("div", { id: headingId, className: s.OptionGroupHeading, children: label }), maybeLimitedOptions.map((limitedOptions) => (_jsx(CustomSelectOption, { ...limitedOptions }, limitedOptions.value))), hasExpandableLimit && (_jsx(CustomSelectExpandableLimit, { value: `group-limit-${groupId}`, label: optionsLimit.label, onPointerUp: handleLimitExpanded })), hasHardLimit && _jsx(CustomSelectHardLimit, { numHidden: options.length - HARD_OPTIONS_LIMIT })] }));
578
611
  };
579
612
  const CustomSelectHardLimit = ({ numHidden }) => {
580
613
  const { checkPosition } = useSelectContext();
581
614
  return (_jsxs("div", { className: s.OptionHardLimitHeading, children: [checkPosition === 'start' && _jsx("div", { className: s.OptionIndicatorSlot }), `…and ${numHidden.toLocaleString()} more options. Use search to refine results further.`] }));
582
615
  };
583
616
  const CustomSelectExpandableLimit = ({ value, label, onPointerUp, }) => {
617
+ const { checkPosition } = useSelectContext();
584
618
  const { highlightedValue, setHighlightedValue } = useCustomSelectMenuContext();
619
+ const optionId = useId();
585
620
  const isHighlighted = value === highlightedValue;
586
621
  const handlePointerMove = () => {
587
622
  if (isHighlighted) {
@@ -599,13 +634,17 @@ const CustomSelectExpandableLimit = ({ value, label, onPointerUp, }) => {
599
634
  // This component acts a LOT like an Option, but has enough bespoke behavior
600
635
  // that it cannot literally be one. We copy the important parts of Option for
601
636
  // keyboard navigation, UX, etc.
602
- return (_jsx("div", { className: clsx(s.Option, s.OptionsLimit), "data-option-id": value, "data-highlight": isHighlighted ? "" : undefined, role: "option", "aria-selected": isHighlighted, onPointerUp: onPointerUp, onPointerMove: handlePointerMove, onPointerLeave: handlePointerLeave, children: _jsxs("div", { className: clsx(s.PressableInner, s.OptionInner), children: [_jsx("div", { className: s.OptionIndicatorSlot }), label] }) }));
637
+ return (_jsx("div", { id: optionId, className: clsx(s.Option, s.OptionsLimit), "data-option-id": value, "data-highlight": isHighlighted ? "" : undefined,
638
+ // Not selectable: no aria-selected
639
+ role: "option", onPointerUp: onPointerUp, onPointerMove: handlePointerMove, onPointerLeave: handlePointerLeave, children: _jsxs("div", { className: clsx(s.PressableInner, s.OptionInner), children: [checkPosition === 'start' && _jsx("div", { className: s.OptionIndicatorSlot }), label] }) }));
603
640
  };
604
641
  const INTERNAL_DOM_SELECTION_DATA_ATTR = "data-option-id";
605
642
  const CustomSelectOption = (option) => {
606
643
  const { optionClassName, OptionView, value: propsValue, multiple, onSelectRef, checkPosition, } = useSelectContext();
607
644
  const { openingValue, requestCloseRef, highlightedValue, setHighlightedValue } = useCustomSelectMenuContext();
608
645
  const { value, disabled, tooltip } = option;
646
+ // Referenced by the list's aria-activedescendant while highlighted
647
+ const optionId = useId();
609
648
  // NOTE: SingleSelect mode keeps the opening value instead of the live `propsValue`
610
649
  // to avoid selecting the item as the select closes.
611
650
  const isSelected = multiple ? propsValue.includes(value) : value === openingValue;
@@ -635,7 +674,7 @@ const CustomSelectOption = (option) => {
635
674
  return currentHighlightedValue !== value ? currentHighlightedValue : "";
636
675
  });
637
676
  };
638
- return (_jsx("div", { className: clsx(s.Option, optionClassName), "data-highlight": isHighlighted ? "" : undefined, role: "option", "aria-selected": isHighlighted, "data-selected": isSelected ? "" : undefined, [INTERNAL_DOM_SELECTION_DATA_ATTR]: value,
677
+ return (_jsx("div", { id: optionId, className: clsx(s.Option, optionClassName), "data-highlight": isHighlighted ? "" : undefined, role: "option", "aria-selected": isSelected, "data-selected": isSelected ? "" : undefined, [INTERNAL_DOM_SELECTION_DATA_ATTR]: value,
639
678
  // Allow options to behave like a native select, when you can open and select an item in a single click
640
679
  onPointerUp: disabled ? undefined : handlePointerUp,
641
680
  // Pointer move allows us to prevent contention from keyboard presses and a still mouse
@@ -764,32 +803,31 @@ const getOptionsByValues = (options, values) => {
764
803
  return found;
765
804
  };
766
805
  const MAX_DOM_CRAWLS = 40;
767
- const findOptionByValue = (currentValue, container) => container.querySelector(`[data-option-id="${currentValue}"]`);
806
+ const findOptionByValue = (currentValue, container) => container.querySelector(`[data-option-id="${CSS.escape(currentValue)}"]`);
768
807
  const isValidOptionNode = (node) => node.matches("[data-option-id]:not([data-disabled])");
769
- const findNextOption = (currentValue, container) => {
808
+ // Steps from the current option to the nearest enabled one, one option row at a
809
+ // time in document order: across groups (siblings would stop at a group's
810
+ // edge), skipping disabled rows, at most MAX_DOM_CRAWLS rows away
811
+ const findAdjacentOption = (currentValue, container, step) => {
770
812
  const currentOption = findOptionByValue(currentValue, container);
771
- let nextNode = currentOption?.nextElementSibling;
772
- let maxSteps = 0;
773
- while (nextNode && maxSteps < MAX_DOM_CRAWLS) {
774
- if (isValidOptionNode(nextNode)) {
775
- return nextNode;
776
- }
777
- nextNode = nextNode.nextElementSibling;
778
- maxSteps += 1;
813
+ const rows = Array.from(container.querySelectorAll("[data-option-id]"));
814
+ let index = currentOption ? rows.indexOf(currentOption) : -1;
815
+ if (index === -1) {
816
+ return undefined;
779
817
  }
780
- };
781
- const findPreviousOption = (currentValue, container) => {
782
- const currentOption = findOptionByValue(currentValue, container);
783
- let nextNode = currentOption?.previousElementSibling;
784
- let maxSteps = 0;
785
- while (nextNode && maxSteps < MAX_DOM_CRAWLS) {
818
+ for (let maxSteps = 0; maxSteps < MAX_DOM_CRAWLS; maxSteps += 1) {
819
+ index += step;
820
+ const nextNode = rows[index];
821
+ if (!nextNode) {
822
+ return undefined;
823
+ }
786
824
  if (isValidOptionNode(nextNode)) {
787
825
  return nextNode;
788
826
  }
789
- nextNode = nextNode.previousElementSibling;
790
- maxSteps += 1;
791
827
  }
792
828
  };
829
+ const findNextOption = (currentValue, container) => findAdjacentOption(currentValue, container, 1);
830
+ const findPreviousOption = (currentValue, container) => findAdjacentOption(currentValue, container, -1);
793
831
  const createTypeahead = () => {
794
832
  let currentValue = "";
795
833
  let timeoutId;
@@ -814,13 +852,14 @@ const createTypeahead = () => {
814
852
  };
815
853
  };
816
854
  const isValidTypeaheadChar = (char) => /^[a-zA-Z0-9]$/.test(char);
855
+ // A shortcut (Ctrl+C, Cmd+A, Alt+letter) or a key another handler took is not typeahead
856
+ const isTypeaheadKey = (evt) => isValidTypeaheadChar(evt.key) && !evt.ctrlKey && !evt.metaKey && !evt.altKey && !evt.defaultPrevented;
817
857
  const getTypeaheadOption = (options, typeaheadValue, currentHighlightValue) => {
818
858
  // Ensure options actually exist
819
859
  if (!options.length) {
820
860
  return undefined;
821
861
  }
822
862
  let matchBeforeHighlight;
823
- let matchAfterHighlight;
824
863
  // If we' aren't provided a highlighted value, start from the top (e.g., act like it's found)
825
864
  let foundHighlightedValue = !currentHighlightValue;
826
865
  const optionValidAndMatches = ({ disabled, label, value }) => {
@@ -837,9 +876,8 @@ const getTypeaheadOption = (options, typeaheadValue, currentHighlightValue) => {
837
876
  for (const option of opt.options) {
838
877
  if (optionValidAndMatches(option)) {
839
878
  if (foundHighlightedValue) {
840
- matchAfterHighlight = option;
841
- // We're done after we've found an after match
842
- break;
879
+ // We're done after we've found an after match, in any group
880
+ return option;
843
881
  }
844
882
  else {
845
883
  // Keep the first found "before" match
@@ -851,9 +889,8 @@ const getTypeaheadOption = (options, typeaheadValue, currentHighlightValue) => {
851
889
  else {
852
890
  if (optionValidAndMatches(opt)) {
853
891
  if (foundHighlightedValue) {
854
- matchAfterHighlight = opt;
855
892
  // We're done after we've found an after match
856
- break;
893
+ return opt;
857
894
  }
858
895
  else {
859
896
  // Keep the first found "before" match
@@ -862,6 +899,6 @@ const getTypeaheadOption = (options, typeaheadValue, currentHighlightValue) => {
862
899
  }
863
900
  }
864
901
  }
865
- return matchAfterHighlight || matchBeforeHighlight;
902
+ return matchBeforeHighlight;
866
903
  };
867
904
  //# sourceMappingURL=Select.js.map