@react-md/core 6.5.0 → 6.5.2

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 (402) hide show
  1. package/dist/_utils.scss +5 -1
  2. package/dist/autocomplete/AutocompleteChip.js +2 -2
  3. package/dist/autocomplete/AutocompleteChip.js.map +1 -1
  4. package/dist/autocomplete/AutocompleteListboxChildren.js +1 -1
  5. package/dist/autocomplete/AutocompleteListboxChildren.js.map +1 -1
  6. package/dist/autocomplete/useAutocomplete.js +4 -4
  7. package/dist/autocomplete/useAutocomplete.js.map +1 -1
  8. package/dist/autocomplete/utils.js +3 -3
  9. package/dist/autocomplete/utils.js.map +1 -1
  10. package/dist/box/styles.js +2 -2
  11. package/dist/box/styles.js.map +1 -1
  12. package/dist/button/AsyncButton.js +1 -1
  13. package/dist/button/AsyncButton.js.map +1 -1
  14. package/dist/chip/Chip.js +1 -1
  15. package/dist/chip/Chip.js.map +1 -1
  16. package/dist/cssUtils.d.ts +11 -6
  17. package/dist/cssUtils.js.map +1 -1
  18. package/dist/datetime/useTimeField.js +1 -1
  19. package/dist/datetime/useTimeField.js.map +1 -1
  20. package/dist/delegateEvent.js +9 -9
  21. package/dist/delegateEvent.js.map +1 -1
  22. package/dist/draggable/useDraggable.js +4 -4
  23. package/dist/draggable/useDraggable.js.map +1 -1
  24. package/dist/draggable/utils.js +1 -1
  25. package/dist/draggable/utils.js.map +1 -1
  26. package/dist/expansion-panel/ExpansionPanel.js +1 -1
  27. package/dist/expansion-panel/ExpansionPanel.js.map +1 -1
  28. package/dist/expansion-panel/useExpansionPanels.js +1 -1
  29. package/dist/expansion-panel/useExpansionPanels.js.map +1 -1
  30. package/dist/files/FileInput.js +1 -1
  31. package/dist/files/FileInput.js.map +1 -1
  32. package/dist/files/createAcceptFromExtensions.d.ts +5 -0
  33. package/dist/files/createAcceptFromExtensions.js +15 -0
  34. package/dist/files/createAcceptFromExtensions.js.map +1 -0
  35. package/dist/files/useFileUpload.js +45 -41
  36. package/dist/files/useFileUpload.js.map +1 -1
  37. package/dist/files/utils.js +14 -10
  38. package/dist/files/utils.js.map +1 -1
  39. package/dist/files/validation.js +7 -8
  40. package/dist/files/validation.js.map +1 -1
  41. package/dist/focus/useFocusContainer.js +1 -1
  42. package/dist/focus/useFocusContainer.js.map +1 -1
  43. package/dist/focus/utils.js +12 -7
  44. package/dist/focus/utils.js.map +1 -1
  45. package/dist/form/InputToggleIcon.js +5 -1
  46. package/dist/form/InputToggleIcon.js.map +1 -1
  47. package/dist/form/NativeSelect.js +1 -1
  48. package/dist/form/NativeSelect.js.map +1 -1
  49. package/dist/form/Select.js +5 -5
  50. package/dist/form/Select.js.map +1 -1
  51. package/dist/form/formConfig.js +1 -1
  52. package/dist/form/formConfig.js.map +1 -1
  53. package/dist/form/inputToggleStyles.js +7 -1
  54. package/dist/form/inputToggleStyles.js.map +1 -1
  55. package/dist/form/selectUtils.js +2 -2
  56. package/dist/form/selectUtils.js.map +1 -1
  57. package/dist/form/useCombobox.js +1 -0
  58. package/dist/form/useCombobox.js.map +1 -1
  59. package/dist/form/useFormReset.js +2 -2
  60. package/dist/form/useFormReset.js.map +1 -1
  61. package/dist/form/useNumberField.js +1 -1
  62. package/dist/form/useNumberField.js.map +1 -1
  63. package/dist/form/useResizingTextArea.js +4 -4
  64. package/dist/form/useResizingTextArea.js.map +1 -1
  65. package/dist/form/useSelectCombobox.js +1 -1
  66. package/dist/form/useSelectCombobox.js.map +1 -1
  67. package/dist/form/validation.js +1 -1
  68. package/dist/form/validation.js.map +1 -1
  69. package/dist/hoverMode/useHoverMode.js +8 -8
  70. package/dist/hoverMode/useHoverMode.js.map +1 -1
  71. package/dist/hoverMode/useHoverModeProvider.js +3 -3
  72. package/dist/hoverMode/useHoverModeProvider.js.map +1 -1
  73. package/dist/icon/config.js +3 -3
  74. package/dist/icon/config.js.map +1 -1
  75. package/dist/icon/materialConfig.js +1 -1
  76. package/dist/icon/materialConfig.js.map +1 -1
  77. package/dist/interaction/UserInteractionModeProvider.js +11 -10
  78. package/dist/interaction/UserInteractionModeProvider.js.map +1 -1
  79. package/dist/interaction/utils.js +7 -3
  80. package/dist/interaction/utils.js.map +1 -1
  81. package/dist/layout/useExpandableLayout.js +3 -4
  82. package/dist/layout/useExpandableLayout.js.map +1 -1
  83. package/dist/layout/useMainTabIndex.js +1 -1
  84. package/dist/layout/useMainTabIndex.js.map +1 -1
  85. package/dist/list/ListItem.js +1 -1
  86. package/dist/list/ListItem.js.map +1 -1
  87. package/dist/media-queries/AppSizeProvider.js +1 -1
  88. package/dist/media-queries/AppSizeProvider.js.map +1 -1
  89. package/dist/media-queries/config.js +2 -2
  90. package/dist/media-queries/config.js.map +1 -1
  91. package/dist/media-queries/useMediaQuery.js +3 -3
  92. package/dist/media-queries/useMediaQuery.js.map +1 -1
  93. package/dist/menu/Menu.js +4 -4
  94. package/dist/menu/Menu.js.map +1 -1
  95. package/dist/menu/MenuItemButton.js +1 -1
  96. package/dist/menu/MenuItemButton.js.map +1 -1
  97. package/dist/menu/MenuItemFileInput.js +1 -1
  98. package/dist/menu/MenuItemFileInput.js.map +1 -1
  99. package/dist/menu/MenuWidget.js +2 -2
  100. package/dist/menu/MenuWidget.js.map +1 -1
  101. package/dist/movement/findMatchIndex.js +2 -2
  102. package/dist/movement/findMatchIndex.js.map +1 -1
  103. package/dist/movement/useKeyboardMovementProvider.js +2 -2
  104. package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
  105. package/dist/movement/utils.js +12 -10
  106. package/dist/movement/utils.js.map +1 -1
  107. package/dist/navigation/getTableOfContentsHeadings.js +4 -3
  108. package/dist/navigation/getTableOfContentsHeadings.js.map +1 -1
  109. package/dist/navigation/useActiveHeadingId.js +9 -9
  110. package/dist/navigation/useActiveHeadingId.js.map +1 -1
  111. package/dist/navigation/useTableOfContentsHeadings.js +1 -1
  112. package/dist/navigation/useTableOfContentsHeadings.js.map +1 -1
  113. package/dist/navigation/utils.js +6 -5
  114. package/dist/navigation/utils.js.map +1 -1
  115. package/dist/portal/PortalContainerProvider.js +5 -3
  116. package/dist/portal/PortalContainerProvider.js.map +1 -1
  117. package/dist/positioning/getFixedPosition.js +2 -4
  118. package/dist/positioning/getFixedPosition.js.map +1 -1
  119. package/dist/positioning/useFixedPositioning.js +2 -2
  120. package/dist/positioning/useFixedPositioning.js.map +1 -1
  121. package/dist/positioning/utils.js +3 -3
  122. package/dist/positioning/utils.js.map +1 -1
  123. package/dist/scroll/getScrollbarWidth.js +4 -4
  124. package/dist/scroll/getScrollbarWidth.js.map +1 -1
  125. package/dist/searching/fuzzy.js +3 -2
  126. package/dist/searching/fuzzy.js.map +1 -1
  127. package/dist/searching/toSearchQuery.js +1 -1
  128. package/dist/searching/toSearchQuery.js.map +1 -1
  129. package/dist/searching/utils.js +1 -1
  130. package/dist/searching/utils.js.map +1 -1
  131. package/dist/snackbar/Toast.js +1 -1
  132. package/dist/snackbar/Toast.js.map +1 -1
  133. package/dist/snackbar/ToastContent.js +2 -2
  134. package/dist/snackbar/ToastContent.js.map +1 -1
  135. package/dist/snackbar/ToastManager.d.ts +1 -1
  136. package/dist/snackbar/ToastManager.js +11 -11
  137. package/dist/snackbar/ToastManager.js.map +1 -1
  138. package/dist/spinbutton/useSpinButton.js +1 -1
  139. package/dist/spinbutton/useSpinButton.js.map +1 -1
  140. package/dist/spinbutton/utils/deselectNode.js +1 -1
  141. package/dist/spinbutton/utils/deselectNode.js.map +1 -1
  142. package/dist/spinbutton/utils/resolveInputEvent.js +1 -1
  143. package/dist/spinbutton/utils/resolveInputEvent.js.map +1 -1
  144. package/dist/spinbutton/utils/selectNode.js +1 -1
  145. package/dist/spinbutton/utils/selectNode.js.map +1 -1
  146. package/dist/storage/useStorage.js +8 -3
  147. package/dist/storage/useStorage.js.map +1 -1
  148. package/dist/table/useStickyTableSection.js +1 -1
  149. package/dist/table/useStickyTableSection.js.map +1 -1
  150. package/dist/tabs/TabList.js +2 -2
  151. package/dist/tabs/TabList.js.map +1 -1
  152. package/dist/tabs/useMaxTabPanelHeight.js +4 -3
  153. package/dist/tabs/useMaxTabPanelHeight.js.map +1 -1
  154. package/dist/tabs/useTabList.js +1 -1
  155. package/dist/tabs/useTabList.js.map +1 -1
  156. package/dist/test-utils/jest-globals/match-media.d.ts +1 -1
  157. package/dist/test-utils/jest-globals/match-media.js +1 -1
  158. package/dist/test-utils/jest-globals/match-media.js.map +1 -1
  159. package/dist/test-utils/jest-globals/timers.js +1 -1
  160. package/dist/test-utils/jest-globals/timers.js.map +1 -1
  161. package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js +1 -1
  162. package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js.map +1 -1
  163. package/dist/test-utils/mocks/ResizeObserver.js +2 -2
  164. package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
  165. package/dist/test-utils/polyfills/IntersectionObserver.js +2 -2
  166. package/dist/test-utils/polyfills/IntersectionObserver.js.map +1 -1
  167. package/dist/test-utils/polyfills/ResizeObserver.js +2 -2
  168. package/dist/test-utils/polyfills/ResizeObserver.js.map +1 -1
  169. package/dist/test-utils/polyfills/TextDecoder.js +2 -2
  170. package/dist/test-utils/polyfills/TextDecoder.js.map +1 -1
  171. package/dist/test-utils/polyfills/TextEncoder.js +2 -2
  172. package/dist/test-utils/polyfills/TextEncoder.js.map +1 -1
  173. package/dist/test-utils/polyfills/matchMedia.js +2 -2
  174. package/dist/test-utils/polyfills/matchMedia.js.map +1 -1
  175. package/dist/test-utils/polyfills/offsetParent.js +2 -2
  176. package/dist/test-utils/polyfills/offsetParent.js.map +1 -1
  177. package/dist/test-utils/polyfills/scrollIntoView.js +1 -1
  178. package/dist/test-utils/polyfills/scrollIntoView.js.map +1 -1
  179. package/dist/test-utils/queries/select.js +2 -2
  180. package/dist/test-utils/queries/select.js.map +1 -1
  181. package/dist/test-utils/queries/slider.js +1 -1
  182. package/dist/test-utils/queries/slider.js.map +1 -1
  183. package/dist/test-utils/utils/createFileList.js +2 -0
  184. package/dist/test-utils/utils/createFileList.js.map +1 -1
  185. package/dist/test-utils/utils/createMatchMediaSpy.d.ts +1 -1
  186. package/dist/test-utils/utils/createMatchMediaSpy.js +3 -3
  187. package/dist/test-utils/utils/createMatchMediaSpy.js.map +1 -1
  188. package/dist/test-utils/vitest/match-media.d.ts +1 -1
  189. package/dist/test-utils/vitest/match-media.js +1 -1
  190. package/dist/test-utils/vitest/match-media.js.map +1 -1
  191. package/dist/test-utils/vitest/timers.js +1 -1
  192. package/dist/test-utils/vitest/timers.js.map +1 -1
  193. package/dist/test-utils/vitest/uploadMenuItemFileInput.js +1 -1
  194. package/dist/test-utils/vitest/uploadMenuItemFileInput.js.map +1 -1
  195. package/dist/theme/ThemeProvider.js +2 -2
  196. package/dist/theme/ThemeProvider.js.map +1 -1
  197. package/dist/theme/getDerivedTheme.js +1 -1
  198. package/dist/theme/getDerivedTheme.js.map +1 -1
  199. package/dist/theme/useCSSVariables.js +5 -5
  200. package/dist/theme/useCSSVariables.js.map +1 -1
  201. package/dist/theme/useColorSchemeMetaTag.js +2 -2
  202. package/dist/theme/useColorSchemeMetaTag.js.map +1 -1
  203. package/dist/theme/useInlineCSSVariables.js +4 -3
  204. package/dist/theme/useInlineCSSVariables.js.map +1 -1
  205. package/dist/theme/utils.js +8 -8
  206. package/dist/theme/utils.js.map +1 -1
  207. package/dist/tooltip/useTooltip.js +7 -7
  208. package/dist/tooltip/useTooltip.js.map +1 -1
  209. package/dist/tooltip/useTooltipPosition.js +1 -1
  210. package/dist/tooltip/useTooltipPosition.js.map +1 -1
  211. package/dist/transition/useCarousel.js +2 -2
  212. package/dist/transition/useCarousel.js.map +1 -1
  213. package/dist/transition/useCollapseTransition.js +1 -1
  214. package/dist/transition/useCollapseTransition.js.map +1 -1
  215. package/dist/transition/useSkeletonPlaceholder.js +4 -4
  216. package/dist/transition/useSkeletonPlaceholder.js.map +1 -1
  217. package/dist/transition/useTransition.js +2 -2
  218. package/dist/transition/useTransition.js.map +1 -1
  219. package/dist/transition/utils.js +5 -5
  220. package/dist/transition/utils.js.map +1 -1
  221. package/dist/tree/TreeItem.js +1 -1
  222. package/dist/tree/TreeItem.js.map +1 -1
  223. package/dist/tree/useTreeItems.js +7 -5
  224. package/dist/tree/useTreeItems.js.map +1 -1
  225. package/dist/tree/useTreeMovement.js +1 -1
  226. package/dist/tree/useTreeMovement.js.map +1 -1
  227. package/dist/tree/utils.js +6 -9
  228. package/dist/tree/utils.js.map +1 -1
  229. package/dist/typography/HighlightText.js +2 -1
  230. package/dist/typography/HighlightText.js.map +1 -1
  231. package/dist/typography/SrOnly.js +7 -1
  232. package/dist/typography/SrOnly.js.map +1 -1
  233. package/dist/useDebouncedFunction.js +4 -4
  234. package/dist/useDebouncedFunction.js.map +1 -1
  235. package/dist/useDropzone.js +9 -9
  236. package/dist/useDropzone.js.map +1 -1
  237. package/dist/useEnsuredState.js +5 -5
  238. package/dist/useEnsuredState.js.map +1 -1
  239. package/dist/useIntersectionObserver.js +3 -3
  240. package/dist/useIntersectionObserver.js.map +1 -1
  241. package/dist/useIsomorphicLayoutEffect.js +1 -1
  242. package/dist/useIsomorphicLayoutEffect.js.map +1 -1
  243. package/dist/useOrientation.js +1 -1
  244. package/dist/useOrientation.js.map +1 -1
  245. package/dist/useReadonlySet.js +1 -1
  246. package/dist/useReadonlySet.js.map +1 -1
  247. package/dist/useResizeListener.js +2 -2
  248. package/dist/useResizeListener.js.map +1 -1
  249. package/dist/useResizeObserver.js +3 -4
  250. package/dist/useResizeObserver.js.map +1 -1
  251. package/dist/useThrottledFunction.js +3 -3
  252. package/dist/useThrottledFunction.js.map +1 -1
  253. package/dist/useWindowSize.js +1 -1
  254. package/dist/useWindowSize.js.map +1 -1
  255. package/dist/utils/alphaNumericSort.js +3 -1
  256. package/dist/utils/alphaNumericSort.js.map +1 -1
  257. package/dist/utils/bem.js +9 -12
  258. package/dist/utils/bem.js.map +1 -1
  259. package/dist/utils/getNumberOfDigits.js +1 -0
  260. package/dist/utils/getNumberOfDigits.js.map +1 -1
  261. package/dist/utils/getRangeDefaultValue.js +1 -1
  262. package/dist/utils/getRangeDefaultValue.js.map +1 -1
  263. package/dist/utils/nearest.js +2 -2
  264. package/dist/utils/nearest.js.map +1 -1
  265. package/dist/utils/parseCssLengthUnit.js +3 -3
  266. package/dist/utils/parseCssLengthUnit.js.map +1 -1
  267. package/dist/utils/trigonometry.js +1 -1
  268. package/dist/utils/trigonometry.js.map +1 -1
  269. package/package.json +3 -1
  270. package/src/autocomplete/AutocompleteChip.tsx +2 -2
  271. package/src/autocomplete/AutocompleteListboxChildren.tsx +1 -1
  272. package/src/autocomplete/useAutocomplete.ts +4 -4
  273. package/src/autocomplete/utils.ts +3 -3
  274. package/src/box/styles.ts +2 -2
  275. package/src/button/AsyncButton.tsx +1 -3
  276. package/src/chip/Chip.tsx +1 -2
  277. package/src/cssUtils.ts +12 -6
  278. package/src/datetime/useTimeField.ts +1 -1
  279. package/src/delegateEvent.ts +9 -9
  280. package/src/draggable/useDraggable.ts +4 -4
  281. package/src/draggable/utils.ts +1 -1
  282. package/src/expansion-panel/ExpansionPanel.tsx +1 -1
  283. package/src/expansion-panel/useExpansionPanels.ts +1 -1
  284. package/src/files/FileInput.tsx +1 -1
  285. package/src/files/createAcceptFromExtensions.ts +18 -0
  286. package/src/files/useFileUpload.ts +36 -37
  287. package/src/files/utils.ts +15 -11
  288. package/src/files/validation.ts +7 -9
  289. package/src/focus/useFocusContainer.ts +1 -1
  290. package/src/focus/utils.ts +11 -6
  291. package/src/form/InputToggleIcon.tsx +5 -5
  292. package/src/form/NativeSelect.tsx +1 -1
  293. package/src/form/Select.tsx +5 -5
  294. package/src/form/formConfig.ts +1 -1
  295. package/src/form/inputToggleStyles.ts +9 -4
  296. package/src/form/selectUtils.ts +2 -2
  297. package/src/form/useCombobox.ts +1 -0
  298. package/src/form/useFormReset.ts +2 -2
  299. package/src/form/useNumberField.ts +1 -1
  300. package/src/form/useResizingTextArea.ts +5 -5
  301. package/src/form/useSelectCombobox.ts +1 -4
  302. package/src/form/validation.ts +1 -1
  303. package/src/hoverMode/useHoverMode.ts +9 -9
  304. package/src/hoverMode/useHoverModeProvider.ts +4 -4
  305. package/src/icon/config.tsx +3 -3
  306. package/src/icon/materialConfig.ts +1 -1
  307. package/src/interaction/UserInteractionModeProvider.tsx +11 -10
  308. package/src/interaction/utils.ts +3 -3
  309. package/src/layout/useExpandableLayout.ts +3 -4
  310. package/src/layout/useMainTabIndex.ts +1 -1
  311. package/src/list/ListItem.tsx +1 -1
  312. package/src/media-queries/AppSizeProvider.tsx +1 -1
  313. package/src/media-queries/config.ts +2 -2
  314. package/src/media-queries/useMediaQuery.ts +3 -3
  315. package/src/menu/Menu.tsx +4 -4
  316. package/src/menu/MenuItemButton.tsx +1 -1
  317. package/src/menu/MenuItemFileInput.tsx +1 -1
  318. package/src/menu/MenuWidget.tsx +6 -4
  319. package/src/movement/findMatchIndex.ts +2 -2
  320. package/src/movement/useKeyboardMovementProvider.ts +2 -2
  321. package/src/movement/utils.ts +15 -14
  322. package/src/navigation/getTableOfContentsHeadings.ts +4 -3
  323. package/src/navigation/useActiveHeadingId.ts +8 -8
  324. package/src/navigation/useTableOfContentsHeadings.ts +1 -1
  325. package/src/navigation/utils.ts +6 -5
  326. package/src/portal/PortalContainerProvider.tsx +5 -3
  327. package/src/positioning/getFixedPosition.ts +9 -6
  328. package/src/positioning/useFixedPositioning.ts +2 -2
  329. package/src/positioning/utils.ts +3 -3
  330. package/src/scroll/getScrollbarWidth.ts +4 -4
  331. package/src/searching/fuzzy.ts +7 -3
  332. package/src/searching/toSearchQuery.ts +1 -1
  333. package/src/searching/utils.ts +1 -1
  334. package/src/snackbar/Toast.tsx +1 -1
  335. package/src/snackbar/ToastContent.tsx +2 -2
  336. package/src/snackbar/ToastManager.ts +11 -12
  337. package/src/spinbutton/useSpinButton.ts +1 -1
  338. package/src/spinbutton/utils/deselectNode.ts +1 -1
  339. package/src/spinbutton/utils/resolveInputEvent.ts +1 -1
  340. package/src/spinbutton/utils/selectNode.ts +1 -1
  341. package/src/storage/useStorage.ts +7 -2
  342. package/src/table/useStickyTableSection.tsx +1 -1
  343. package/src/tabs/TabList.tsx +2 -2
  344. package/src/tabs/useMaxTabPanelHeight.ts +6 -3
  345. package/src/tabs/useTabList.ts +2 -2
  346. package/src/test-utils/jest-globals/match-media.ts +5 -2
  347. package/src/test-utils/jest-globals/timers.ts +1 -1
  348. package/src/test-utils/jest-globals/uploadMenuItemFileInput.ts +1 -1
  349. package/src/test-utils/mocks/ResizeObserver.ts +2 -2
  350. package/src/test-utils/polyfills/IntersectionObserver.ts +2 -2
  351. package/src/test-utils/polyfills/ResizeObserver.ts +2 -2
  352. package/src/test-utils/polyfills/TextDecoder.ts +2 -2
  353. package/src/test-utils/polyfills/TextEncoder.ts +2 -2
  354. package/src/test-utils/polyfills/matchMedia.ts +5 -2
  355. package/src/test-utils/polyfills/offsetParent.ts +2 -2
  356. package/src/test-utils/polyfills/scrollIntoView.ts +1 -1
  357. package/src/test-utils/queries/select.ts +2 -2
  358. package/src/test-utils/queries/slider.ts +1 -1
  359. package/src/test-utils/utils/createFileList.ts +2 -0
  360. package/src/test-utils/utils/createMatchMediaSpy.ts +4 -4
  361. package/src/test-utils/vitest/match-media.ts +2 -2
  362. package/src/test-utils/vitest/timers.ts +1 -1
  363. package/src/test-utils/vitest/uploadMenuItemFileInput.ts +1 -1
  364. package/src/theme/ThemeProvider.tsx +2 -2
  365. package/src/theme/getDerivedTheme.ts +1 -1
  366. package/src/theme/useCSSVariables.ts +5 -5
  367. package/src/theme/useColorSchemeMetaTag.ts +2 -2
  368. package/src/theme/useInlineCSSVariables.ts +6 -7
  369. package/src/theme/utils.ts +8 -8
  370. package/src/tooltip/useTooltip.ts +7 -7
  371. package/src/tooltip/useTooltipPosition.ts +1 -1
  372. package/src/transition/useCarousel.ts +2 -2
  373. package/src/transition/useCollapseTransition.ts +1 -1
  374. package/src/transition/useSkeletonPlaceholder.ts +4 -4
  375. package/src/transition/useTransition.ts +2 -2
  376. package/src/transition/utils.ts +5 -5
  377. package/src/tree/TreeItem.tsx +1 -1
  378. package/src/tree/useTreeItems.ts +5 -5
  379. package/src/tree/useTreeMovement.ts +1 -1
  380. package/src/tree/utils.ts +9 -9
  381. package/src/typography/HighlightText.tsx +4 -3
  382. package/src/typography/SrOnly.tsx +9 -2
  383. package/src/useDebouncedFunction.ts +5 -5
  384. package/src/useDropzone.ts +10 -10
  385. package/src/useEnsuredState.ts +5 -5
  386. package/src/useIntersectionObserver.ts +3 -3
  387. package/src/useIsomorphicLayoutEffect.ts +3 -3
  388. package/src/useOrientation.ts +1 -1
  389. package/src/useReadonlySet.ts +3 -1
  390. package/src/useResizeListener.ts +2 -2
  391. package/src/useResizeObserver.ts +3 -4
  392. package/src/useThrottledFunction.ts +4 -4
  393. package/src/useWindowSize.ts +1 -1
  394. package/src/utils/alphaNumericSort.ts +1 -1
  395. package/src/utils/bem.ts +15 -16
  396. package/src/utils/getNumberOfDigits.ts +1 -0
  397. package/src/utils/getRangeDefaultValue.ts +1 -1
  398. package/src/utils/nearest.ts +5 -2
  399. package/src/utils/parseCssLengthUnit.ts +5 -4
  400. package/src/utils/trigonometry.ts +1 -1
  401. package/dist/form/defaultGetSelectedOptionChildren.d.ts +0 -1
  402. package/dist/form/getSelectedOptionChildren.d.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n type FocusElementWithinType,\n focusElementWithin,\n getFocusableElements,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/**\n * @since 6.0.0\n * @deprecated Use `TransitionCallbacks` instead.\n */\nexport type FocusContainerTransitionCallbacks = TransitionCallbacks;\n\n/**\n * @since 6.0.0\n * @since 6.3.2 Fixed by extending `TransitionCallbacks` after the\n * `onEnteredOnce` and `onExitedOnce` support was added to CSS transitions.\n */\nexport interface FocusContainerTransitionOptions<\n E extends HTMLElement,\n> extends TransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>, FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import { Button } from \"@react-md/core/button/Button\"\n * import { useFocusContainer } from \"@react-md/core/focus/useFocusContainer\"\n * import { useScaleTransition } from \"@react-md/core/transition/useScaleTransition\"\n * import { useToggle } from \"@react-md/core/useToggle\"\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n ...getTransitionCallbacks({\n onEnter,\n onEnterOnce: () => {\n const instance = ref.current;\n if (\n instance &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement ||\n !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n },\n onEntering,\n onEntered,\n onExitOnce: () => {\n if (isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n window.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n },\n onExit,\n onExiting,\n onExited,\n disableTransition,\n }),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","getTransitionCallbacks","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEnter","onEntering","onEntered","onExit","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","transitionOptions","onEnterOnce","instance","contains","focus","onExitOnce","window","requestAnimationFrame","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AAEA,SAIEA,SAAS,EACTC,MAAM,QACD,QAAQ;AAEf,SAASC,sBAAsB,QAAQ,0CAA0C;AAEjF,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAEEC,kBAAkB,EAClBC,oBAAoB,QACf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AA0FA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,OAAO,EACPC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,QAAQ,EACRC,YAAYX,IAAI,EAChBY,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBd,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACa,KAAKC,YAAY,GAAGnB,cAAcM;IACzC,MAAMc,YAAYtB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEc,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACf;KAAS;IAEb,OAAO;QACLD,SAASY;QACTO,mBAAmB;YACjBnB,SAASa;YACT,GAAGpB,uBAAuB;gBACxBS;gBACAkB,aAAa;oBACX,MAAMC,WAAWT,IAAIM,OAAO;oBAC5B,IACEG,YACA,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IACtB,CAACK,SAASC,QAAQ,CAACP,SAASC,aAAa,CAAA,GAC3C;wBACAK,SAASE,KAAK;oBAChB;gBACF;gBACApB;gBACAC;gBACAoB,YAAY;oBACV,IAAIb,oBAAoB,YAAY;wBAClC;oBACF;oBAEA,2EAA2E;oBAC3E,iCAAiC;oBACjCc,OAAOC,qBAAqB,CAAC;wBAC3BZ,UAAUI,OAAO,EAAEK;oBACrB;gBACF;gBACAlB;gBACAC;gBACAC;gBACAG;YACF,EAAE;QACJ;QACAiB,eAAe;YACbnB,WAAUoB,KAAK;gBACbpB,UAAUoB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdnB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEoB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWtC,qBAAqBqC,eAAexB;gBACrD,MAAM0B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpB1C,mBAAmB;wBACjB2C;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n type FocusElementWithinType,\n focusElementWithin,\n getFocusableElements,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/**\n * @since 6.0.0\n * @deprecated Use `TransitionCallbacks` instead.\n */\nexport type FocusContainerTransitionCallbacks = TransitionCallbacks;\n\n/**\n * @since 6.0.0\n * @since 6.3.2 Fixed by extending `TransitionCallbacks` after the\n * `onEnteredOnce` and `onExitedOnce` support was added to CSS transitions.\n */\nexport interface FocusContainerTransitionOptions<\n E extends HTMLElement,\n> extends TransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>, FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import { Button } from \"@react-md/core/button/Button\"\n * import { useFocusContainer } from \"@react-md/core/focus/useFocusContainer\"\n * import { useScaleTransition } from \"@react-md/core/transition/useScaleTransition\"\n * import { useToggle } from \"@react-md/core/useToggle\"\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n ...getTransitionCallbacks({\n onEnter,\n onEnterOnce: () => {\n const instance = ref.current;\n if (\n instance &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement ||\n !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n },\n onEntering,\n onEntered,\n onExitOnce: () => {\n if (isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n globalThis.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n },\n onExit,\n onExiting,\n onExited,\n disableTransition,\n }),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","getTransitionCallbacks","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEnter","onEntering","onEntered","onExit","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","transitionOptions","onEnterOnce","instance","contains","focus","onExitOnce","globalThis","requestAnimationFrame","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AAEA,SAIEA,SAAS,EACTC,MAAM,QACD,QAAQ;AAEf,SAASC,sBAAsB,QAAQ,0CAA0C;AAEjF,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAEEC,kBAAkB,EAClBC,oBAAoB,QACf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AA0FA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,OAAO,EACPC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,QAAQ,EACRC,YAAYX,IAAI,EAChBY,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBd,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACa,KAAKC,YAAY,GAAGnB,cAAcM;IACzC,MAAMc,YAAYtB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEc,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACf;KAAS;IAEb,OAAO;QACLD,SAASY;QACTO,mBAAmB;YACjBnB,SAASa;YACT,GAAGpB,uBAAuB;gBACxBS;gBACAkB,aAAa;oBACX,MAAMC,WAAWT,IAAIM,OAAO;oBAC5B,IACEG,YACA,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IACtB,CAACK,SAASC,QAAQ,CAACP,SAASC,aAAa,CAAA,GAC3C;wBACAK,SAASE,KAAK;oBAChB;gBACF;gBACApB;gBACAC;gBACAoB,YAAY;oBACV,IAAIb,oBAAoB,YAAY;wBAClC;oBACF;oBAEA,2EAA2E;oBAC3E,iCAAiC;oBACjCc,WAAWC,qBAAqB,CAAC;wBAC/BZ,UAAUI,OAAO,EAAEK;oBACrB;gBACF;gBACAlB;gBACAC;gBACAC;gBACAG;YACF,EAAE;QACJ;QACAiB,eAAe;YACbnB,WAAUoB,KAAK;gBACbpB,UAAUoB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdnB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEoB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWtC,qBAAqBqC,eAAexB;gBACrD,MAAM0B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpB1C,mBAAmB;wBACjB2C;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
@@ -30,7 +30,8 @@ const queries = [
30
30
  * @since 6.0.0 This was updated to remove ALL elements that have a
31
31
  * `tabindex="-1"` applied instead of only elements that had a manual tab index
32
32
  * applied.
33
- */ export const TAB_FOCUSABLE = queries.reduce((fullQuery, query)=>{
33
+ */ // eslint-disable-next-line unicorn/no-array-reduce
34
+ export const TAB_FOCUSABLE = queries.reduce((fullQuery, query)=>{
34
35
  const prefix = `${fullQuery}${fullQuery ? "," : ""}`;
35
36
  const notProgrammaticQuery = `${query}:not([tabindex="-1"])`;
36
37
  return `${prefix}${notProgrammaticQuery}`;
@@ -81,12 +82,16 @@ export function focusElementWithin(options) {
81
82
  return;
82
83
  }
83
84
  let element = null;
84
- if (type === "first") {
85
- [element] = elements;
86
- } else if (type === "last") {
87
- element = elements[elements.length - 1];
88
- } else if (type === "query") {
89
- element = document.querySelector(query);
85
+ switch(type){
86
+ case "first":
87
+ [element] = elements;
88
+ break;
89
+ case "last":
90
+ element = elements.at(-1) ?? null;
91
+ break;
92
+ case "query":
93
+ element = document.querySelector(query);
94
+ break;
90
95
  }
91
96
  if (!element && isFocusable(container)) {
92
97
  element = container;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/focus/utils.ts"],"sourcesContent":["const queries = [\n 'input:not([type=\"hidden\"]):not([disabled])',\n \"button:not([disabled])\",\n \"textarea:not([disabled])\",\n \"select:not([disabled])\",\n \"a[href]\",\n \"area[href]\",\n \"[tabindex]\",\n] as const;\n\n/**\n * A query selector to find elements that are programmatically focusable.\n *\n * Example:\n *\n * ```ts\n * const focusableElements = document.querySelectorAll(PROGRAMMATICALLY_FOCUSABLE);\n * // do something with elements\n * ```\n */\nexport const PROGRAMMATICALLY_FOCUSABLE = queries.join(\",\");\n\n/**\n * A query selector to find elements that are focusable only with tab and shift+tab.\n *\n * Example:\n *\n * ```ts\n * const focusableElements = document.querySelectorAll(TAB_FOCUSABLE);\n * // do something with elements\n * ```\n *\n * @since 6.0.0 This was updated to remove ALL elements that have a\n * `tabindex=\"-1\"` applied instead of only elements that had a manual tab index\n * applied.\n */\nexport const TAB_FOCUSABLE = queries.reduce((fullQuery, query) => {\n const prefix = `${fullQuery}${fullQuery ? \",\" : \"\"}`;\n const notProgrammaticQuery = `${query}:not([tabindex=\"-1\"])`;\n\n return `${prefix}${notProgrammaticQuery}`;\n}, \"\");\n\n/**\n * A simple util that will find all the tab focusable elements within a\n * container element. The container should normally be a specific HTMLElement,\n * but it can also be the entire document if you want to find **all** focusable\n * elements within your page.\n *\n * @since 6.0.0 This function will be used for all keyboard focus behavior\n * instead of trying to use refs. I did some performance testing in Firefox and\n * Chrome and the `querySelectorAll` takes 4ms with 5000 elements for my use\n * cases. There is more of a performance issue around rendering all 5000\n * elements and since this is only used for specific keydown events, this is\n * good enough for me.\n *\n * @param container - The container element/document to find focusable elements\n * within.\n * @param programmatic - Boolean if programmatically focusable elements should be\n * included instead of only tab focusable.\n * @returns A list of HTMLElements that are focusable within the container.\n */\nexport function getFocusableElements(\n container: HTMLElement | Document,\n programmatic = false\n): readonly HTMLElement[] {\n // spread operator is faster than Array.from\n return [\n ...container.querySelectorAll<HTMLElement>(\n programmatic ? PROGRAMMATICALLY_FOCUSABLE : TAB_FOCUSABLE\n ),\n ];\n}\n\n/**\n * Attempts to find the first focusable element within a container.\n *\n * @since 6.0.0\n * @param container - The container element/document to find focusable elements\n * within.\n * @param programmatic - Boolean if programmatically focusable elements should be\n * included instead of only tab focusable.\n * @returns A list of HTMLElements that are focusable within the container.\n */\nexport function getFocusableElement(\n container: HTMLElement | Document,\n programmatic = false\n): HTMLElement | null {\n return container.querySelector<HTMLElement>(\n programmatic ? PROGRAMMATICALLY_FOCUSABLE : TAB_FOCUSABLE\n );\n}\n\n/**\n * An element can be tab focused if it is:\n * - an anchor or area with an `href`\n * - a non-disabled `input` element that is not `type=\"hidden\"`\n * - a non-disabled `button`, `textarea`, or `select` element\n * - an element with a `tabIndex >= 0`\n *\n * An element can be noted as \"programmatically focusable only\" has the above\n * rules, but the `tabIndex` will be set to `-1`.\n *\n * @since 2.8.0\n */\nexport type ElementFocusType = \"tab\" | \"programmatic\";\n\nexport function isFocusable(\n element: HTMLElement | Document | Window,\n type: ElementFocusType = \"programmatic\"\n): element is HTMLElement {\n const selector = type === \"tab\" ? TAB_FOCUSABLE : PROGRAMMATICALLY_FOCUSABLE;\n\n return \"matches\" in element && element.matches(selector);\n}\n\nexport type FocusElementWithinType =\n | \"first\"\n | \"last\"\n | \"query\"\n | \"self\"\n | \"none\";\n\nexport interface FocusElementWithinOptions {\n type: FocusElementWithinType;\n query?: string;\n elements: readonly HTMLElement[];\n container: HTMLElement | Document;\n}\n\nexport function focusElementWithin(options: FocusElementWithinOptions): void {\n const { type, query = \"\", container, elements } = options;\n if (type === \"none\") {\n return;\n }\n\n let element: HTMLElement | null = null;\n if (type === \"first\") {\n [element] = elements;\n } else if (type === \"last\") {\n element = elements[elements.length - 1];\n } else if (type === \"query\") {\n element = document.querySelector<HTMLElement>(query);\n }\n\n if (!element && isFocusable(container)) {\n element = container;\n }\n\n // TODO: Why did I add preventScroll?\n element?.focus();\n}\n"],"names":["queries","PROGRAMMATICALLY_FOCUSABLE","join","TAB_FOCUSABLE","reduce","fullQuery","query","prefix","notProgrammaticQuery","getFocusableElements","container","programmatic","querySelectorAll","getFocusableElement","querySelector","isFocusable","element","type","selector","matches","focusElementWithin","options","elements","length","document","focus"],"mappings":"AAAA,MAAMA,UAAU;IACd;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED;;;;;;;;;CASC,GACD,OAAO,MAAMC,6BAA6BD,QAAQE,IAAI,CAAC,KAAK;AAE5D;;;;;;;;;;;;;CAaC,GACD,OAAO,MAAMC,gBAAgBH,QAAQI,MAAM,CAAC,CAACC,WAAWC;IACtD,MAAMC,SAAS,GAAGF,YAAYA,YAAY,MAAM,IAAI;IACpD,MAAMG,uBAAuB,GAAGF,MAAM,qBAAqB,CAAC;IAE5D,OAAO,GAAGC,SAASC,sBAAsB;AAC3C,GAAG,IAAI;AAEP;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,qBACdC,SAAiC,EACjCC,eAAe,KAAK;IAEpB,4CAA4C;IAC5C,OAAO;WACFD,UAAUE,gBAAgB,CAC3BD,eAAeV,6BAA6BE;KAE/C;AACH;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASU,oBACdH,SAAiC,EACjCC,eAAe,KAAK;IAEpB,OAAOD,UAAUI,aAAa,CAC5BH,eAAeV,6BAA6BE;AAEhD;AAgBA,OAAO,SAASY,YACdC,OAAwC,EACxCC,OAAyB,cAAc;IAEvC,MAAMC,WAAWD,SAAS,QAAQd,gBAAgBF;IAElD,OAAO,aAAae,WAAWA,QAAQG,OAAO,CAACD;AACjD;AAgBA,OAAO,SAASE,mBAAmBC,OAAkC;IACnE,MAAM,EAAEJ,IAAI,EAAEX,QAAQ,EAAE,EAAEI,SAAS,EAAEY,QAAQ,EAAE,GAAGD;IAClD,IAAIJ,SAAS,QAAQ;QACnB;IACF;IAEA,IAAID,UAA8B;IAClC,IAAIC,SAAS,SAAS;QACpB,CAACD,QAAQ,GAAGM;IACd,OAAO,IAAIL,SAAS,QAAQ;QAC1BD,UAAUM,QAAQ,CAACA,SAASC,MAAM,GAAG,EAAE;IACzC,OAAO,IAAIN,SAAS,SAAS;QAC3BD,UAAUQ,SAASV,aAAa,CAAcR;IAChD;IAEA,IAAI,CAACU,WAAWD,YAAYL,YAAY;QACtCM,UAAUN;IACZ;IAEA,qCAAqC;IACrCM,SAASS;AACX"}
1
+ {"version":3,"sources":["../../src/focus/utils.ts"],"sourcesContent":["const queries = [\n 'input:not([type=\"hidden\"]):not([disabled])',\n \"button:not([disabled])\",\n \"textarea:not([disabled])\",\n \"select:not([disabled])\",\n \"a[href]\",\n \"area[href]\",\n \"[tabindex]\",\n] as const;\n\n/**\n * A query selector to find elements that are programmatically focusable.\n *\n * Example:\n *\n * ```ts\n * const focusableElements = document.querySelectorAll(PROGRAMMATICALLY_FOCUSABLE);\n * // do something with elements\n * ```\n */\nexport const PROGRAMMATICALLY_FOCUSABLE = queries.join(\",\");\n\n/**\n * A query selector to find elements that are focusable only with tab and shift+tab.\n *\n * Example:\n *\n * ```ts\n * const focusableElements = document.querySelectorAll(TAB_FOCUSABLE);\n * // do something with elements\n * ```\n *\n * @since 6.0.0 This was updated to remove ALL elements that have a\n * `tabindex=\"-1\"` applied instead of only elements that had a manual tab index\n * applied.\n */\n// eslint-disable-next-line unicorn/no-array-reduce\nexport const TAB_FOCUSABLE = queries.reduce((fullQuery, query) => {\n const prefix = `${fullQuery}${fullQuery ? \",\" : \"\"}`;\n const notProgrammaticQuery = `${query}:not([tabindex=\"-1\"])`;\n\n return `${prefix}${notProgrammaticQuery}`;\n}, \"\");\n\n/**\n * A simple util that will find all the tab focusable elements within a\n * container element. The container should normally be a specific HTMLElement,\n * but it can also be the entire document if you want to find **all** focusable\n * elements within your page.\n *\n * @since 6.0.0 This function will be used for all keyboard focus behavior\n * instead of trying to use refs. I did some performance testing in Firefox and\n * Chrome and the `querySelectorAll` takes 4ms with 5000 elements for my use\n * cases. There is more of a performance issue around rendering all 5000\n * elements and since this is only used for specific keydown events, this is\n * good enough for me.\n *\n * @param container - The container element/document to find focusable elements\n * within.\n * @param programmatic - Boolean if programmatically focusable elements should be\n * included instead of only tab focusable.\n * @returns A list of HTMLElements that are focusable within the container.\n */\nexport function getFocusableElements(\n container: HTMLElement | Document,\n programmatic = false\n): readonly HTMLElement[] {\n // spread operator is faster than Array.from\n return [\n ...container.querySelectorAll<HTMLElement>(\n programmatic ? PROGRAMMATICALLY_FOCUSABLE : TAB_FOCUSABLE\n ),\n ];\n}\n\n/**\n * Attempts to find the first focusable element within a container.\n *\n * @since 6.0.0\n * @param container - The container element/document to find focusable elements\n * within.\n * @param programmatic - Boolean if programmatically focusable elements should be\n * included instead of only tab focusable.\n * @returns A list of HTMLElements that are focusable within the container.\n */\nexport function getFocusableElement(\n container: HTMLElement | Document,\n programmatic = false\n): HTMLElement | null {\n return container.querySelector<HTMLElement>(\n programmatic ? PROGRAMMATICALLY_FOCUSABLE : TAB_FOCUSABLE\n );\n}\n\n/**\n * An element can be tab focused if it is:\n * - an anchor or area with an `href`\n * - a non-disabled `input` element that is not `type=\"hidden\"`\n * - a non-disabled `button`, `textarea`, or `select` element\n * - an element with a `tabIndex >= 0`\n *\n * An element can be noted as \"programmatically focusable only\" has the above\n * rules, but the `tabIndex` will be set to `-1`.\n *\n * @since 2.8.0\n */\nexport type ElementFocusType = \"tab\" | \"programmatic\";\n\nexport function isFocusable(\n element: HTMLElement | Document | Window,\n type: ElementFocusType = \"programmatic\"\n): element is HTMLElement {\n const selector = type === \"tab\" ? TAB_FOCUSABLE : PROGRAMMATICALLY_FOCUSABLE;\n\n return \"matches\" in element && element.matches(selector);\n}\n\nexport type FocusElementWithinType =\n | \"first\"\n | \"last\"\n | \"query\"\n | \"self\"\n | \"none\";\n\nexport interface FocusElementWithinOptions {\n type: FocusElementWithinType;\n query?: string;\n elements: readonly HTMLElement[];\n container: HTMLElement | Document;\n}\n\nexport function focusElementWithin(options: FocusElementWithinOptions): void {\n const { type, query = \"\", container, elements } = options;\n if (type === \"none\") {\n return;\n }\n\n let element: HTMLElement | null = null;\n switch (type) {\n case \"first\":\n [element] = elements;\n break;\n case \"last\":\n element = elements.at(-1) ?? null;\n break;\n case \"query\":\n element = document.querySelector<HTMLElement>(query);\n break;\n }\n\n if (!element && isFocusable(container)) {\n element = container;\n }\n\n // TODO: Why did I add preventScroll?\n element?.focus();\n}\n"],"names":["queries","PROGRAMMATICALLY_FOCUSABLE","join","TAB_FOCUSABLE","reduce","fullQuery","query","prefix","notProgrammaticQuery","getFocusableElements","container","programmatic","querySelectorAll","getFocusableElement","querySelector","isFocusable","element","type","selector","matches","focusElementWithin","options","elements","at","document","focus"],"mappings":"AAAA,MAAMA,UAAU;IACd;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED;;;;;;;;;CASC,GACD,OAAO,MAAMC,6BAA6BD,QAAQE,IAAI,CAAC,KAAK;AAE5D;;;;;;;;;;;;;CAaC,GACD,mDAAmD;AACnD,OAAO,MAAMC,gBAAgBH,QAAQI,MAAM,CAAC,CAACC,WAAWC;IACtD,MAAMC,SAAS,GAAGF,YAAYA,YAAY,MAAM,IAAI;IACpD,MAAMG,uBAAuB,GAAGF,MAAM,qBAAqB,CAAC;IAE5D,OAAO,GAAGC,SAASC,sBAAsB;AAC3C,GAAG,IAAI;AAEP;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,qBACdC,SAAiC,EACjCC,eAAe,KAAK;IAEpB,4CAA4C;IAC5C,OAAO;WACFD,UAAUE,gBAAgB,CAC3BD,eAAeV,6BAA6BE;KAE/C;AACH;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASU,oBACdH,SAAiC,EACjCC,eAAe,KAAK;IAEpB,OAAOD,UAAUI,aAAa,CAC5BH,eAAeV,6BAA6BE;AAEhD;AAgBA,OAAO,SAASY,YACdC,OAAwC,EACxCC,OAAyB,cAAc;IAEvC,MAAMC,WAAWD,SAAS,QAAQd,gBAAgBF;IAElD,OAAO,aAAae,WAAWA,QAAQG,OAAO,CAACD;AACjD;AAgBA,OAAO,SAASE,mBAAmBC,OAAkC;IACnE,MAAM,EAAEJ,IAAI,EAAEX,QAAQ,EAAE,EAAEI,SAAS,EAAEY,QAAQ,EAAE,GAAGD;IAClD,IAAIJ,SAAS,QAAQ;QACnB;IACF;IAEA,IAAID,UAA8B;IAClC,OAAQC;QACN,KAAK;YACH,CAACD,QAAQ,GAAGM;YACZ;QACF,KAAK;YACHN,UAAUM,SAASC,EAAE,CAAC,CAAC,MAAM;YAC7B;QACF,KAAK;YACHP,UAAUQ,SAASV,aAAa,CAAcR;YAC9C;IACJ;IAEA,IAAI,CAACU,WAAWD,YAAYL,YAAY;QACtCM,UAAUN;IACZ;IAEA,qCAAqC;IACrCM,SAASS;AACX"}
@@ -19,7 +19,11 @@ import { inputToggle } from "./inputToggleStyles.js";
19
19
  const uncontrolled = typeof checked !== "boolean";
20
20
  if (!uncontrolled || !FORM_CONFIG.uncontrolledToggles) {
21
21
  active = !!checked && !error;
22
- icon = checked ? indeterminate ? indeterminateIcon : checkedIcon : uncheckedIcon;
22
+ if (checked) {
23
+ icon = indeterminate ? indeterminateIcon : checkedIcon;
24
+ } else {
25
+ icon = uncheckedIcon;
26
+ }
23
27
  } else {
24
28
  icon = /*#__PURE__*/ _jsxs(_Fragment, {
25
29
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/InputToggleIcon.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport { type HTMLAttributes, type ReactNode, forwardRef } from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { FORM_CONFIG } from \"./formConfig.js\";\nimport { type InputToggleSize, inputToggle } from \"./inputToggleStyles.js\";\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Removed the `circle` and `overlay` props since they are no\n * longer needed. Added the `icon`, `disableEm`, `checkedIcon` and\n * `indeterminateIcon` props.\n * @internal\n */\nexport interface InputToggleIconProps extends HTMLAttributes<HTMLSpanElement> {\n type: \"checkbox\" | \"radio\";\n /**\n * Note: If this is `undefined` and the {@link FORM_CONFIG.uncontrolledToggles} is `false`,\n * the icon state won't work.\n */\n checked?: boolean;\n\n /**\n * The icon to display while {@link checked} is `false`.\n */\n icon?: ReactNode;\n\n /**\n * The icon to display while {@link checked} is `true` and\n * {@link indeterminate} is `false`.\n */\n checkedIcon?: ReactNode;\n\n /**\n * The icon to display while both {@link checked} and {@link indeterminate}\n * are `true`.\n */\n indeterminateIcon?: ReactNode;\n\n /** @defaultValue `\"normal\"` */\n size?: InputToggleSize;\n\n /** @defaultValue `false` */\n error?: boolean;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /** @defaultValue `false` */\n disableEm?: boolean;\n\n /** @defaultValue `false` */\n indeterminate?: boolean;\n}\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Updated to use different icons for each checked state instead\n * of a css overlay hack.\n * @internal\n */\nexport const InputToggleIcon = forwardRef<\n HTMLSpanElement,\n InputToggleIconProps\n>(function InputToggleIcon(props, ref) {\n const {\n type,\n size = \"normal\",\n icon: propIcon,\n error,\n checked,\n children,\n disabled,\n indeterminate,\n className,\n disableEm = false,\n checkedIcon: propCheckedIcon,\n indeterminateIcon: propIndeterminateIcon,\n ...remaining\n } = props;\n const uncheckedIcon = getIcon(type, propIcon);\n const checkedIcon = getIcon(`${type}Checked`, propCheckedIcon);\n const indeterminateIcon = getIcon(\n \"checkboxIndeterminate\",\n propIndeterminateIcon\n );\n\n let icon: ReactNode;\n let active = false;\n const uncontrolled = typeof checked !== \"boolean\";\n if (!uncontrolled || !FORM_CONFIG.uncontrolledToggles) {\n active = !!checked && !error;\n icon = checked\n ? indeterminate\n ? indeterminateIcon\n : checkedIcon\n : uncheckedIcon;\n } else {\n icon = (\n <>\n {uncheckedIcon}\n {indeterminate ? indeterminateIcon : checkedIcon}\n </>\n );\n }\n\n return (\n <span\n {...remaining}\n ref={ref}\n className={cnb(\n inputToggle({\n em: !disableEm,\n size,\n type,\n error,\n active,\n disabled,\n uncontrolled,\n className,\n })\n )}\n >\n {children}\n {icon}\n </span>\n );\n});\n"],"names":["cnb","forwardRef","getIcon","FORM_CONFIG","inputToggle","InputToggleIcon","props","ref","type","size","icon","propIcon","error","checked","children","disabled","indeterminate","className","disableEm","checkedIcon","propCheckedIcon","indeterminateIcon","propIndeterminateIcon","remaining","uncheckedIcon","active","uncontrolled","uncontrolledToggles","span","em"],"mappings":";AAAA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAA8CC,UAAU,QAAQ,QAAQ;AAExE,SAASC,OAAO,QAAQ,oBAAoB;AAC5C,SAASC,WAAW,QAAQ,kBAAkB;AAC9C,SAA+BC,WAAW,QAAQ,yBAAyB;AAkD3E;;;;;CAKC,GACD,OAAO,MAAMC,gCAAkBJ,WAG7B,SAASI,gBAAgBC,KAAK,EAAEC,GAAG;IACnC,MAAM,EACJC,IAAI,EACJC,OAAO,QAAQ,EACfC,MAAMC,QAAQ,EACdC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,SAAS,EACTC,YAAY,KAAK,EACjBC,aAAaC,eAAe,EAC5BC,mBAAmBC,qBAAqB,EACxC,GAAGC,WACJ,GAAGjB;IACJ,MAAMkB,gBAAgBtB,QAAQM,MAAMG;IACpC,MAAMQ,cAAcjB,QAAQ,GAAGM,KAAK,OAAO,CAAC,EAAEY;IAC9C,MAAMC,oBAAoBnB,QACxB,yBACAoB;IAGF,IAAIZ;IACJ,IAAIe,SAAS;IACb,MAAMC,eAAe,OAAOb,YAAY;IACxC,IAAI,CAACa,gBAAgB,CAACvB,YAAYwB,mBAAmB,EAAE;QACrDF,SAAS,CAAC,CAACZ,WAAW,CAACD;QACvBF,OAAOG,UACHG,gBACEK,oBACAF,cACFK;IACN,OAAO;QACLd,qBACE;;gBACGc;gBACAR,gBAAgBK,oBAAoBF;;;IAG3C;IAEA,qBACE,MAACS;QACE,GAAGL,SAAS;QACbhB,KAAKA;QACLU,WAAWjB,IACTI,YAAY;YACVyB,IAAI,CAACX;YACLT;YACAD;YACAI;YACAa;YACAV;YACAW;YACAT;QACF;;YAGDH;YACAJ;;;AAGP,GAAG"}
1
+ {"version":3,"sources":["../../src/form/InputToggleIcon.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport { type HTMLAttributes, type ReactNode, forwardRef } from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { FORM_CONFIG } from \"./formConfig.js\";\nimport { type InputToggleSize, inputToggle } from \"./inputToggleStyles.js\";\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Removed the `circle` and `overlay` props since they are no\n * longer needed. Added the `icon`, `disableEm`, `checkedIcon` and\n * `indeterminateIcon` props.\n * @internal\n */\nexport interface InputToggleIconProps extends HTMLAttributes<HTMLSpanElement> {\n type: \"checkbox\" | \"radio\";\n /**\n * Note: If this is `undefined` and the {@link FORM_CONFIG.uncontrolledToggles} is `false`,\n * the icon state won't work.\n */\n checked?: boolean;\n\n /**\n * The icon to display while {@link checked} is `false`.\n */\n icon?: ReactNode;\n\n /**\n * The icon to display while {@link checked} is `true` and\n * {@link indeterminate} is `false`.\n */\n checkedIcon?: ReactNode;\n\n /**\n * The icon to display while both {@link checked} and {@link indeterminate}\n * are `true`.\n */\n indeterminateIcon?: ReactNode;\n\n /** @defaultValue `\"normal\"` */\n size?: InputToggleSize;\n\n /** @defaultValue `false` */\n error?: boolean;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /** @defaultValue `false` */\n disableEm?: boolean;\n\n /** @defaultValue `false` */\n indeterminate?: boolean;\n}\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Updated to use different icons for each checked state instead\n * of a css overlay hack.\n * @internal\n */\nexport const InputToggleIcon = forwardRef<\n HTMLSpanElement,\n InputToggleIconProps\n>(function InputToggleIcon(props, ref) {\n const {\n type,\n size = \"normal\",\n icon: propIcon,\n error,\n checked,\n children,\n disabled,\n indeterminate,\n className,\n disableEm = false,\n checkedIcon: propCheckedIcon,\n indeterminateIcon: propIndeterminateIcon,\n ...remaining\n } = props;\n const uncheckedIcon = getIcon(type, propIcon);\n const checkedIcon = getIcon(`${type}Checked`, propCheckedIcon);\n const indeterminateIcon = getIcon(\n \"checkboxIndeterminate\",\n propIndeterminateIcon\n );\n\n let icon: ReactNode;\n let active = false;\n const uncontrolled = typeof checked !== \"boolean\";\n if (!uncontrolled || !FORM_CONFIG.uncontrolledToggles) {\n active = !!checked && !error;\n if (checked) {\n icon = indeterminate ? indeterminateIcon : checkedIcon;\n } else {\n icon = uncheckedIcon;\n }\n } else {\n icon = (\n <>\n {uncheckedIcon}\n {indeterminate ? indeterminateIcon : checkedIcon}\n </>\n );\n }\n\n return (\n <span\n {...remaining}\n ref={ref}\n className={cnb(\n inputToggle({\n em: !disableEm,\n size,\n type,\n error,\n active,\n disabled,\n uncontrolled,\n className,\n })\n )}\n >\n {children}\n {icon}\n </span>\n );\n});\n"],"names":["cnb","forwardRef","getIcon","FORM_CONFIG","inputToggle","InputToggleIcon","props","ref","type","size","icon","propIcon","error","checked","children","disabled","indeterminate","className","disableEm","checkedIcon","propCheckedIcon","indeterminateIcon","propIndeterminateIcon","remaining","uncheckedIcon","active","uncontrolled","uncontrolledToggles","span","em"],"mappings":";AAAA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAA8CC,UAAU,QAAQ,QAAQ;AAExE,SAASC,OAAO,QAAQ,oBAAoB;AAC5C,SAASC,WAAW,QAAQ,kBAAkB;AAC9C,SAA+BC,WAAW,QAAQ,yBAAyB;AAkD3E;;;;;CAKC,GACD,OAAO,MAAMC,gCAAkBJ,WAG7B,SAASI,gBAAgBC,KAAK,EAAEC,GAAG;IACnC,MAAM,EACJC,IAAI,EACJC,OAAO,QAAQ,EACfC,MAAMC,QAAQ,EACdC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,SAAS,EACTC,YAAY,KAAK,EACjBC,aAAaC,eAAe,EAC5BC,mBAAmBC,qBAAqB,EACxC,GAAGC,WACJ,GAAGjB;IACJ,MAAMkB,gBAAgBtB,QAAQM,MAAMG;IACpC,MAAMQ,cAAcjB,QAAQ,GAAGM,KAAK,OAAO,CAAC,EAAEY;IAC9C,MAAMC,oBAAoBnB,QACxB,yBACAoB;IAGF,IAAIZ;IACJ,IAAIe,SAAS;IACb,MAAMC,eAAe,OAAOb,YAAY;IACxC,IAAI,CAACa,gBAAgB,CAACvB,YAAYwB,mBAAmB,EAAE;QACrDF,SAAS,CAAC,CAACZ,WAAW,CAACD;QACvB,IAAIC,SAAS;YACXH,OAAOM,gBAAgBK,oBAAoBF;QAC7C,OAAO;YACLT,OAAOc;QACT;IACF,OAAO;QACLd,qBACE;;gBACGc;gBACAR,gBAAgBK,oBAAoBF;;;IAG3C;IAEA,qBACE,MAACS;QACE,GAAGL,SAAS;QACbhB,KAAKA;QACLU,WAAWjB,IACTI,YAAY;YACVyB,IAAI,CAACX;YACLT;YACAD;YACAI;YACAa;YACAV;YACAW;YACAT;QACF;;YAGDH;YACAJ;;;AAGP,GAAG"}
@@ -60,7 +60,7 @@ import { nativeSelect, nativeSelectContainer } from "./nativeSelectStyles.js";
60
60
  const icon = getIcon("dropdown", propIcon);
61
61
  const underlined = theme === "underline" || theme === "filled";
62
62
  let rightAddon = propRightAddon;
63
- if (typeof propRightAddon === "undefined" && !multiple) {
63
+ if (propRightAddon === undefined && !multiple) {
64
64
  rightAddon = icon;
65
65
  }
66
66
  return /*#__PURE__*/ _jsx(FormMessageContainer, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/NativeSelect.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type SelectHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { Label } from \"./Label.js\";\nimport { TextFieldContainer } from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { nativeSelect, nativeSelectContainer } from \"./nativeSelectStyles.js\";\nimport {\n type FormFieldOptions,\n type UserAgentAutocompleteProps,\n} from \"./types.js\";\n\n/**\n * @since 6.0.0 Added support for {@link UserAgentAutocompleteProps}\n */\nexport interface NativeSelectProps\n extends\n Omit<SelectHTMLAttributes<HTMLSelectElement>, \"autoComplete\">,\n UserAgentAutocompleteProps,\n FormFieldOptions {\n /**\n * A custom dropdown icon to use instead of the browser's default select\n * dropdown icon.\n *\n * Set this to `null` if the browser's default icon should be used instead.\n *\n * @defaultValue `getIcon(\"dropdown\")`\n */\n icon?: ReactNode;\n\n /**\n * This applies custom inline styles to the `<select>` element since the\n * `style` prop is applied to the container element instead.\n */\n selectStyle?: CSSProperties;\n\n /**\n * This applies custom className to the `<select>` element since the\n * `className` prop is applied to the container element instead.\n */\n selectClassName?: string;\n\n /**\n * This should be a list of `<option>` elements for specific values within the\n * `<select>`.\n *\n * Check out the {@link NativeSelect} for examples around using \"placeholder\"\n * text and requiring a value to be selected.\n */\n children: ReactNode;\n\n /**\n * Optional props to provide to the {@link TextFieldContainer} component.\n * There probably isn't any real use for this prop other than if you need to\n * add a `ref` for some DOM behavior.\n */\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * This component is a wrapper for the native `<select>` field that applies the\n * same theming as `TextField` and `TextArea` components. This component might\n * not be used much since the `Select` offers more styling options.\n *\n * @example Simple Example\n * ```tsx\n * <NativeSelect label=\"Label\">\n * <option value=\"a\">Value 1</option>\n * <option value=\"b\">Value 2</option>\n * <option value=\"c\">Value 3</option>\n * <option value=\"d\">Value 4</option>\n * </NativeSelect>\n * ```\n *\n * @example Required Value Example\n * ```tsx\n * function Example(): ReactElement {\n * // using `defaultValue=\"\"` makes it so the first option selected by default\n * // and considered an \"invalid\" value since it is `disabled`\n * //\n * // a `name` must be set with `required` so that the form validation will\n * // fire if the value is still the empty string when the form is submitted\n * //\n * // the first `<option>` is kind of like placeholder text since it doesn't\n * // have a value and is disabled by default\n *\n * return (\n * <NativeSelect\n * label=\"State\"\n * name=\"state\"\n * required\n * defaultValue=\"\"\n * >\n * <option value=\"\" disabled>Choose a state</option>\n * {states.map(({ name, code }) => (\n * <option key={code} value={code}>{name}</option>\n * ))}\n * </NativeSelect>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/native-select | NativeSelect Demos}\n */\nexport const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(\n function NativeSelect(props, ref) {\n const {\n id: propId,\n style,\n className,\n icon: propIcon,\n label,\n labelProps,\n labelStyle,\n labelClassName,\n selectStyle,\n selectClassName,\n autoCompleteValue,\n autoComplete = autoCompleteValue,\n name = autoCompleteValue,\n dense,\n error,\n active,\n inline,\n leftAddon,\n rightAddon: propRightAddon,\n leftAddonProps,\n rightAddonProps,\n disableLeftAddonStyles,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n messageProps,\n messageContainerProps,\n containerProps,\n children,\n ...remaining\n } = props;\n const { disabled, readOnly, multiple } = props;\n const id = useEnsuredId(propId, \"select\");\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n const icon = getIcon(\"dropdown\", propIcon);\n const underlined = theme === \"underline\" || theme === \"filled\";\n\n let rightAddon = propRightAddon;\n if (typeof propRightAddon === \"undefined\" && !multiple) {\n rightAddon = icon;\n }\n\n return (\n <FormMessageContainer\n inline={inline}\n {...messageContainerProps}\n messageProps={\n messageProps && {\n error,\n theme,\n ...messageProps,\n }\n }\n >\n <TextFieldContainer\n {...containerProps}\n style={style}\n className={nativeSelectContainer({\n label: !!label,\n multiple,\n underlined,\n className,\n })}\n theme={theme}\n label={!!label}\n error={error}\n dense={dense}\n inline={inline}\n active={active}\n readOnly={readOnly}\n disabled={disabled}\n leftAddon={leftAddon}\n leftAddonProps={leftAddonProps}\n rightAddon={rightAddon}\n rightAddonProps={rightAddonProps}\n underlineDirection={underlineDirection}\n disableLeftAddonStyles={disableLeftAddonStyles}\n disableRightAddonStyles={disableRightAddonStyles}\n >\n <select\n {...remaining}\n id={id}\n ref={ref}\n autoComplete={autoComplete}\n name={name}\n disabled={disabled}\n style={selectStyle}\n className={nativeSelect({\n icon: !!icon,\n className: selectClassName,\n })}\n >\n {children}\n </select>\n {label && (\n <Label\n {...labelProps}\n htmlFor={id}\n style={labelProps?.style ?? labelStyle}\n className={labelProps?.className ?? labelClassName}\n floating\n dense={dense}\n error={error}\n active={active}\n disabled={disabled}\n >\n {label}\n </Label>\n )}\n </TextFieldContainer>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["forwardRef","getIcon","useEnsuredId","FormMessageContainer","Label","TextFieldContainer","getFormConfig","nativeSelect","nativeSelectContainer","NativeSelect","props","ref","id","propId","style","className","icon","propIcon","label","labelProps","labelStyle","labelClassName","selectStyle","selectClassName","autoCompleteValue","autoComplete","name","dense","error","active","inline","leftAddon","rightAddon","propRightAddon","leftAddonProps","rightAddonProps","disableLeftAddonStyles","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","messageProps","messageContainerProps","containerProps","children","remaining","disabled","readOnly","multiple","underlined","select","htmlFor","floating"],"mappings":";AAAA,SAKEA,UAAU,QACL,QAAQ;AAEf,SAASC,OAAO,QAAQ,oBAAoB;AAE5C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AACjE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,YAAY,EAAEC,qBAAqB,QAAQ,0BAA0B;AAqD9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CC,GACD,OAAO,MAAMC,6BAAeT,WAC1B,SAASS,aAAaC,KAAK,EAAEC,GAAG;IAC9B,MAAM,EACJC,IAAIC,MAAM,EACVC,KAAK,EACLC,SAAS,EACTC,MAAMC,QAAQ,EACdC,KAAK,EACLC,UAAU,EACVC,UAAU,EACVC,cAAc,EACdC,WAAW,EACXC,eAAe,EACfC,iBAAiB,EACjBC,eAAeD,iBAAiB,EAChCE,OAAOF,iBAAiB,EACxBG,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,SAAS,EACTC,YAAYC,cAAc,EAC1BC,cAAc,EACdC,eAAe,EACfC,sBAAsB,EACtBC,uBAAuB,EACvBC,OAAOC,SAAS,EAChBC,oBAAoBC,sBAAsB,EAC1CC,YAAY,EACZC,qBAAqB,EACrBC,cAAc,EACdC,QAAQ,EACR,GAAGC,WACJ,GAAGpC;IACJ,MAAM,EAAEqC,QAAQ,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,GAAGvC;IACzC,MAAME,KAAKV,aAAaW,QAAQ;IAChC,MAAMyB,QAAQhC,cAAc,SAASiC;IACrC,MAAMC,qBAAqBlC,cACzB,sBACAmC;IAEF,MAAMzB,OAAOf,QAAQ,YAAYgB;IACjC,MAAMiC,aAAaZ,UAAU,eAAeA,UAAU;IAEtD,IAAIN,aAAaC;IACjB,IAAI,OAAOA,mBAAmB,eAAe,CAACgB,UAAU;QACtDjB,aAAahB;IACf;IAEA,qBACE,KAACb;QACC2B,QAAQA;QACP,GAAGa,qBAAqB;QACzBD,cACEA,gBAAgB;YACdd;YACAU;YACA,GAAGI,YAAY;QACjB;kBAGF,cAAA,MAACrC;YACE,GAAGuC,cAAc;YAClB9B,OAAOA;YACPC,WAAWP,sBAAsB;gBAC/BU,OAAO,CAAC,CAACA;gBACT+B;gBACAC;gBACAnC;YACF;YACAuB,OAAOA;YACPpB,OAAO,CAAC,CAACA;YACTU,OAAOA;YACPD,OAAOA;YACPG,QAAQA;YACRD,QAAQA;YACRmB,UAAUA;YACVD,UAAUA;YACVhB,WAAWA;YACXG,gBAAgBA;YAChBF,YAAYA;YACZG,iBAAiBA;YACjBK,oBAAoBA;YACpBJ,wBAAwBA;YACxBC,yBAAyBA;;8BAEzB,KAACc;oBACE,GAAGL,SAAS;oBACblC,IAAIA;oBACJD,KAAKA;oBACLc,cAAcA;oBACdC,MAAMA;oBACNqB,UAAUA;oBACVjC,OAAOQ;oBACPP,WAAWR,aAAa;wBACtBS,MAAM,CAAC,CAACA;wBACRD,WAAWQ;oBACb;8BAECsB;;gBAEF3B,uBACC,KAACd;oBACE,GAAGe,UAAU;oBACdiC,SAASxC;oBACTE,OAAOK,YAAYL,SAASM;oBAC5BL,WAAWI,YAAYJ,aAAaM;oBACpCgC,QAAQ;oBACR1B,OAAOA;oBACPC,OAAOA;oBACPC,QAAQA;oBACRkB,UAAUA;8BAET7B;;;;;AAMb,GACA"}
1
+ {"version":3,"sources":["../../src/form/NativeSelect.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type SelectHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { Label } from \"./Label.js\";\nimport { TextFieldContainer } from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { nativeSelect, nativeSelectContainer } from \"./nativeSelectStyles.js\";\nimport {\n type FormFieldOptions,\n type UserAgentAutocompleteProps,\n} from \"./types.js\";\n\n/**\n * @since 6.0.0 Added support for {@link UserAgentAutocompleteProps}\n */\nexport interface NativeSelectProps\n extends\n Omit<SelectHTMLAttributes<HTMLSelectElement>, \"autoComplete\">,\n UserAgentAutocompleteProps,\n FormFieldOptions {\n /**\n * A custom dropdown icon to use instead of the browser's default select\n * dropdown icon.\n *\n * Set this to `null` if the browser's default icon should be used instead.\n *\n * @defaultValue `getIcon(\"dropdown\")`\n */\n icon?: ReactNode;\n\n /**\n * This applies custom inline styles to the `<select>` element since the\n * `style` prop is applied to the container element instead.\n */\n selectStyle?: CSSProperties;\n\n /**\n * This applies custom className to the `<select>` element since the\n * `className` prop is applied to the container element instead.\n */\n selectClassName?: string;\n\n /**\n * This should be a list of `<option>` elements for specific values within the\n * `<select>`.\n *\n * Check out the {@link NativeSelect} for examples around using \"placeholder\"\n * text and requiring a value to be selected.\n */\n children: ReactNode;\n\n /**\n * Optional props to provide to the {@link TextFieldContainer} component.\n * There probably isn't any real use for this prop other than if you need to\n * add a `ref` for some DOM behavior.\n */\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * This component is a wrapper for the native `<select>` field that applies the\n * same theming as `TextField` and `TextArea` components. This component might\n * not be used much since the `Select` offers more styling options.\n *\n * @example Simple Example\n * ```tsx\n * <NativeSelect label=\"Label\">\n * <option value=\"a\">Value 1</option>\n * <option value=\"b\">Value 2</option>\n * <option value=\"c\">Value 3</option>\n * <option value=\"d\">Value 4</option>\n * </NativeSelect>\n * ```\n *\n * @example Required Value Example\n * ```tsx\n * function Example(): ReactElement {\n * // using `defaultValue=\"\"` makes it so the first option selected by default\n * // and considered an \"invalid\" value since it is `disabled`\n * //\n * // a `name` must be set with `required` so that the form validation will\n * // fire if the value is still the empty string when the form is submitted\n * //\n * // the first `<option>` is kind of like placeholder text since it doesn't\n * // have a value and is disabled by default\n *\n * return (\n * <NativeSelect\n * label=\"State\"\n * name=\"state\"\n * required\n * defaultValue=\"\"\n * >\n * <option value=\"\" disabled>Choose a state</option>\n * {states.map(({ name, code }) => (\n * <option key={code} value={code}>{name}</option>\n * ))}\n * </NativeSelect>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/native-select | NativeSelect Demos}\n */\nexport const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(\n function NativeSelect(props, ref) {\n const {\n id: propId,\n style,\n className,\n icon: propIcon,\n label,\n labelProps,\n labelStyle,\n labelClassName,\n selectStyle,\n selectClassName,\n autoCompleteValue,\n autoComplete = autoCompleteValue,\n name = autoCompleteValue,\n dense,\n error,\n active,\n inline,\n leftAddon,\n rightAddon: propRightAddon,\n leftAddonProps,\n rightAddonProps,\n disableLeftAddonStyles,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n messageProps,\n messageContainerProps,\n containerProps,\n children,\n ...remaining\n } = props;\n const { disabled, readOnly, multiple } = props;\n const id = useEnsuredId(propId, \"select\");\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n const icon = getIcon(\"dropdown\", propIcon);\n const underlined = theme === \"underline\" || theme === \"filled\";\n\n let rightAddon = propRightAddon;\n if (propRightAddon === undefined && !multiple) {\n rightAddon = icon;\n }\n\n return (\n <FormMessageContainer\n inline={inline}\n {...messageContainerProps}\n messageProps={\n messageProps && {\n error,\n theme,\n ...messageProps,\n }\n }\n >\n <TextFieldContainer\n {...containerProps}\n style={style}\n className={nativeSelectContainer({\n label: !!label,\n multiple,\n underlined,\n className,\n })}\n theme={theme}\n label={!!label}\n error={error}\n dense={dense}\n inline={inline}\n active={active}\n readOnly={readOnly}\n disabled={disabled}\n leftAddon={leftAddon}\n leftAddonProps={leftAddonProps}\n rightAddon={rightAddon}\n rightAddonProps={rightAddonProps}\n underlineDirection={underlineDirection}\n disableLeftAddonStyles={disableLeftAddonStyles}\n disableRightAddonStyles={disableRightAddonStyles}\n >\n <select\n {...remaining}\n id={id}\n ref={ref}\n autoComplete={autoComplete}\n name={name}\n disabled={disabled}\n style={selectStyle}\n className={nativeSelect({\n icon: !!icon,\n className: selectClassName,\n })}\n >\n {children}\n </select>\n {label && (\n <Label\n {...labelProps}\n htmlFor={id}\n style={labelProps?.style ?? labelStyle}\n className={labelProps?.className ?? labelClassName}\n floating\n dense={dense}\n error={error}\n active={active}\n disabled={disabled}\n >\n {label}\n </Label>\n )}\n </TextFieldContainer>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["forwardRef","getIcon","useEnsuredId","FormMessageContainer","Label","TextFieldContainer","getFormConfig","nativeSelect","nativeSelectContainer","NativeSelect","props","ref","id","propId","style","className","icon","propIcon","label","labelProps","labelStyle","labelClassName","selectStyle","selectClassName","autoCompleteValue","autoComplete","name","dense","error","active","inline","leftAddon","rightAddon","propRightAddon","leftAddonProps","rightAddonProps","disableLeftAddonStyles","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","messageProps","messageContainerProps","containerProps","children","remaining","disabled","readOnly","multiple","underlined","undefined","select","htmlFor","floating"],"mappings":";AAAA,SAKEA,UAAU,QACL,QAAQ;AAEf,SAASC,OAAO,QAAQ,oBAAoB;AAE5C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AACjE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,YAAY,EAAEC,qBAAqB,QAAQ,0BAA0B;AAqD9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CC,GACD,OAAO,MAAMC,6BAAeT,WAC1B,SAASS,aAAaC,KAAK,EAAEC,GAAG;IAC9B,MAAM,EACJC,IAAIC,MAAM,EACVC,KAAK,EACLC,SAAS,EACTC,MAAMC,QAAQ,EACdC,KAAK,EACLC,UAAU,EACVC,UAAU,EACVC,cAAc,EACdC,WAAW,EACXC,eAAe,EACfC,iBAAiB,EACjBC,eAAeD,iBAAiB,EAChCE,OAAOF,iBAAiB,EACxBG,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,SAAS,EACTC,YAAYC,cAAc,EAC1BC,cAAc,EACdC,eAAe,EACfC,sBAAsB,EACtBC,uBAAuB,EACvBC,OAAOC,SAAS,EAChBC,oBAAoBC,sBAAsB,EAC1CC,YAAY,EACZC,qBAAqB,EACrBC,cAAc,EACdC,QAAQ,EACR,GAAGC,WACJ,GAAGpC;IACJ,MAAM,EAAEqC,QAAQ,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,GAAGvC;IACzC,MAAME,KAAKV,aAAaW,QAAQ;IAChC,MAAMyB,QAAQhC,cAAc,SAASiC;IACrC,MAAMC,qBAAqBlC,cACzB,sBACAmC;IAEF,MAAMzB,OAAOf,QAAQ,YAAYgB;IACjC,MAAMiC,aAAaZ,UAAU,eAAeA,UAAU;IAEtD,IAAIN,aAAaC;IACjB,IAAIA,mBAAmBkB,aAAa,CAACF,UAAU;QAC7CjB,aAAahB;IACf;IAEA,qBACE,KAACb;QACC2B,QAAQA;QACP,GAAGa,qBAAqB;QACzBD,cACEA,gBAAgB;YACdd;YACAU;YACA,GAAGI,YAAY;QACjB;kBAGF,cAAA,MAACrC;YACE,GAAGuC,cAAc;YAClB9B,OAAOA;YACPC,WAAWP,sBAAsB;gBAC/BU,OAAO,CAAC,CAACA;gBACT+B;gBACAC;gBACAnC;YACF;YACAuB,OAAOA;YACPpB,OAAO,CAAC,CAACA;YACTU,OAAOA;YACPD,OAAOA;YACPG,QAAQA;YACRD,QAAQA;YACRmB,UAAUA;YACVD,UAAUA;YACVhB,WAAWA;YACXG,gBAAgBA;YAChBF,YAAYA;YACZG,iBAAiBA;YACjBK,oBAAoBA;YACpBJ,wBAAwBA;YACxBC,yBAAyBA;;8BAEzB,KAACe;oBACE,GAAGN,SAAS;oBACblC,IAAIA;oBACJD,KAAKA;oBACLc,cAAcA;oBACdC,MAAMA;oBACNqB,UAAUA;oBACVjC,OAAOQ;oBACPP,WAAWR,aAAa;wBACtBS,MAAM,CAAC,CAACA;wBACRD,WAAWQ;oBACb;8BAECsB;;gBAEF3B,uBACC,KAACd;oBACE,GAAGe,UAAU;oBACdkC,SAASzC;oBACTE,OAAOK,YAAYL,SAASM;oBAC5BL,WAAWI,YAAYJ,aAAaM;oBACpCiC,QAAQ;oBACR3B,OAAOA;oBACPC,OAAOA;oBACPC,QAAQA;oBACRkB,UAAUA;8BAET7B;;;;;AAMb,GACA"}
@@ -66,12 +66,12 @@ const noop = ()=>{
66
66
  const selectLabelId = useEnsuredId(labelProps.id, "select-label");
67
67
  const labelId = label ? selectLabelId : undefined;
68
68
  const [localValue, setLocalValue] = useState(()=>{
69
- if (typeof defaultValue !== "undefined") {
69
+ if (defaultValue !== undefined) {
70
70
  return defaultValue;
71
71
  }
72
- return typeof value !== "undefined" ? value : EMPTY_STRING;
72
+ return value !== undefined ? value : EMPTY_STRING;
73
73
  });
74
- const currentValue = typeof value === "undefined" ? localValue : value;
74
+ const currentValue = value === undefined ? localValue : value;
75
75
  const initialValue = useRef(currentValue);
76
76
  const { options, currentOption } = extractOptionsFromChildren(children, currentValue);
77
77
  const { visible, comboboxProps, movementContext, getMenuProps } = useSelectCombobox({
@@ -96,7 +96,7 @@ const noop = ()=>{
96
96
  const icon = getIcon("dropdown", propIcon);
97
97
  const theme = getFormConfig("theme", propTheme);
98
98
  let rightAddon = propRightAddon;
99
- if (typeof rightAddon === "undefined" && icon) {
99
+ if (rightAddon === undefined && icon) {
100
100
  rightAddon = /*#__PURE__*/ _jsx(IconRotator, {
101
101
  rotated: visible,
102
102
  children: icon
@@ -151,7 +151,7 @@ const noop = ()=>{
151
151
  }), textField()),
152
152
  onChange: (event)=>{
153
153
  onChange(event);
154
- if (typeof value !== "undefined") {
154
+ if (value !== undefined) {
155
155
  return;
156
156
  }
157
157
  const nextValue = event.currentTarget.value;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/Select.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type ChangeEvent,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { type BoxProps } from \"../box/Box.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { type MenuProps } from \"../menu/Menu.js\";\nimport { KeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport {\n type LabelA11y,\n type PropsWithRef,\n type RequireAtLeastOne,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { Listbox } from \"./Listbox.js\";\nimport { type OptionProps } from \"./Option.js\";\nimport { SelectedOption } from \"./SelectedOption.js\";\nimport {\n TextFieldContainer,\n type TextFieldContainerProps,\n} from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { label as labelStyles } from \"./labelStyles.js\";\nimport { select } from \"./selectStyles.js\";\nimport { extractOptionsFromChildren } from \"./selectUtils.js\";\nimport { textField } from \"./textFieldStyles.js\";\nimport { type UserAgentAutocompleteProps } from \"./types.js\";\nimport { useFormReset } from \"./useFormReset.js\";\nimport { useSelectCombobox } from \"./useSelectCombobox.js\";\nimport { triggerManualChangeEvent } from \"./utils.js\";\n\nconst EMPTY_STRING = \"\" as const;\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.5.0\n */\nexport interface GetSelectedOptionChildrenOptions<\n Value extends string = string,\n> {\n value: \"\" | Value;\n\n /**\n * The option will be undefined if there is no value or matching option.\n */\n option: OptionProps | undefined;\n\n /**\n * This is a pass-through of the {@link SelectProps.placeholder}\n */\n placeholder?: ReactNode;\n\n /**\n * This is a pass-through of the {@link SelectProps.selectedOptionProps}\n */\n children?: ReactNode;\n}\n\n/**\n * @since 6.5.0\n */\nconst defaultGetSelectedOptionChildren = (\n options: GetSelectedOptionChildrenOptions\n): ReactNode => {\n const { children, option, placeholder } = options;\n\n return children ?? (option?.children || placeholder);\n};\n\n/**\n * This is a convenience type for casting the `event.currentTarget.value` of a\n * `Select`'s change event to be union of available values.\n *\n * Note: The change event does not provide any sort of validation on the value\n * so automation tools like Cypress, Playwright, or Selenium might set an\n * invalid value. This also does not work for numbers, so you will need to\n * implement that yourself.\n *\n * @example Simple Usage\n * ```tsx\n * import { Select, type SelectChangeEvent } from \"@react-md/core/form/Select\";\n * import { Option } from \"@react-md/core/form/Option\";\n * import type { ReactElement } from \"react\";\n *\n * type Value = \"\" | \"a\" | \"b\" | \"c\" | \"d\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState<Value>(\"\");\n *\n * const handleChange = (event: SelectChangeEvent<Value>): void => {\n * // No type error!\n * // `event.currentTarget.value`'s type is `Value` instead of a generic `string`\n * setValue(event.currentTarget.value);\n * };\n *\n * return (\n * <Select\n * label=\"Label\"\n * value={value}\n * onChange={handleChange}\n * >\n * <Option value=\"a\">First</Option>\n * <Option value=\"b\">Second</Option>\n * <Option value=\"c\">Third</Option>\n * <Option value=\"d\">Fourth</Option>\n * </Select>\n * );\n * }\n * ```\n * @since 6.0.0\n */\nexport type SelectChangeEvent<Value extends string> =\n ChangeEvent<HTMLInputElement> & { currentTarget: { value: Value } };\n\n/**\n * @since 6.0.0 Rewritten with a new API.\n */\nexport interface SelectProps<Value extends string>\n extends\n Omit<TextFieldContainerProps, \"label\">,\n Pick<InputHTMLAttributes<HTMLInputElement>, \"form\" | \"required\">,\n UserAgentAutocompleteProps {\n /**\n * @defaultValue `\"select-\" + useId()`\n */\n id?: string;\n\n /**\n * Optional placeholder text or element to render while no options have been\n * selected.\n */\n placeholder?: ReactNode;\n\n /**\n * Set this to a custom dropdown icon or `null` to not render a dropdown icon.\n *\n * @defaultValue `getIcon(\"dropdown\")`\n */\n icon?: ReactNode;\n\n /**\n * Set this value to fully control the value of the select component. The\n * {@link onChange} handler **must** also be provided if this prop exists.\n */\n value?: Value;\n\n /**\n * An optional default value when the value of the select component is\n * uncontrolled.\n *\n * @defaultValue `\"\"`\n */\n defaultValue?: Value;\n\n /** @see {@link SelectChangeEvent} */\n onChange?: (event: SelectChangeEvent<Value>) => void;\n\n /**\n * An optional floating label to display like other form fields.\n */\n label?: ReactNode;\n\n /**\n * Optional props to pass to the `<span>` that surrounds the {@link label}\n */\n labelProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * An optional ref to pass to the hidden `<input type=\"text\" />` element that\n * stores the current value. This is really only useful if you'd like to keep\n * this component uncontrolled and access the value through\n * `inputRef.current.value`.\n */\n inputRef?: Ref<HTMLInputElement>;\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n\n /**\n * A ref for the container `<div>` element.\n */\n containerRef?: Ref<HTMLDivElement>;\n\n /**\n * Any additional props to provide to the `Menu` component that renders all\n * the `Option`s.\n *\n * The menu will always have these default values unless explicity\n * overwritten by this prop:\n *\n * - `aria-labelledby={label ? labelId : id}` -- this will be undefined if\n * `aria-label` is provided\n * - `anchor={BELOW_CENTER_ANCHOR}`\n * - `width=\"min\"`\n */\n menuProps?: PropsWithRef<\n Omit<MenuProps, \"visible\" | \"onRequestClose\" | \"fixedTo\">\n >;\n\n /**\n * Any additional props to pass to the div that contains the current visible\n * option.\n */\n selectedOptionProps?: BoxProps;\n\n /**\n * Set this to `true` if all the `Option` components should display the\n * selected icon after the children instead of before.\n *\n * @see {@link disableSelectedIcon} to remove the selected icon instead.\n *\n * @defaultValue `false`\n */\n selectedIconAfter?: boolean;\n\n /**\n * Set this to `true` to prevent the current option from rendering the\n * `leftAddon` in the `TextFieldContainer`.\n *\n * @defaultValue `false`\n */\n disableOptionAddon?: boolean;\n\n /**\n * Set this to `true` to update all the `Option` components to no longer\n * render an icon while selected.\n *\n * @defaultValue `false`\n */\n disableSelectedIcon?: boolean;\n\n /**\n * @since 6.5.0\n * @defaultValue `({ children, option, placeholder }) => children ?? (option?.children || placeholder)`\n */\n getSelectedOptionChildren?: (\n options: GetSelectedOptionChildrenOptions<Value>\n ) => ReactNode;\n\n /**\n * This should be the available `Option`s for the select to choose from. It\n * can also contain `OptGroup` or any other elements but only clicking on an\n * `Option` component will update the value.\n */\n children: ReactNode;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { Option } from \"@react-md/core/form/Option\";\n * import { Select } from \"@react-md/core/form/Select\";\n * import { useState, type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState(\"\");\n *\n * return (\n * <Select\n * label=\"Select\"\n * value={value}\n * onChange={(event) => setValue(event.currentTarget.value)}\n * placeholder=\"Select a value\"\n * >\n * <Option value=\"a\">Option 1</Option>\n * <Option value=\"b\">Option 2</Option>\n * <Option value=\"c\">Option 3</Option>\n * <Option value=\"d\">Option 4</Option>\n * </Select>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/select | Select Demos}\n * @since 6.0.0 Rewritten with a new API.\n */\nexport function Select<Value extends string>(\n props: RequireAtLeastOne<SelectProps<Value>, \"label\" | keyof LabelA11y>\n): ReactElement {\n const {\n id,\n form,\n autoCompleteValue,\n autoComplete = autoCompleteValue,\n name = autoCompleteValue,\n className,\n onClick,\n onFocus,\n onKeyDown,\n inputRef: propInputRef,\n inputProps,\n containerRef,\n placeholder,\n menuProps = {},\n label,\n labelProps = {},\n selectedOptionProps,\n getSelectedOptionChildren = defaultGetSelectedOptionChildren,\n icon: propIcon,\n value,\n defaultValue,\n theme: propTheme,\n onChange = noop,\n rightAddon: propRightAddon,\n active = false,\n required,\n selectedIconAfter = false,\n disableOptionAddon = false,\n disableSelectedIcon = false,\n children,\n ...remaining\n } = props;\n const { dense, error, disabled } = props;\n\n const comboboxId = useEnsuredId(id, \"select\");\n const inputId = useEnsuredId(inputProps?.id, \"select-value\");\n const selectLabelId = useEnsuredId(labelProps.id, \"select-label\");\n const labelId = label ? selectLabelId : undefined;\n\n const [localValue, setLocalValue] = useState(() => {\n if (typeof defaultValue !== \"undefined\") {\n return defaultValue;\n }\n\n return typeof value !== \"undefined\" ? value : EMPTY_STRING;\n });\n const currentValue = typeof value === \"undefined\" ? localValue : value;\n const initialValue = useRef(currentValue);\n const { options, currentOption } = extractOptionsFromChildren(\n children,\n currentValue\n );\n\n const { visible, comboboxProps, movementContext, getMenuProps } =\n useSelectCombobox({\n form,\n value: currentValue,\n values: options,\n onClick,\n onFocus,\n onKeyDown,\n disabled,\n popupId: menuProps.id,\n popupRef: menuProps.ref,\n comboboxId,\n comboboxRef: containerRef,\n });\n\n const [inputRef, inputRefCallback] = useEnsuredRef(propInputRef);\n useFormReset({\n form,\n elementRef: inputRef,\n defaultValue: initialValue.current,\n });\n\n const icon = getIcon(\"dropdown\", propIcon);\n const theme = getFormConfig(\"theme\", propTheme);\n let rightAddon = propRightAddon;\n if (typeof rightAddon === \"undefined\" && icon) {\n rightAddon = <IconRotator rotated={visible}>{icon}</IconRotator>;\n }\n\n const { ref: listboxRef, ...listboxProps } = getMenuProps(menuProps);\n let listboxLabelledBy = menuProps[\"aria-labelledby\"];\n const listboxLabel = menuProps[\"aria-label\"];\n if (!listboxLabel && !listboxLabelledBy) {\n listboxLabelledBy = labelId || comboboxId;\n }\n\n return (\n <KeyboardMovementProvider value={movementContext}>\n <TextFieldContainer\n aria-labelledby={labelId}\n {...remaining}\n {...comboboxProps}\n label={!!label}\n theme={theme}\n active={active || visible}\n className={cnb(\"rmd-select-container\", className)}\n rightAddon={rightAddon}\n >\n <SelectedOption\n option={currentOption}\n disableAddon={disableOptionAddon}\n {...selectedOptionProps}\n >\n {getSelectedOptionChildren({\n value: currentValue,\n option: currentOption,\n placeholder,\n children: selectedOptionProps?.children,\n })}\n </SelectedOption>\n <input\n aria-hidden\n id={inputId}\n ref={inputRefCallback}\n type=\"text\"\n autoComplete={autoComplete}\n name={name}\n tabIndex={-1}\n disabled={disabled}\n required={required}\n placeholder=\" \"\n {...inputProps}\n value={value}\n defaultValue={defaultValue}\n className={cnb(select({ theme }), textField())}\n onChange={(event) => {\n onChange(event as SelectChangeEvent<Value>);\n if (typeof value !== \"undefined\") {\n return;\n }\n\n const nextValue = event.currentTarget.value;\n const nextOption = options.find((option) => option === nextValue);\n\n setLocalValue(nextOption ?? initialValue.current);\n }}\n />\n {label && (\n <span\n {...labelProps}\n id={labelId}\n className={labelStyles({\n dense,\n error,\n disabled,\n active: active || visible,\n floating: true,\n floatingActive: !!placeholder || !!currentOption,\n className: labelProps.className,\n })}\n >\n {label}\n </span>\n )}\n </TextFieldContainer>\n <Listbox\n {...listboxProps}\n aria-label={listboxLabel}\n aria-labelledby={listboxLabelledBy as string}\n nodeRef={listboxRef}\n value={currentValue}\n setValue={useCallback(\n (option: \"\" | Value) => {\n triggerManualChangeEvent(inputRef.current, option);\n },\n [inputRef]\n )}\n selectedIconAfter={selectedIconAfter}\n disableSelectedIcon={disableSelectedIcon}\n >\n {children}\n </Listbox>\n </KeyboardMovementProvider>\n );\n}\n"],"names":["cnb","useCallback","useRef","useState","IconRotator","getIcon","KeyboardMovementProvider","useEnsuredId","useEnsuredRef","Listbox","SelectedOption","TextFieldContainer","getFormConfig","label","labelStyles","select","extractOptionsFromChildren","textField","useFormReset","useSelectCombobox","triggerManualChangeEvent","EMPTY_STRING","noop","defaultGetSelectedOptionChildren","options","children","option","placeholder","Select","props","id","form","autoCompleteValue","autoComplete","name","className","onClick","onFocus","onKeyDown","inputRef","propInputRef","inputProps","containerRef","menuProps","labelProps","selectedOptionProps","getSelectedOptionChildren","icon","propIcon","value","defaultValue","theme","propTheme","onChange","rightAddon","propRightAddon","active","required","selectedIconAfter","disableOptionAddon","disableSelectedIcon","remaining","dense","error","disabled","comboboxId","inputId","selectLabelId","labelId","undefined","localValue","setLocalValue","currentValue","initialValue","currentOption","visible","comboboxProps","movementContext","getMenuProps","values","popupId","popupRef","ref","comboboxRef","inputRefCallback","elementRef","current","rotated","listboxRef","listboxProps","listboxLabelledBy","listboxLabel","aria-labelledby","disableAddon","input","aria-hidden","type","tabIndex","event","nextValue","currentTarget","nextOption","find","span","floating","floatingActive","aria-label","nodeRef","setValue"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/form/Select.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type ChangeEvent,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { type BoxProps } from \"../box/Box.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { type MenuProps } from \"../menu/Menu.js\";\nimport { KeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport {\n type LabelA11y,\n type PropsWithRef,\n type RequireAtLeastOne,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { Listbox } from \"./Listbox.js\";\nimport { type OptionProps } from \"./Option.js\";\nimport { SelectedOption } from \"./SelectedOption.js\";\nimport {\n TextFieldContainer,\n type TextFieldContainerProps,\n} from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { label as labelStyles } from \"./labelStyles.js\";\nimport { select } from \"./selectStyles.js\";\nimport { extractOptionsFromChildren } from \"./selectUtils.js\";\nimport { textField } from \"./textFieldStyles.js\";\nimport { type UserAgentAutocompleteProps } from \"./types.js\";\nimport { useFormReset } from \"./useFormReset.js\";\nimport { useSelectCombobox } from \"./useSelectCombobox.js\";\nimport { triggerManualChangeEvent } from \"./utils.js\";\n\nconst EMPTY_STRING = \"\" as const;\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.5.0\n */\nexport interface GetSelectedOptionChildrenOptions<\n Value extends string = string,\n> {\n value: \"\" | Value;\n\n /**\n * The option will be undefined if there is no value or matching option.\n */\n option: OptionProps | undefined;\n\n /**\n * This is a pass-through of the {@link SelectProps.placeholder}\n */\n placeholder?: ReactNode;\n\n /**\n * This is a pass-through of the {@link SelectProps.selectedOptionProps}\n */\n children?: ReactNode;\n}\n\n/**\n * @since 6.5.0\n */\nconst defaultGetSelectedOptionChildren = (\n options: GetSelectedOptionChildrenOptions\n): ReactNode => {\n const { children, option, placeholder } = options;\n\n return children ?? (option?.children || placeholder);\n};\n\n/**\n * This is a convenience type for casting the `event.currentTarget.value` of a\n * `Select`'s change event to be union of available values.\n *\n * Note: The change event does not provide any sort of validation on the value\n * so automation tools like Cypress, Playwright, or Selenium might set an\n * invalid value. This also does not work for numbers, so you will need to\n * implement that yourself.\n *\n * @example Simple Usage\n * ```tsx\n * import { Select, type SelectChangeEvent } from \"@react-md/core/form/Select\";\n * import { Option } from \"@react-md/core/form/Option\";\n * import type { ReactElement } from \"react\";\n *\n * type Value = \"\" | \"a\" | \"b\" | \"c\" | \"d\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState<Value>(\"\");\n *\n * const handleChange = (event: SelectChangeEvent<Value>): void => {\n * // No type error!\n * // `event.currentTarget.value`'s type is `Value` instead of a generic `string`\n * setValue(event.currentTarget.value);\n * };\n *\n * return (\n * <Select\n * label=\"Label\"\n * value={value}\n * onChange={handleChange}\n * >\n * <Option value=\"a\">First</Option>\n * <Option value=\"b\">Second</Option>\n * <Option value=\"c\">Third</Option>\n * <Option value=\"d\">Fourth</Option>\n * </Select>\n * );\n * }\n * ```\n * @since 6.0.0\n */\nexport type SelectChangeEvent<Value extends string> =\n ChangeEvent<HTMLInputElement> & { currentTarget: { value: Value } };\n\n/**\n * @since 6.0.0 Rewritten with a new API.\n */\nexport interface SelectProps<Value extends string>\n extends\n Omit<TextFieldContainerProps, \"label\">,\n Pick<InputHTMLAttributes<HTMLInputElement>, \"form\" | \"required\">,\n UserAgentAutocompleteProps {\n /**\n * @defaultValue `\"select-\" + useId()`\n */\n id?: string;\n\n /**\n * Optional placeholder text or element to render while no options have been\n * selected.\n */\n placeholder?: ReactNode;\n\n /**\n * Set this to a custom dropdown icon or `null` to not render a dropdown icon.\n *\n * @defaultValue `getIcon(\"dropdown\")`\n */\n icon?: ReactNode;\n\n /**\n * Set this value to fully control the value of the select component. The\n * {@link onChange} handler **must** also be provided if this prop exists.\n */\n value?: Value;\n\n /**\n * An optional default value when the value of the select component is\n * uncontrolled.\n *\n * @defaultValue `\"\"`\n */\n defaultValue?: Value;\n\n /** @see {@link SelectChangeEvent} */\n onChange?: (event: SelectChangeEvent<Value>) => void;\n\n /**\n * An optional floating label to display like other form fields.\n */\n label?: ReactNode;\n\n /**\n * Optional props to pass to the `<span>` that surrounds the {@link label}\n */\n labelProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * An optional ref to pass to the hidden `<input type=\"text\" />` element that\n * stores the current value. This is really only useful if you'd like to keep\n * this component uncontrolled and access the value through\n * `inputRef.current.value`.\n */\n inputRef?: Ref<HTMLInputElement>;\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n\n /**\n * A ref for the container `<div>` element.\n */\n containerRef?: Ref<HTMLDivElement>;\n\n /**\n * Any additional props to provide to the `Menu` component that renders all\n * the `Option`s.\n *\n * The menu will always have these default values unless explicity\n * overwritten by this prop:\n *\n * - `aria-labelledby={label ? labelId : id}` -- this will be undefined if\n * `aria-label` is provided\n * - `anchor={BELOW_CENTER_ANCHOR}`\n * - `width=\"min\"`\n */\n menuProps?: PropsWithRef<\n Omit<MenuProps, \"visible\" | \"onRequestClose\" | \"fixedTo\">\n >;\n\n /**\n * Any additional props to pass to the div that contains the current visible\n * option.\n */\n selectedOptionProps?: BoxProps;\n\n /**\n * Set this to `true` if all the `Option` components should display the\n * selected icon after the children instead of before.\n *\n * @see {@link disableSelectedIcon} to remove the selected icon instead.\n *\n * @defaultValue `false`\n */\n selectedIconAfter?: boolean;\n\n /**\n * Set this to `true` to prevent the current option from rendering the\n * `leftAddon` in the `TextFieldContainer`.\n *\n * @defaultValue `false`\n */\n disableOptionAddon?: boolean;\n\n /**\n * Set this to `true` to update all the `Option` components to no longer\n * render an icon while selected.\n *\n * @defaultValue `false`\n */\n disableSelectedIcon?: boolean;\n\n /**\n * @since 6.5.0\n * @defaultValue `({ children, option, placeholder }) => children ?? (option?.children || placeholder)`\n */\n getSelectedOptionChildren?: (\n options: GetSelectedOptionChildrenOptions<Value>\n ) => ReactNode;\n\n /**\n * This should be the available `Option`s for the select to choose from. It\n * can also contain `OptGroup` or any other elements but only clicking on an\n * `Option` component will update the value.\n */\n children: ReactNode;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { Option } from \"@react-md/core/form/Option\";\n * import { Select } from \"@react-md/core/form/Select\";\n * import { useState, type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState(\"\");\n *\n * return (\n * <Select\n * label=\"Select\"\n * value={value}\n * onChange={(event) => setValue(event.currentTarget.value)}\n * placeholder=\"Select a value\"\n * >\n * <Option value=\"a\">Option 1</Option>\n * <Option value=\"b\">Option 2</Option>\n * <Option value=\"c\">Option 3</Option>\n * <Option value=\"d\">Option 4</Option>\n * </Select>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/select | Select Demos}\n * @since 6.0.0 Rewritten with a new API.\n */\nexport function Select<Value extends string>(\n props: RequireAtLeastOne<SelectProps<Value>, \"label\" | keyof LabelA11y>\n): ReactElement {\n const {\n id,\n form,\n autoCompleteValue,\n autoComplete = autoCompleteValue,\n name = autoCompleteValue,\n className,\n onClick,\n onFocus,\n onKeyDown,\n inputRef: propInputRef,\n inputProps,\n containerRef,\n placeholder,\n menuProps = {},\n label,\n labelProps = {},\n selectedOptionProps,\n getSelectedOptionChildren = defaultGetSelectedOptionChildren,\n icon: propIcon,\n value,\n defaultValue,\n theme: propTheme,\n onChange = noop,\n rightAddon: propRightAddon,\n active = false,\n required,\n selectedIconAfter = false,\n disableOptionAddon = false,\n disableSelectedIcon = false,\n children,\n ...remaining\n } = props;\n const { dense, error, disabled } = props;\n\n const comboboxId = useEnsuredId(id, \"select\");\n const inputId = useEnsuredId(inputProps?.id, \"select-value\");\n const selectLabelId = useEnsuredId(labelProps.id, \"select-label\");\n const labelId = label ? selectLabelId : undefined;\n\n const [localValue, setLocalValue] = useState(() => {\n if (defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value !== undefined ? value : EMPTY_STRING;\n });\n const currentValue = value === undefined ? localValue : value;\n const initialValue = useRef(currentValue);\n const { options, currentOption } = extractOptionsFromChildren(\n children,\n currentValue\n );\n\n const { visible, comboboxProps, movementContext, getMenuProps } =\n useSelectCombobox({\n form,\n value: currentValue,\n values: options,\n onClick,\n onFocus,\n onKeyDown,\n disabled,\n popupId: menuProps.id,\n popupRef: menuProps.ref,\n comboboxId,\n comboboxRef: containerRef,\n });\n\n const [inputRef, inputRefCallback] = useEnsuredRef(propInputRef);\n useFormReset({\n form,\n elementRef: inputRef,\n defaultValue: initialValue.current,\n });\n\n const icon = getIcon(\"dropdown\", propIcon);\n const theme = getFormConfig(\"theme\", propTheme);\n let rightAddon = propRightAddon;\n if (rightAddon === undefined && icon) {\n rightAddon = <IconRotator rotated={visible}>{icon}</IconRotator>;\n }\n\n const { ref: listboxRef, ...listboxProps } = getMenuProps(menuProps);\n let listboxLabelledBy = menuProps[\"aria-labelledby\"];\n const listboxLabel = menuProps[\"aria-label\"];\n if (!listboxLabel && !listboxLabelledBy) {\n listboxLabelledBy = labelId || comboboxId;\n }\n\n return (\n <KeyboardMovementProvider value={movementContext}>\n <TextFieldContainer\n aria-labelledby={labelId}\n {...remaining}\n {...comboboxProps}\n label={!!label}\n theme={theme}\n active={active || visible}\n className={cnb(\"rmd-select-container\", className)}\n rightAddon={rightAddon}\n >\n <SelectedOption\n option={currentOption}\n disableAddon={disableOptionAddon}\n {...selectedOptionProps}\n >\n {getSelectedOptionChildren({\n value: currentValue,\n option: currentOption,\n placeholder,\n children: selectedOptionProps?.children,\n })}\n </SelectedOption>\n <input\n aria-hidden\n id={inputId}\n ref={inputRefCallback}\n type=\"text\"\n autoComplete={autoComplete}\n name={name}\n tabIndex={-1}\n disabled={disabled}\n required={required}\n placeholder=\" \"\n {...inputProps}\n value={value}\n defaultValue={defaultValue}\n className={cnb(select({ theme }), textField())}\n onChange={(event) => {\n onChange(event as SelectChangeEvent<Value>);\n if (value !== undefined) {\n return;\n }\n\n const nextValue = event.currentTarget.value;\n const nextOption = options.find((option) => option === nextValue);\n\n setLocalValue(nextOption ?? initialValue.current);\n }}\n />\n {label && (\n <span\n {...labelProps}\n id={labelId}\n className={labelStyles({\n dense,\n error,\n disabled,\n active: active || visible,\n floating: true,\n floatingActive: !!placeholder || !!currentOption,\n className: labelProps.className,\n })}\n >\n {label}\n </span>\n )}\n </TextFieldContainer>\n <Listbox\n {...listboxProps}\n aria-label={listboxLabel}\n aria-labelledby={listboxLabelledBy as string}\n nodeRef={listboxRef}\n value={currentValue}\n setValue={useCallback(\n (option: \"\" | Value) => {\n triggerManualChangeEvent(inputRef.current, option);\n },\n [inputRef]\n )}\n selectedIconAfter={selectedIconAfter}\n disableSelectedIcon={disableSelectedIcon}\n >\n {children}\n </Listbox>\n </KeyboardMovementProvider>\n );\n}\n"],"names":["cnb","useCallback","useRef","useState","IconRotator","getIcon","KeyboardMovementProvider","useEnsuredId","useEnsuredRef","Listbox","SelectedOption","TextFieldContainer","getFormConfig","label","labelStyles","select","extractOptionsFromChildren","textField","useFormReset","useSelectCombobox","triggerManualChangeEvent","EMPTY_STRING","noop","defaultGetSelectedOptionChildren","options","children","option","placeholder","Select","props","id","form","autoCompleteValue","autoComplete","name","className","onClick","onFocus","onKeyDown","inputRef","propInputRef","inputProps","containerRef","menuProps","labelProps","selectedOptionProps","getSelectedOptionChildren","icon","propIcon","value","defaultValue","theme","propTheme","onChange","rightAddon","propRightAddon","active","required","selectedIconAfter","disableOptionAddon","disableSelectedIcon","remaining","dense","error","disabled","comboboxId","inputId","selectLabelId","labelId","undefined","localValue","setLocalValue","currentValue","initialValue","currentOption","visible","comboboxProps","movementContext","getMenuProps","values","popupId","popupRef","ref","comboboxRef","inputRefCallback","elementRef","current","rotated","listboxRef","listboxProps","listboxLabelledBy","listboxLabel","aria-labelledby","disableAddon","input","aria-hidden","type","tabIndex","event","nextValue","currentTarget","nextOption","find","span","floating","floatingActive","aria-label","nodeRef","setValue"],"mappings":"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"}
@@ -27,7 +27,7 @@ let uncontrolledToggles = true;
27
27
  /**
28
28
  * @since 6.0.0
29
29
  */ export function getFormConfig(name, override) {
30
- if (typeof override !== "undefined") {
30
+ if (override !== undefined) {
31
31
  return override;
32
32
  }
33
33
  return FORM_CONFIG[name];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/formConfig.ts"],"sourcesContent":["import {\n type FormConfiguration,\n type FormTheme,\n type FormUnderlineDirection,\n} from \"./types.js\";\n\n// NOTE: Uses get/set for test mocking\n\nlet theme: FormTheme = \"outline\";\nlet underlineDirection: FormUnderlineDirection = \"left\";\nlet uncontrolledToggles = true;\n\n/**\n * @since 6.0.0\n */\nexport const FORM_CONFIG: FormConfiguration = {\n get theme() {\n return theme;\n },\n set theme(nextTheme: FormTheme) {\n theme = nextTheme;\n },\n get underlineDirection() {\n return underlineDirection;\n },\n set underlineDirection(nextUnderlineDirection: FormUnderlineDirection) {\n underlineDirection = nextUnderlineDirection;\n },\n get uncontrolledToggles() {\n return uncontrolledToggles;\n },\n set uncontrolledToggles(nextUncontrolledToggles: boolean) {\n uncontrolledToggles = nextUncontrolledToggles;\n },\n};\n\n/**\n * @since 6.0.0\n */\nexport function getFormConfig<N extends keyof FormConfiguration>(\n name: N,\n override?: FormConfiguration[N]\n): FormConfiguration[N] {\n if (typeof override !== \"undefined\") {\n return override;\n }\n\n return FORM_CONFIG[name];\n}\n"],"names":["theme","underlineDirection","uncontrolledToggles","FORM_CONFIG","nextTheme","nextUnderlineDirection","nextUncontrolledToggles","getFormConfig","name","override"],"mappings":"AAMA,sCAAsC;AAEtC,IAAIA,QAAmB;AACvB,IAAIC,qBAA6C;AACjD,IAAIC,sBAAsB;AAE1B;;CAEC,GACD,OAAO,MAAMC,cAAiC;IAC5C,IAAIH,SAAQ;QACV,OAAOA;IACT;IACA,IAAIA,OAAMI,UAAsB;QAC9BJ,QAAQI;IACV;IACA,IAAIH,sBAAqB;QACvB,OAAOA;IACT;IACA,IAAIA,oBAAmBI,uBAAgD;QACrEJ,qBAAqBI;IACvB;IACA,IAAIH,uBAAsB;QACxB,OAAOA;IACT;IACA,IAAIA,qBAAoBI,wBAAkC;QACxDJ,sBAAsBI;IACxB;AACF,EAAE;AAEF;;CAEC,GACD,OAAO,SAASC,cACdC,IAAO,EACPC,QAA+B;IAE/B,IAAI,OAAOA,aAAa,aAAa;QACnC,OAAOA;IACT;IAEA,OAAON,WAAW,CAACK,KAAK;AAC1B"}
1
+ {"version":3,"sources":["../../src/form/formConfig.ts"],"sourcesContent":["import {\n type FormConfiguration,\n type FormTheme,\n type FormUnderlineDirection,\n} from \"./types.js\";\n\n// NOTE: Uses get/set for test mocking\n\nlet theme: FormTheme = \"outline\";\nlet underlineDirection: FormUnderlineDirection = \"left\";\nlet uncontrolledToggles = true;\n\n/**\n * @since 6.0.0\n */\nexport const FORM_CONFIG: FormConfiguration = {\n get theme() {\n return theme;\n },\n set theme(nextTheme: FormTheme) {\n theme = nextTheme;\n },\n get underlineDirection() {\n return underlineDirection;\n },\n set underlineDirection(nextUnderlineDirection: FormUnderlineDirection) {\n underlineDirection = nextUnderlineDirection;\n },\n get uncontrolledToggles() {\n return uncontrolledToggles;\n },\n set uncontrolledToggles(nextUncontrolledToggles: boolean) {\n uncontrolledToggles = nextUncontrolledToggles;\n },\n};\n\n/**\n * @since 6.0.0\n */\nexport function getFormConfig<N extends keyof FormConfiguration>(\n name: N,\n override?: FormConfiguration[N]\n): FormConfiguration[N] {\n if (override !== undefined) {\n return override;\n }\n\n return FORM_CONFIG[name];\n}\n"],"names":["theme","underlineDirection","uncontrolledToggles","FORM_CONFIG","nextTheme","nextUnderlineDirection","nextUncontrolledToggles","getFormConfig","name","override","undefined"],"mappings":"AAMA,sCAAsC;AAEtC,IAAIA,QAAmB;AACvB,IAAIC,qBAA6C;AACjD,IAAIC,sBAAsB;AAE1B;;CAEC,GACD,OAAO,MAAMC,cAAiC;IAC5C,IAAIH,SAAQ;QACV,OAAOA;IACT;IACA,IAAIA,OAAMI,UAAsB;QAC9BJ,QAAQI;IACV;IACA,IAAIH,sBAAqB;QACvB,OAAOA;IACT;IACA,IAAIA,oBAAmBI,uBAAgD;QACrEJ,qBAAqBI;IACvB;IACA,IAAIH,uBAAsB;QACxB,OAAOA;IACT;IACA,IAAIA,qBAAoBI,wBAAkC;QACxDJ,sBAAsBI;IACxB;AACF,EAAE;AAEF;;CAEC,GACD,OAAO,SAASC,cACdC,IAAO,EACPC,QAA+B;IAE/B,IAAIA,aAAaC,WAAW;QAC1B,OAAOD;IACT;IAEA,OAAON,WAAW,CAACK,KAAK;AAC1B"}
@@ -6,6 +6,12 @@ const styles = bem("rmd-input-toggle");
6
6
  * @since 6.0.0
7
7
  */ export function inputToggle(options) {
8
8
  const { className, em = true, type, size = "auto", error, active = false, disabled = false, uncontrolled } = options;
9
+ let textColor;
10
+ if (disabled) {
11
+ textColor = "text-disabled";
12
+ } else if (error) {
13
+ textColor = "error";
14
+ }
9
15
  return cnb(`rmd-${type}`, styles({
10
16
  em,
11
17
  active: active && !disabled,
@@ -16,7 +22,7 @@ const styles = bem("rmd-input-toggle");
16
22
  large: size === "large",
17
23
  uncontrolled
18
24
  }), cssUtils({
19
- textColor: disabled ? "text-disabled" : error ? "error" : undefined
25
+ textColor
20
26
  }), className);
21
27
  }
22
28
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/inputToggleStyles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\nimport { cssUtils } from \"../cssUtils.js\";\nimport { bem } from \"../utils/bem.js\";\nimport { type FormComponentStates } from \"./types.js\";\n\nconst styles = bem(\"rmd-input-toggle\");\n\n/**\n * The size to use for the `Checkbox` or `Radio` component. Each of these values\n * except for `\"auto\"` map to Sass variables:\n * - `\"small\"` - `$input-toggle-small-size`\n * - `\"dense\"` - `$input-toggle-dense-size`\n * - `\"normal\"` - `$input-toggle-large-size`\n * - `\"large\"` - `$input-toggle-large-size`\n *\n * When this is set to `\"auto\"`, the size will be determined by the current\n * `font-size` of the `Label` element.\n *\n * @since 6.0.0\n */\nexport type InputToggleSize = \"auto\" | \"small\" | \"dense\" | \"normal\" | \"large\";\n\n/** @since 6.0.0 */\nexport interface InputToggleClassNameOptions extends Omit<\n FormComponentStates,\n \"readOnly\"\n> {\n className?: string;\n type: \"checkbox\" | \"radio\";\n\n /**\n * Set the icon size to `1em` to allow easy sizing through font size.\n *\n * @defaultValue `true`\n */\n em?: boolean;\n\n /**\n * @see {@link InputToggleSize}\n * @defaultValue `\"auto\"`\n */\n size?: InputToggleSize;\n\n uncontrolled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport function inputToggle(options: InputToggleClassNameOptions): string {\n const {\n className,\n em = true,\n type,\n size = \"auto\",\n error,\n active = false,\n disabled = false,\n uncontrolled,\n } = options;\n\n return cnb(\n `rmd-${type}`,\n styles({\n em,\n active: active && !disabled,\n disabled,\n small: size === \"small\",\n dense: size === \"dense\",\n normal: size === \"normal\",\n large: size === \"large\",\n uncontrolled,\n }),\n cssUtils({\n textColor: disabled ? \"text-disabled\" : error ? \"error\" : undefined,\n }),\n className\n );\n}\n"],"names":["cnb","cssUtils","bem","styles","inputToggle","options","className","em","type","size","error","active","disabled","uncontrolled","small","dense","normal","large","textColor","undefined"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAASC,QAAQ,QAAQ,iBAAiB;AAC1C,SAASC,GAAG,QAAQ,kBAAkB;AAGtC,MAAMC,SAASD,IAAI;AAyCnB;;CAEC,GACD,OAAO,SAASE,YAAYC,OAAoC;IAC9D,MAAM,EACJC,SAAS,EACTC,KAAK,IAAI,EACTC,IAAI,EACJC,OAAO,MAAM,EACbC,KAAK,EACLC,SAAS,KAAK,EACdC,WAAW,KAAK,EAChBC,YAAY,EACb,GAAGR;IAEJ,OAAOL,IACL,CAAC,IAAI,EAAEQ,MAAM,EACbL,OAAO;QACLI;QACAI,QAAQA,UAAU,CAACC;QACnBA;QACAE,OAAOL,SAAS;QAChBM,OAAON,SAAS;QAChBO,QAAQP,SAAS;QACjBQ,OAAOR,SAAS;QAChBI;IACF,IACAZ,SAAS;QACPiB,WAAWN,WAAW,kBAAkBF,QAAQ,UAAUS;IAC5D,IACAb;AAEJ"}
1
+ {"version":3,"sources":["../../src/form/inputToggleStyles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\nimport { type TextColor, type ThemeColor, cssUtils } from \"../cssUtils.js\";\nimport { bem } from \"../utils/bem.js\";\nimport { type FormComponentStates } from \"./types.js\";\n\nconst styles = bem(\"rmd-input-toggle\");\n\n/**\n * The size to use for the `Checkbox` or `Radio` component. Each of these values\n * except for `\"auto\"` map to Sass variables:\n * - `\"small\"` - `$input-toggle-small-size`\n * - `\"dense\"` - `$input-toggle-dense-size`\n * - `\"normal\"` - `$input-toggle-large-size`\n * - `\"large\"` - `$input-toggle-large-size`\n *\n * When this is set to `\"auto\"`, the size will be determined by the current\n * `font-size` of the `Label` element.\n *\n * @since 6.0.0\n */\nexport type InputToggleSize = \"auto\" | \"small\" | \"dense\" | \"normal\" | \"large\";\n\n/** @since 6.0.0 */\nexport interface InputToggleClassNameOptions extends Omit<\n FormComponentStates,\n \"readOnly\"\n> {\n className?: string;\n type: \"checkbox\" | \"radio\";\n\n /**\n * Set the icon size to `1em` to allow easy sizing through font size.\n *\n * @defaultValue `true`\n */\n em?: boolean;\n\n /**\n * @see {@link InputToggleSize}\n * @defaultValue `\"auto\"`\n */\n size?: InputToggleSize;\n\n uncontrolled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport function inputToggle(options: InputToggleClassNameOptions): string {\n const {\n className,\n em = true,\n type,\n size = \"auto\",\n error,\n active = false,\n disabled = false,\n uncontrolled,\n } = options;\n\n let textColor: TextColor | ThemeColor | undefined;\n if (disabled) {\n textColor = \"text-disabled\";\n } else if (error) {\n textColor = \"error\";\n }\n\n return cnb(\n `rmd-${type}`,\n styles({\n em,\n active: active && !disabled,\n disabled,\n small: size === \"small\",\n dense: size === \"dense\",\n normal: size === \"normal\",\n large: size === \"large\",\n uncontrolled,\n }),\n cssUtils({ textColor }),\n className\n );\n}\n"],"names":["cnb","cssUtils","bem","styles","inputToggle","options","className","em","type","size","error","active","disabled","uncontrolled","textColor","small","dense","normal","large"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAA0CC,QAAQ,QAAQ,iBAAiB;AAC3E,SAASC,GAAG,QAAQ,kBAAkB;AAGtC,MAAMC,SAASD,IAAI;AAyCnB;;CAEC,GACD,OAAO,SAASE,YAAYC,OAAoC;IAC9D,MAAM,EACJC,SAAS,EACTC,KAAK,IAAI,EACTC,IAAI,EACJC,OAAO,MAAM,EACbC,KAAK,EACLC,SAAS,KAAK,EACdC,WAAW,KAAK,EAChBC,YAAY,EACb,GAAGR;IAEJ,IAAIS;IACJ,IAAIF,UAAU;QACZE,YAAY;IACd,OAAO,IAAIJ,OAAO;QAChBI,YAAY;IACd;IAEA,OAAOd,IACL,CAAC,IAAI,EAAEQ,MAAM,EACbL,OAAO;QACLI;QACAI,QAAQA,UAAU,CAACC;QACnBA;QACAG,OAAON,SAAS;QAChBO,OAAOP,SAAS;QAChBQ,QAAQR,SAAS;QACjBS,OAAOT,SAAS;QAChBI;IACF,IACAZ,SAAS;QAAEa;IAAU,IACrBR;AAEJ"}
@@ -38,8 +38,8 @@ import { Children, isValidElement } from "react";
38
38
  return;
39
39
  }
40
40
  const { value, disabled, children } = child.props;
41
- if (typeof value !== "undefined") {
42
- if (value === currentValue || !currentOption && typeof currentValue === "undefined") {
41
+ if (value !== undefined) {
42
+ if (value === currentValue || !currentOption && currentValue === undefined) {
43
43
  currentOption = child.props;
44
44
  }
45
45
  if (!disabled) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/selectUtils.ts"],"sourcesContent":["import { Children, type ReactNode, isValidElement } from \"react\";\n\nimport { type MenuItemProps } from \"../menu/MenuItem.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface SelectOption<\n Value extends string | number = string,\n> extends MenuItemProps {\n value: Value;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nfunction getLabelFromChildren(children: ReactNode): string {\n if (!children) {\n return \"\";\n }\n\n if (typeof children === \"string\" || typeof children === \"number\") {\n return `${children}`;\n }\n\n if (isValidElement<{ children: ReactNode; hidden?: boolean }>(children)) {\n if (children.props.hidden) {\n return \"\";\n }\n\n return getLabelFromChildren(children.props.children);\n }\n\n const childList = Children.toArray(children);\n for (const child of childList) {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return `${child}`[0].toUpperCase();\n }\n\n if (\n isValidElement<{ children: ReactNode; hidden?: boolean }>(child) &&\n !child.props.hidden\n ) {\n return getLabelFromChildren(child.props.children);\n }\n }\n\n return \"\";\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\ninterface ExtractedOptions<Value extends string | number> {\n options: readonly Value[];\n currentOption: SelectOption<Value> | undefined;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function extractOptionsFromChildren<Value extends string | number>(\n children: ReactNode,\n currentValue: Value | undefined\n): ExtractedOptions<Value> {\n let currentOption: SelectOption<Value> | undefined;\n\n const options: Value[] = [];\n const searchValues: string[] = [];\n Children.forEach(children, (child) => {\n if (!isValidElement<SelectOption<Value>>(child)) {\n return;\n }\n\n const { value, disabled, children } = child.props;\n if (typeof value !== \"undefined\") {\n if (\n value === currentValue ||\n (!currentOption && typeof currentValue === \"undefined\")\n ) {\n currentOption = child.props;\n }\n\n if (!disabled) {\n options.push(child.props.value);\n searchValues.push(getLabelFromChildren(children));\n }\n } else if (children) {\n const result = extractOptionsFromChildren(children, currentValue);\n if (!currentOption) {\n ({ currentOption } = result);\n }\n\n options.push(...result.options);\n }\n });\n\n return {\n options,\n currentOption,\n };\n}\n"],"names":["Children","isValidElement","getLabelFromChildren","children","props","hidden","childList","toArray","child","toUpperCase","extractOptionsFromChildren","currentValue","currentOption","options","searchValues","forEach","value","disabled","push","result"],"mappings":"AAAA,SAASA,QAAQ,EAAkBC,cAAc,QAAQ,QAAQ;AAcjE;;;CAGC,GACD,SAASC,qBAAqBC,QAAmB;IAC/C,IAAI,CAACA,UAAU;QACb,OAAO;IACT;IAEA,IAAI,OAAOA,aAAa,YAAY,OAAOA,aAAa,UAAU;QAChE,OAAO,GAAGA,UAAU;IACtB;IAEA,IAAIF,eAA0DE,WAAW;QACvE,IAAIA,SAASC,KAAK,CAACC,MAAM,EAAE;YACzB,OAAO;QACT;QAEA,OAAOH,qBAAqBC,SAASC,KAAK,CAACD,QAAQ;IACrD;IAEA,MAAMG,YAAYN,SAASO,OAAO,CAACJ;IACnC,KAAK,MAAMK,SAASF,UAAW;QAC7B,IAAI,OAAOE,UAAU,YAAY,OAAOA,UAAU,UAAU;YAC1D,OAAO,GAAGA,OAAO,CAAC,EAAE,CAACC,WAAW;QAClC;QAEA,IACER,eAA0DO,UAC1D,CAACA,MAAMJ,KAAK,CAACC,MAAM,EACnB;YACA,OAAOH,qBAAqBM,MAAMJ,KAAK,CAACD,QAAQ;QAClD;IACF;IAEA,OAAO;AACT;AAWA;;;CAGC,GACD,OAAO,SAASO,2BACdP,QAAmB,EACnBQ,YAA+B;IAE/B,IAAIC;IAEJ,MAAMC,UAAmB,EAAE;IAC3B,MAAMC,eAAyB,EAAE;IACjCd,SAASe,OAAO,CAACZ,UAAU,CAACK;QAC1B,IAAI,CAACP,eAAoCO,QAAQ;YAC/C;QACF;QAEA,MAAM,EAAEQ,KAAK,EAAEC,QAAQ,EAAEd,QAAQ,EAAE,GAAGK,MAAMJ,KAAK;QACjD,IAAI,OAAOY,UAAU,aAAa;YAChC,IACEA,UAAUL,gBACT,CAACC,iBAAiB,OAAOD,iBAAiB,aAC3C;gBACAC,gBAAgBJ,MAAMJ,KAAK;YAC7B;YAEA,IAAI,CAACa,UAAU;gBACbJ,QAAQK,IAAI,CAACV,MAAMJ,KAAK,CAACY,KAAK;gBAC9BF,aAAaI,IAAI,CAAChB,qBAAqBC;YACzC;QACF,OAAO,IAAIA,UAAU;YACnB,MAAMgB,SAAST,2BAA2BP,UAAUQ;YACpD,IAAI,CAACC,eAAe;gBACjB,CAAA,EAAEA,aAAa,EAAE,GAAGO,MAAK;YAC5B;YAEAN,QAAQK,IAAI,IAAIC,OAAON,OAAO;QAChC;IACF;IAEA,OAAO;QACLA;QACAD;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/form/selectUtils.ts"],"sourcesContent":["import { Children, type ReactNode, isValidElement } from \"react\";\n\nimport { type MenuItemProps } from \"../menu/MenuItem.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface SelectOption<\n Value extends string | number = string,\n> extends MenuItemProps {\n value: Value;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nfunction getLabelFromChildren(children: ReactNode): string {\n if (!children) {\n return \"\";\n }\n\n if (typeof children === \"string\" || typeof children === \"number\") {\n return `${children}`;\n }\n\n if (isValidElement<{ children: ReactNode; hidden?: boolean }>(children)) {\n if (children.props.hidden) {\n return \"\";\n }\n\n return getLabelFromChildren(children.props.children);\n }\n\n const childList = Children.toArray(children);\n for (const child of childList) {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return `${child}`[0].toUpperCase();\n }\n\n if (\n isValidElement<{ children: ReactNode; hidden?: boolean }>(child) &&\n !child.props.hidden\n ) {\n return getLabelFromChildren(child.props.children);\n }\n }\n\n return \"\";\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\ninterface ExtractedOptions<Value extends string | number> {\n options: readonly Value[];\n currentOption: SelectOption<Value> | undefined;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function extractOptionsFromChildren<Value extends string | number>(\n children: ReactNode,\n currentValue: Value | undefined\n): ExtractedOptions<Value> {\n let currentOption: SelectOption<Value> | undefined;\n\n const options: Value[] = [];\n const searchValues: string[] = [];\n Children.forEach(children, (child) => {\n if (!isValidElement<SelectOption<Value>>(child)) {\n return;\n }\n\n const { value, disabled, children } = child.props;\n if (value !== undefined) {\n if (\n value === currentValue ||\n (!currentOption && currentValue === undefined)\n ) {\n currentOption = child.props;\n }\n\n if (!disabled) {\n options.push(child.props.value);\n searchValues.push(getLabelFromChildren(children));\n }\n } else if (children) {\n const result = extractOptionsFromChildren(children, currentValue);\n if (!currentOption) {\n ({ currentOption } = result);\n }\n\n options.push(...result.options);\n }\n });\n\n return {\n options,\n currentOption,\n };\n}\n"],"names":["Children","isValidElement","getLabelFromChildren","children","props","hidden","childList","toArray","child","toUpperCase","extractOptionsFromChildren","currentValue","currentOption","options","searchValues","forEach","value","disabled","undefined","push","result"],"mappings":"AAAA,SAASA,QAAQ,EAAkBC,cAAc,QAAQ,QAAQ;AAcjE;;;CAGC,GACD,SAASC,qBAAqBC,QAAmB;IAC/C,IAAI,CAACA,UAAU;QACb,OAAO;IACT;IAEA,IAAI,OAAOA,aAAa,YAAY,OAAOA,aAAa,UAAU;QAChE,OAAO,GAAGA,UAAU;IACtB;IAEA,IAAIF,eAA0DE,WAAW;QACvE,IAAIA,SAASC,KAAK,CAACC,MAAM,EAAE;YACzB,OAAO;QACT;QAEA,OAAOH,qBAAqBC,SAASC,KAAK,CAACD,QAAQ;IACrD;IAEA,MAAMG,YAAYN,SAASO,OAAO,CAACJ;IACnC,KAAK,MAAMK,SAASF,UAAW;QAC7B,IAAI,OAAOE,UAAU,YAAY,OAAOA,UAAU,UAAU;YAC1D,OAAO,GAAGA,OAAO,CAAC,EAAE,CAACC,WAAW;QAClC;QAEA,IACER,eAA0DO,UAC1D,CAACA,MAAMJ,KAAK,CAACC,MAAM,EACnB;YACA,OAAOH,qBAAqBM,MAAMJ,KAAK,CAACD,QAAQ;QAClD;IACF;IAEA,OAAO;AACT;AAWA;;;CAGC,GACD,OAAO,SAASO,2BACdP,QAAmB,EACnBQ,YAA+B;IAE/B,IAAIC;IAEJ,MAAMC,UAAmB,EAAE;IAC3B,MAAMC,eAAyB,EAAE;IACjCd,SAASe,OAAO,CAACZ,UAAU,CAACK;QAC1B,IAAI,CAACP,eAAoCO,QAAQ;YAC/C;QACF;QAEA,MAAM,EAAEQ,KAAK,EAAEC,QAAQ,EAAEd,QAAQ,EAAE,GAAGK,MAAMJ,KAAK;QACjD,IAAIY,UAAUE,WAAW;YACvB,IACEF,UAAUL,gBACT,CAACC,iBAAiBD,iBAAiBO,WACpC;gBACAN,gBAAgBJ,MAAMJ,KAAK;YAC7B;YAEA,IAAI,CAACa,UAAU;gBACbJ,QAAQM,IAAI,CAACX,MAAMJ,KAAK,CAACY,KAAK;gBAC9BF,aAAaK,IAAI,CAACjB,qBAAqBC;YACzC;QACF,OAAO,IAAIA,UAAU;YACnB,MAAMiB,SAASV,2BAA2BP,UAAUQ;YACpD,IAAI,CAACC,eAAe;gBACjB,CAAA,EAAEA,aAAa,EAAE,GAAGQ,MAAK;YAC5B;YAEAP,QAAQM,IAAI,IAAIC,OAAOP,OAAO;QAChC;IACF;IAEA,OAAO;QACLA;QACAD;IACF;AACF"}
@@ -145,6 +145,7 @@ const noop = ()=>{
145
145
  // to really make sure the item is in view. An alternative would be to
146
146
  // implement a custom scrollIntoView behavior again like the previous
147
147
  // versions of react-md, but this is less lines of code
148
+ // eslint-disable-next-line unicorn/consistent-function-scoping
148
149
  const attemptScroll = ()=>{
149
150
  const activeOption = document.getElementById(activeDescendantId);
150
151
  if (activeOption) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/useCombobox.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type FocusEventHandler,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type InputHTMLAttributes,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useRef,\n} from \"react\";\n\nimport { type MenuProps } from \"../menu/Menu.js\";\nimport { type MenuSheetConfigurableProps } from \"../menu/MenuSheet.js\";\nimport {\n type GetDefaultFocusedIndex,\n type GetFocusableElements,\n type KeyboardMovementExtensionData,\n type KeyboardMovementProviderImplementation,\n type KeyboardMovementProviderOptions,\n} from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { BELOW_CENTER_ANCHOR } from \"../positioning/constants.js\";\nimport {\n type PositionAnchor,\n type PositionWidth,\n} from \"../positioning/types.js\";\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport {\n type NonNullMutableRef,\n type UseStateInitializer,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useEnsuredState } from \"../useEnsuredState.js\";\nimport { tryToSubmitRelatedForm } from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport const getNonDisabledOptions = (\n container: HTMLElement\n): readonly HTMLElement[] => [\n ...container.querySelectorAll<HTMLLIElement>(\n '[role=\"option\"]:not([aria-disabled])'\n ),\n];\n\n/**\n * @since 6.0.0\n */\nexport type SupportedComboboxPopup = \"listbox\" | \"grid\" | \"dialog\";\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxKeyboardMovementData<\n E extends HTMLElement = HTMLInputElement,\n> extends KeyboardMovementExtensionData<E> {\n show: () => void;\n hide: () => void;\n visible: boolean;\n\n /**\n * @since 6.3.0 Renamed from `focusLast` to `focusLastRef` to support the new\n * actions.\n */\n focusLastRef: NonNullMutableRef<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type ExtendComboboxKeyDown<E extends HTMLElement = HTMLInputElement> = (\n movementData: ComboboxKeyboardMovementData<E>\n) => void;\n\n/**\n * @since 6.0.0\n */\nexport type ComboboxKeyboardMovementOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n> = Pick<\n KeyboardMovementProviderOptions<ComboboxEl>,\n | \"onClick\"\n | \"onFocus\"\n | \"onKeyDown\"\n | \"disabled\"\n | \"loopable\"\n | \"searchable\"\n | \"onFocusChange\"\n | \"isNegativeOneAllowed\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxVisibilityOptions {\n /**\n * This can be used to control the popup's visibility and **must** be used\n * along with {@link setVisible}.\n */\n visible?: boolean;\n\n /**\n * Used to control the popup's visibility and should generally be a `useState`\n * setter.\n *\n * @example Controlling the Visibility\n * ```tsx\n * const [visible, setVisible] = useState(false);\n *\n * useCombobox({\n * visible,\n * setVisible,\n * });\n * ```\n */\n setVisible?: UseStateSetter<boolean>;\n\n /**\n * Set this to `true` to have the combobox's popup visible by default.\n *\n * @defaultValue `false`\n */\n defaultVisible?: UseStateInitializer<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableComboboxOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n>\n extends\n ComboboxKeyboardMovementOptions<ComboboxEl>,\n ComboboxVisibilityOptions {\n /**\n * This is the {@link InputHTMLAttributes.form} attribute and is used to\n * attempt submitting a form when the enter key is pressed.\n */\n form?: string;\n\n /**\n * @defaultValue `\"combobox-popup-\" + useId()`\n */\n popupId?: string;\n popupRef?: Ref<PopupEl>;\n\n /**\n * @defaultValue `\"combobox-\" + useId()`\n */\n comboboxId?: string;\n comboboxRef?: Ref<ComboboxEl>;\n\n /**\n * @defaultValue `\"listbox\"`\n */\n popup?: \"listbox\" | \"grid\" | \"dialog\";\n\n /**\n * @defaultValue `false`\n */\n multiselect?: boolean;\n\n extendKeyDown?: ExtendComboboxKeyDown<ComboboxEl>;\n\n /**\n * @defaultValue {@link getNonDisabledOptions}\n */\n getFocusableElements?: GetFocusableElements;\n\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxGetEnterDefaultFocusedIndexOptions {\n focusLast: boolean;\n focusables: readonly HTMLElement[];\n currentFocusIndex: number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n> extends ConfigurableComboboxOptions<ComboboxEl, PopupEl> {\n getEnterDefaultFocusedIndex: (\n options: ComboboxGetEnterDefaultFocusedIndexOptions\n ) => number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxWidgetProps<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n> {\n \"aria-controls\": string;\n \"aria-disabled\": true | undefined;\n \"aria-expanded\": boolean;\n \"aria-haspopup\": SupportedComboboxPopup;\n id: string;\n ref: RefCallback<ComboboxEl>;\n role: \"combobox\";\n onClick: MouseEventHandler<ComboboxEl>;\n onFocus: FocusEventHandler<ComboboxEl>;\n onKeyDown: KeyboardEventHandler<ComboboxEl>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxWidgetPopupProps<\n PopupEl extends HTMLElement = HTMLElement,\n> {\n \"aria-multiselectable\": true | undefined;\n id: string;\n ref: RefCallback<PopupEl>;\n role: \"listbox\" | \"dialog\" | \"grid\";\n}\n\n/**\n * @since 6.0.0\n */\nexport type ComboboxTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEntering\" | \"onEntered\" | \"onExiting\" | \"onExited\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxTransitionOptions extends ComboboxTransitionCallbacks {\n disableTransition?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport type ConfigurableComboboxMenuProps = Partial<\n Omit<MenuProps, \"visible\" | \"onRequestClose\" | keyof ComboboxWidgetPopupProps>\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedComboboxMenuProps<\n PopupEl extends HTMLElement = HTMLDivElement,\n>\n extends\n Required<ComboboxTransitionCallbacks>,\n ComboboxWidgetPopupProps<PopupEl> {\n visible: boolean;\n onRequestClose: () => void;\n /** @defaultValue `\"min\"` */\n width: PositionWidth;\n /** @defaultValue `BELOW_CENTER_ANCHOR` */\n anchor: PositionAnchor;\n fixedTo: RefObject<HTMLElement>;\n sheetProps: MenuSheetConfigurableProps &\n Required<ComboboxTransitionCallbacks>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxMenuProps<PopupEl extends HTMLElement = HTMLDivElement>\n extends\n Omit<ConfigurableComboboxMenuProps, keyof ProvidedComboboxMenuProps>,\n ProvidedComboboxMenuProps<PopupEl> {}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxImplementation<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n> extends Omit<KeyboardMovementProviderImplementation<ComboboxEl>, \"nodeRef\"> {\n show: () => void;\n hide: () => void;\n visible: boolean;\n setVisible: UseStateSetter<boolean>;\n focusLast: NonNullMutableRef<boolean>;\n popupRef: RefObject<PopupEl>;\n popupProps: ComboboxWidgetPopupProps<PopupEl>;\n comboboxRef: RefObject<ComboboxEl>;\n comboboxProps: ComboboxWidgetProps<ComboboxEl>;\n /**\n * Since the combobox usually uses the `Menu` as a popup element, this is a\n * helper util to create the required props and merge any additional props\n * with reasonable defaults.\n */\n getMenuProps: (\n overrides?: ConfigurableComboboxMenuProps\n ) => ComboboxMenuProps<PopupEl>;\n}\n\n/**\n * @since 6.0.0\n */\nexport function useCombobox<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n>(\n options: ComboboxOptions<ComboboxEl, PopupEl>\n): ComboboxImplementation<ComboboxEl, PopupEl> {\n const {\n form,\n popup = \"listbox\",\n onClick = noop,\n onFocus,\n onKeyDown,\n searchable,\n multiselect,\n isNegativeOneAllowed,\n loopable,\n disabled,\n visible: propVisible,\n setVisible: propSetVisible,\n defaultVisible = false,\n comboboxId: propComboboxId,\n comboboxRef: propComboboxRef,\n popupId: propPopupId,\n popupRef: propPopupRef,\n onFocusChange = noop,\n extendKeyDown = noop,\n getFocusableElements = getNonDisabledOptions,\n getEnterDefaultFocusedIndex,\n getDefaultFocusedIndex,\n } = options;\n\n const [visible, setVisible] = useEnsuredState({\n name: \"visible\",\n value: propVisible,\n setValue: propSetVisible,\n defaultValue: defaultVisible,\n });\n const show = useCallback(() => {\n setVisible(true);\n }, [setVisible]);\n const hide = useCallback(() => {\n setVisible(false);\n }, [setVisible]);\n\n const popupId = useEnsuredId(propPopupId, \"combobox-popup\");\n const comboboxId = useEnsuredId(propComboboxId, \"combobox\");\n const [popupRef, popupRefCallback] = useEnsuredRef(propPopupRef);\n const focusLastRef = useRef(false);\n const {\n nodeRef: comboboxRef,\n movementProps,\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n } = useKeyboardMovementProvider<ComboboxEl>({\n ref: propComboboxRef,\n onFocus,\n onKeyDown,\n onClick(event) {\n onClick(event);\n if (disabled) {\n return;\n }\n\n show();\n },\n extendKeyDown(movementData) {\n extendKeyDown({\n ...movementData,\n show,\n hide,\n visible,\n focusLastRef,\n });\n const { event } = movementData;\n if (event.isPropagationStopped()) {\n return;\n }\n\n if (visible) {\n switch (event.key) {\n case \"Tab\":\n // do not stop propagation for tab so that shift+tab works correctly in dialogs\n hide();\n break;\n case \"Escape\":\n event.stopPropagation();\n hide();\n break;\n case \"Enter\":\n event.preventDefault();\n break;\n }\n\n // while visible, always use the default keyboard movement behavior\n return;\n }\n\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowDown\":\n event.preventDefault();\n event.stopPropagation();\n focusLastRef.current = event.key === \"ArrowUp\";\n show();\n break;\n case \"Enter\":\n tryToSubmitRelatedForm(event, form);\n break;\n }\n },\n disabled,\n loopable,\n searchable,\n onFocusChange,\n programmatic: true,\n includeDisabled: false,\n tabIndexBehavior: \"virtual\",\n getFocusableElements(container, programmatic) {\n const popup = popupRef.current;\n if (!popup) {\n return [];\n }\n\n return getFocusableElements(popup || container, programmatic);\n },\n isNegativeOneAllowed,\n getDefaultFocusedIndex,\n });\n\n const popupProps: ComboboxWidgetPopupProps<PopupEl> = {\n \"aria-multiselectable\": multiselect || undefined,\n id: popupId,\n ref: popupRefCallback,\n role: popup,\n };\n\n return {\n show,\n hide,\n visible,\n setVisible,\n focusLast: focusLastRef,\n popupRef,\n popupProps,\n comboboxRef,\n comboboxProps: {\n ...movementProps,\n \"aria-controls\": popupId,\n \"aria-disabled\": disabled || undefined,\n \"aria-expanded\": visible,\n \"aria-haspopup\": popup,\n id: comboboxId,\n role: \"combobox\",\n },\n movementProps,\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n getMenuProps(props = {}) {\n const {\n sheetProps,\n disableTransition,\n onEnter,\n onEntering,\n onEntered = noop,\n onExited,\n onExiting,\n onExit,\n } = props;\n\n // Chrome does not trigger the scrollIntoView behavior correctly while\n // using a scale transition, so need to trigger this on the entered flow\n // to really make sure the item is in view. An alternative would be to\n // implement a custom scrollIntoView behavior again like the previous\n // versions of react-md, but this is less lines of code\n const attemptScroll = (): void => {\n const activeOption = document.getElementById(activeDescendantId);\n if (activeOption) {\n activeOption.scrollIntoView({ block: \"nearest\" });\n }\n };\n const onEnterOnce = (): void => {\n const popup = popupRef.current;\n if (!popup) {\n attemptScroll();\n return;\n }\n\n const focusables = getFocusableElements(popup, true);\n const index = getEnterDefaultFocusedIndex({\n focusLast: focusLastRef.current,\n focusables,\n currentFocusIndex: currentFocusIndex.current,\n });\n focusLastRef.current = false;\n currentFocusIndex.current = index;\n\n const option = focusables[index];\n if (!option) {\n return;\n }\n\n onFocusChange({\n index,\n element: option,\n });\n\n option.scrollIntoView({ block: \"nearest\" });\n setActiveDescendantId(option.id || \"\");\n };\n\n return {\n anchor: BELOW_CENTER_ANCHOR,\n width: \"min\",\n fixedTo: comboboxRef,\n ...props,\n ...popupProps,\n visible,\n onRequestClose: hide,\n ...getTransitionCallbacks({\n disableTransition,\n onEnter,\n onEntered: (appearing) => {\n onEntered(appearing);\n attemptScroll();\n },\n onEntering,\n onEnterOnce,\n onExit,\n onExiting,\n onExited,\n onExitOnce: () => {\n // since the menu is unmounted or set to hidden while not visible, need\n // to clear the aria-activedescendant and current focus index when\n // hiding\n currentFocusIndex.current = -1;\n setActiveDescendantId(\"\");\n },\n }),\n sheetProps: {\n ...sheetProps,\n ...getTransitionCallbacks({\n ...sheetProps,\n onEnterOnce,\n disableTransition:\n sheetProps?.disableTransition ?? disableTransition,\n }),\n },\n };\n },\n };\n}\n"],"names":["useCallback","useRef","useKeyboardMovementProvider","BELOW_CENTER_ANCHOR","getTransitionCallbacks","useEnsuredId","useEnsuredRef","useEnsuredState","tryToSubmitRelatedForm","noop","getNonDisabledOptions","container","querySelectorAll","useCombobox","options","form","popup","onClick","onFocus","onKeyDown","searchable","multiselect","isNegativeOneAllowed","loopable","disabled","visible","propVisible","setVisible","propSetVisible","defaultVisible","comboboxId","propComboboxId","comboboxRef","propComboboxRef","popupId","propPopupId","popupRef","propPopupRef","onFocusChange","extendKeyDown","getFocusableElements","getEnterDefaultFocusedIndex","getDefaultFocusedIndex","name","value","setValue","defaultValue","show","hide","popupRefCallback","focusLastRef","nodeRef","movementProps","movementContext","currentFocusIndex","activeDescendantId","setActiveDescendantId","ref","event","movementData","isPropagationStopped","key","stopPropagation","preventDefault","current","programmatic","includeDisabled","tabIndexBehavior","popupProps","undefined","id","role","focusLast","comboboxProps","getMenuProps","props","sheetProps","disableTransition","onEnter","onEntering","onEntered","onExited","onExiting","onExit","attemptScroll","activeOption","document","getElementById","scrollIntoView","block","onEnterOnce","focusables","index","option","element","anchor","width","fixedTo","onRequestClose","appearing","onExitOnce"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/form/useCombobox.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type FocusEventHandler,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type InputHTMLAttributes,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useRef,\n} from \"react\";\n\nimport { type MenuProps } from \"../menu/Menu.js\";\nimport { type MenuSheetConfigurableProps } from \"../menu/MenuSheet.js\";\nimport {\n type GetDefaultFocusedIndex,\n type GetFocusableElements,\n type KeyboardMovementExtensionData,\n type KeyboardMovementProviderImplementation,\n type KeyboardMovementProviderOptions,\n} from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { BELOW_CENTER_ANCHOR } from \"../positioning/constants.js\";\nimport {\n type PositionAnchor,\n type PositionWidth,\n} from \"../positioning/types.js\";\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport {\n type NonNullMutableRef,\n type UseStateInitializer,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useEnsuredState } from \"../useEnsuredState.js\";\nimport { tryToSubmitRelatedForm } from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport const getNonDisabledOptions = (\n container: HTMLElement\n): readonly HTMLElement[] => [\n ...container.querySelectorAll<HTMLLIElement>(\n '[role=\"option\"]:not([aria-disabled])'\n ),\n];\n\n/**\n * @since 6.0.0\n */\nexport type SupportedComboboxPopup = \"listbox\" | \"grid\" | \"dialog\";\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxKeyboardMovementData<\n E extends HTMLElement = HTMLInputElement,\n> extends KeyboardMovementExtensionData<E> {\n show: () => void;\n hide: () => void;\n visible: boolean;\n\n /**\n * @since 6.3.0 Renamed from `focusLast` to `focusLastRef` to support the new\n * actions.\n */\n focusLastRef: NonNullMutableRef<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type ExtendComboboxKeyDown<E extends HTMLElement = HTMLInputElement> = (\n movementData: ComboboxKeyboardMovementData<E>\n) => void;\n\n/**\n * @since 6.0.0\n */\nexport type ComboboxKeyboardMovementOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n> = Pick<\n KeyboardMovementProviderOptions<ComboboxEl>,\n | \"onClick\"\n | \"onFocus\"\n | \"onKeyDown\"\n | \"disabled\"\n | \"loopable\"\n | \"searchable\"\n | \"onFocusChange\"\n | \"isNegativeOneAllowed\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxVisibilityOptions {\n /**\n * This can be used to control the popup's visibility and **must** be used\n * along with {@link setVisible}.\n */\n visible?: boolean;\n\n /**\n * Used to control the popup's visibility and should generally be a `useState`\n * setter.\n *\n * @example Controlling the Visibility\n * ```tsx\n * const [visible, setVisible] = useState(false);\n *\n * useCombobox({\n * visible,\n * setVisible,\n * });\n * ```\n */\n setVisible?: UseStateSetter<boolean>;\n\n /**\n * Set this to `true` to have the combobox's popup visible by default.\n *\n * @defaultValue `false`\n */\n defaultVisible?: UseStateInitializer<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableComboboxOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n>\n extends\n ComboboxKeyboardMovementOptions<ComboboxEl>,\n ComboboxVisibilityOptions {\n /**\n * This is the {@link InputHTMLAttributes.form} attribute and is used to\n * attempt submitting a form when the enter key is pressed.\n */\n form?: string;\n\n /**\n * @defaultValue `\"combobox-popup-\" + useId()`\n */\n popupId?: string;\n popupRef?: Ref<PopupEl>;\n\n /**\n * @defaultValue `\"combobox-\" + useId()`\n */\n comboboxId?: string;\n comboboxRef?: Ref<ComboboxEl>;\n\n /**\n * @defaultValue `\"listbox\"`\n */\n popup?: \"listbox\" | \"grid\" | \"dialog\";\n\n /**\n * @defaultValue `false`\n */\n multiselect?: boolean;\n\n extendKeyDown?: ExtendComboboxKeyDown<ComboboxEl>;\n\n /**\n * @defaultValue {@link getNonDisabledOptions}\n */\n getFocusableElements?: GetFocusableElements;\n\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxGetEnterDefaultFocusedIndexOptions {\n focusLast: boolean;\n focusables: readonly HTMLElement[];\n currentFocusIndex: number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxOptions<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n> extends ConfigurableComboboxOptions<ComboboxEl, PopupEl> {\n getEnterDefaultFocusedIndex: (\n options: ComboboxGetEnterDefaultFocusedIndexOptions\n ) => number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxWidgetProps<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n> {\n \"aria-controls\": string;\n \"aria-disabled\": true | undefined;\n \"aria-expanded\": boolean;\n \"aria-haspopup\": SupportedComboboxPopup;\n id: string;\n ref: RefCallback<ComboboxEl>;\n role: \"combobox\";\n onClick: MouseEventHandler<ComboboxEl>;\n onFocus: FocusEventHandler<ComboboxEl>;\n onKeyDown: KeyboardEventHandler<ComboboxEl>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxWidgetPopupProps<\n PopupEl extends HTMLElement = HTMLElement,\n> {\n \"aria-multiselectable\": true | undefined;\n id: string;\n ref: RefCallback<PopupEl>;\n role: \"listbox\" | \"dialog\" | \"grid\";\n}\n\n/**\n * @since 6.0.0\n */\nexport type ComboboxTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEntering\" | \"onEntered\" | \"onExiting\" | \"onExited\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxTransitionOptions extends ComboboxTransitionCallbacks {\n disableTransition?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport type ConfigurableComboboxMenuProps = Partial<\n Omit<MenuProps, \"visible\" | \"onRequestClose\" | keyof ComboboxWidgetPopupProps>\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedComboboxMenuProps<\n PopupEl extends HTMLElement = HTMLDivElement,\n>\n extends\n Required<ComboboxTransitionCallbacks>,\n ComboboxWidgetPopupProps<PopupEl> {\n visible: boolean;\n onRequestClose: () => void;\n /** @defaultValue `\"min\"` */\n width: PositionWidth;\n /** @defaultValue `BELOW_CENTER_ANCHOR` */\n anchor: PositionAnchor;\n fixedTo: RefObject<HTMLElement>;\n sheetProps: MenuSheetConfigurableProps &\n Required<ComboboxTransitionCallbacks>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxMenuProps<PopupEl extends HTMLElement = HTMLDivElement>\n extends\n Omit<ConfigurableComboboxMenuProps, keyof ProvidedComboboxMenuProps>,\n ProvidedComboboxMenuProps<PopupEl> {}\n\n/**\n * @since 6.0.0\n */\nexport interface ComboboxImplementation<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n> extends Omit<KeyboardMovementProviderImplementation<ComboboxEl>, \"nodeRef\"> {\n show: () => void;\n hide: () => void;\n visible: boolean;\n setVisible: UseStateSetter<boolean>;\n focusLast: NonNullMutableRef<boolean>;\n popupRef: RefObject<PopupEl>;\n popupProps: ComboboxWidgetPopupProps<PopupEl>;\n comboboxRef: RefObject<ComboboxEl>;\n comboboxProps: ComboboxWidgetProps<ComboboxEl>;\n /**\n * Since the combobox usually uses the `Menu` as a popup element, this is a\n * helper util to create the required props and merge any additional props\n * with reasonable defaults.\n */\n getMenuProps: (\n overrides?: ConfigurableComboboxMenuProps\n ) => ComboboxMenuProps<PopupEl>;\n}\n\n/**\n * @since 6.0.0\n */\nexport function useCombobox<\n ComboboxEl extends HTMLElement = HTMLInputElement,\n PopupEl extends HTMLElement = HTMLElement,\n>(\n options: ComboboxOptions<ComboboxEl, PopupEl>\n): ComboboxImplementation<ComboboxEl, PopupEl> {\n const {\n form,\n popup = \"listbox\",\n onClick = noop,\n onFocus,\n onKeyDown,\n searchable,\n multiselect,\n isNegativeOneAllowed,\n loopable,\n disabled,\n visible: propVisible,\n setVisible: propSetVisible,\n defaultVisible = false,\n comboboxId: propComboboxId,\n comboboxRef: propComboboxRef,\n popupId: propPopupId,\n popupRef: propPopupRef,\n onFocusChange = noop,\n extendKeyDown = noop,\n getFocusableElements = getNonDisabledOptions,\n getEnterDefaultFocusedIndex,\n getDefaultFocusedIndex,\n } = options;\n\n const [visible, setVisible] = useEnsuredState({\n name: \"visible\",\n value: propVisible,\n setValue: propSetVisible,\n defaultValue: defaultVisible,\n });\n const show = useCallback(() => {\n setVisible(true);\n }, [setVisible]);\n const hide = useCallback(() => {\n setVisible(false);\n }, [setVisible]);\n\n const popupId = useEnsuredId(propPopupId, \"combobox-popup\");\n const comboboxId = useEnsuredId(propComboboxId, \"combobox\");\n const [popupRef, popupRefCallback] = useEnsuredRef(propPopupRef);\n const focusLastRef = useRef(false);\n const {\n nodeRef: comboboxRef,\n movementProps,\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n } = useKeyboardMovementProvider<ComboboxEl>({\n ref: propComboboxRef,\n onFocus,\n onKeyDown,\n onClick(event) {\n onClick(event);\n if (disabled) {\n return;\n }\n\n show();\n },\n extendKeyDown(movementData) {\n extendKeyDown({\n ...movementData,\n show,\n hide,\n visible,\n focusLastRef,\n });\n const { event } = movementData;\n if (event.isPropagationStopped()) {\n return;\n }\n\n if (visible) {\n switch (event.key) {\n case \"Tab\":\n // do not stop propagation for tab so that shift+tab works correctly in dialogs\n hide();\n break;\n case \"Escape\":\n event.stopPropagation();\n hide();\n break;\n case \"Enter\":\n event.preventDefault();\n break;\n }\n\n // while visible, always use the default keyboard movement behavior\n return;\n }\n\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowDown\":\n event.preventDefault();\n event.stopPropagation();\n focusLastRef.current = event.key === \"ArrowUp\";\n show();\n break;\n case \"Enter\":\n tryToSubmitRelatedForm(event, form);\n break;\n }\n },\n disabled,\n loopable,\n searchable,\n onFocusChange,\n programmatic: true,\n includeDisabled: false,\n tabIndexBehavior: \"virtual\",\n getFocusableElements(container, programmatic) {\n const popup = popupRef.current;\n if (!popup) {\n return [];\n }\n\n return getFocusableElements(popup || container, programmatic);\n },\n isNegativeOneAllowed,\n getDefaultFocusedIndex,\n });\n\n const popupProps: ComboboxWidgetPopupProps<PopupEl> = {\n \"aria-multiselectable\": multiselect || undefined,\n id: popupId,\n ref: popupRefCallback,\n role: popup,\n };\n\n return {\n show,\n hide,\n visible,\n setVisible,\n focusLast: focusLastRef,\n popupRef,\n popupProps,\n comboboxRef,\n comboboxProps: {\n ...movementProps,\n \"aria-controls\": popupId,\n \"aria-disabled\": disabled || undefined,\n \"aria-expanded\": visible,\n \"aria-haspopup\": popup,\n id: comboboxId,\n role: \"combobox\",\n },\n movementProps,\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n getMenuProps(props = {}) {\n const {\n sheetProps,\n disableTransition,\n onEnter,\n onEntering,\n onEntered = noop,\n onExited,\n onExiting,\n onExit,\n } = props;\n\n // Chrome does not trigger the scrollIntoView behavior correctly while\n // using a scale transition, so need to trigger this on the entered flow\n // to really make sure the item is in view. An alternative would be to\n // implement a custom scrollIntoView behavior again like the previous\n // versions of react-md, but this is less lines of code\n // eslint-disable-next-line unicorn/consistent-function-scoping\n const attemptScroll = (): void => {\n const activeOption = document.getElementById(activeDescendantId);\n if (activeOption) {\n activeOption.scrollIntoView({ block: \"nearest\" });\n }\n };\n const onEnterOnce = (): void => {\n const popup = popupRef.current;\n if (!popup) {\n attemptScroll();\n return;\n }\n\n const focusables = getFocusableElements(popup, true);\n const index = getEnterDefaultFocusedIndex({\n focusLast: focusLastRef.current,\n focusables,\n currentFocusIndex: currentFocusIndex.current,\n });\n focusLastRef.current = false;\n currentFocusIndex.current = index;\n\n const option = focusables[index];\n if (!option) {\n return;\n }\n\n onFocusChange({\n index,\n element: option,\n });\n\n option.scrollIntoView({ block: \"nearest\" });\n setActiveDescendantId(option.id || \"\");\n };\n\n return {\n anchor: BELOW_CENTER_ANCHOR,\n width: \"min\",\n fixedTo: comboboxRef,\n ...props,\n ...popupProps,\n visible,\n onRequestClose: hide,\n ...getTransitionCallbacks({\n disableTransition,\n onEnter,\n onEntered: (appearing) => {\n onEntered(appearing);\n attemptScroll();\n },\n onEntering,\n onEnterOnce,\n onExit,\n onExiting,\n onExited,\n onExitOnce: () => {\n // since the menu is unmounted or set to hidden while not visible, need\n // to clear the aria-activedescendant and current focus index when\n // hiding\n currentFocusIndex.current = -1;\n setActiveDescendantId(\"\");\n },\n }),\n sheetProps: {\n ...sheetProps,\n ...getTransitionCallbacks({\n ...sheetProps,\n onEnterOnce,\n disableTransition:\n sheetProps?.disableTransition ?? disableTransition,\n }),\n },\n };\n },\n };\n}\n"],"names":["useCallback","useRef","useKeyboardMovementProvider","BELOW_CENTER_ANCHOR","getTransitionCallbacks","useEnsuredId","useEnsuredRef","useEnsuredState","tryToSubmitRelatedForm","noop","getNonDisabledOptions","container","querySelectorAll","useCombobox","options","form","popup","onClick","onFocus","onKeyDown","searchable","multiselect","isNegativeOneAllowed","loopable","disabled","visible","propVisible","setVisible","propSetVisible","defaultVisible","comboboxId","propComboboxId","comboboxRef","propComboboxRef","popupId","propPopupId","popupRef","propPopupRef","onFocusChange","extendKeyDown","getFocusableElements","getEnterDefaultFocusedIndex","getDefaultFocusedIndex","name","value","setValue","defaultValue","show","hide","popupRefCallback","focusLastRef","nodeRef","movementProps","movementContext","currentFocusIndex","activeDescendantId","setActiveDescendantId","ref","event","movementData","isPropagationStopped","key","stopPropagation","preventDefault","current","programmatic","includeDisabled","tabIndexBehavior","popupProps","undefined","id","role","focusLast","comboboxProps","getMenuProps","props","sheetProps","disableTransition","onEnter","onEntering","onEntered","onExited","onExiting","onExit","attemptScroll","activeOption","document","getElementById","scrollIntoView","block","onEnterOnce","focusables","index","option","element","anchor","width","fixedTo","onRequestClose","appearing","onExitOnce"],"mappings":"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"}