@react-md/core 6.5.0 → 6.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/dist/_utils.scss +2 -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
@@ -21,10 +21,10 @@ import { randomSkeletonPlaceholder, skeletonPlaceholder } from "./skeletonPlaceh
21
21
  */ export function useSkeletonPlaceholder(options = {}) {
22
22
  const { style: propStyle, className, height, width: propWidth, disabled = false, delay: propDelay, minDelay, maxDelay, minPercentage, maxPercentage } = options;
23
23
  const ssr = useSsr();
24
- const isDefinedWidth = typeof propWidth !== "undefined";
25
- const isDefinedDelay = typeof propDelay !== "undefined";
24
+ const isDefinedWidth = propWidth !== undefined;
25
+ const isDefinedDelay = propDelay !== undefined;
26
26
  const [randomStyles, setRandomStyles] = useState(()=>{
27
- if (typeof window === "undefined" || ssr || disabled) {
27
+ if (globalThis.window === undefined || ssr || disabled) {
28
28
  return {};
29
29
  }
30
30
  return randomSkeletonPlaceholder({
@@ -65,7 +65,7 @@ import { randomSkeletonPlaceholder, skeletonPlaceholder } from "./skeletonPlaceh
65
65
  }
66
66
  }
67
67
  let style = propStyle;
68
- if (!!width || !!animationDelay || typeof height !== "undefined") {
68
+ if (!!width || !!animationDelay || height !== undefined) {
69
69
  style = {
70
70
  ...style,
71
71
  height: height ?? style?.height,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/transition/useSkeletonPlaceholder.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport { type CSSProperties, useEffect, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport {\n type SkeletonPlaceholderRandomOptions,\n randomSkeletonPlaceholder,\n skeletonPlaceholder,\n} from \"./skeletonPlaceholderUtils.js\";\n\n/** @since 6.0.0 */\nexport interface SkeletonPlaceholderOptions extends SkeletonPlaceholderRandomOptions {\n style?: CSSProperties;\n className?: string;\n\n /**\n * Set this to a custom `animation-delay` value (should be in milliseconds).\n *\n * @example\n * ```ts\n * delay=\"200ms\"\n * ```\n */\n delay?: string;\n\n /**\n * Set this value to a number or length unit string to set the height with\n * inline styles.\n *\n * If this is `undefined`, it will use the skeleton placeholder CSS variable\n * value instead which defaults to `1.125em`\n *\n * @defaultValue `undefined`\n */\n height?: string | number;\n\n /**\n * A custom width to apply to the skeleton placeholder.\n *\n * Set this value to an empty string if you want to control the width through\n * SCSS.\n *\n * @example No Inline Width CSS\n * ```scss\n * @use \"@react-md/core\";\n *\n * .customStyles {\n * // You could use these mixins on a parent element instead which would\n * // set the height and width to all skeleton placeholders that appear as a\n * // child instead\n * // @include core.transition-set-var(skeleton-placeholder-height, 1.5rem);\n * // @include core.transition-set-var(skeleton-placeholder-width, 40%);\n *\n * height: 1,5rem;\n * width: 40%;\n * }\n * ```\n *\n * @example No Inline Width\n * ```ts\n * import type { ReactElement } from \"@react\";\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * import styles from \"./MyComponent.module.scss\";\n *\n * export function Example(): ReactElement {\n * const skeletonProps = useSkeletonPlaceholder({\n * width: null,\n * className: styles.customStyles,\n * });\n *\n * return <div {...skeletonProps} />;\n * }\n * ```\n *\n *\n * Set this value to a number or length unit string to set the width with\n * inline styles.\n *\n * @example Custom Inline Width\n * ```ts\n * import type { ReactElement } from \"@react\";\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * export function Example(): ReactElement {\n * const skeletonProps = useSkeletonPlaceholder({\n * // any of these are valid\n * // width: 40,\n * // width: \"1rem\",\n * // width: \"1vh\",\n * // width: \"40%\",\n * width: \"1rem\",\n * });\n *\n * return <div {...skeletonProps} />;\n * }\n * ```\n *\n * If this value is `undefined`, a random percentage will be generated instead\n * using the {@link minPercentage} and {@link maxPercentage} options.\n *\n * Set this value to `null` if the size should be derived from the provided\n * `className` instead.\n *\n * @defaultValue `randomInt({ min: minPercentage, max: maxPercentage })%`\n */\n width?: number | string | null;\n\n /**\n * Settings this to `true` will prevent any of the skeleton placeholder styles\n * to be applied. This is really only useful if you can prerender parts of\n * your layout while waiting for the data to load.\n *\n * @example Pre-rendered Layout\n * ```tsx\n * import type { ReactElement } from \"@react\";\n * import { SkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * interface Data {\n * id: string;\n * name: string;\n * createdBy: string\n * createdOn: string;\n * modifiedBy: string;\n * modifiedOn: string;\n * }\n *\n * function ShowData({\n * id,\n * name,\n * createdBy,\n * createdOn,\n * modifiedBy,\n * modifiedOn,\n * }: Partial<Data>:: ReactElement {\n * const loading =\n * !name &&\n * !createdBy &&\n * !createdOn &&\n * !modifiedBy &&\n * !modifiedOn;\n *\n * return (\n * <Box grid gridClassName=\"custom-class-name\">\n * <SkeletonPlaceholder disabled={!loading}>\n * {id}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {name}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {createdOn}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {createdBy}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {modifiedOn}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {modifiedBy}\n * </SkeletonPlaceholder>\n * </Box>\n * );\n * }\n *\n * export function Example(): ReactElement {\n * const { data } = useLoadSomeDataQuery();\n *\n * const items = useMemo(() => {\n * // if the data has been fetched, just return the data\n * if (data) {\n * return data;\n * }\n *\n * // if the data does not exist, set up a skeleton of your layout by\n * // rendering a random number of items.\n * //\n * // NOTE: This is memoized so you don't create a random length each\n * // render\n * const length = randomInt({ min: 3, max: 10 })\n * return Array.from({ length }, (_, i) => ({ id: `placeholder-${i}` }));\n * }, [data])\n *\n * return (\n * <List>\n * {items.map((item) => <ShowData {...item} />)}\n * </List>\n * );\n * }\n * ```\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface SkeletonPlaceholderStylingProps {\n style?: CSSProperties;\n className: string;\n}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n * import { type ReactElement } from \"react\";\n *\n * export default function UsingTheHookExample(): ReactElement {\n * const { style, className } = useSkeletonPlaceholder();\n * return <div style={style} className={className} />;\n * }\n * ```\n *\n * @see {@link https://react-md.dev/hooks/use-skeleton-placeholder-transition | useSkeletonPlaceholder Demos}\n * @see {@link https://react-md.dev/components/skeleton-placeholder | SkeletonPlaceholder Demos}\n * @since 6.0.0\n */\nexport function useSkeletonPlaceholder(\n options: SkeletonPlaceholderOptions = {}\n): SkeletonPlaceholderStylingProps {\n const {\n style: propStyle,\n className,\n height,\n width: propWidth,\n disabled = false,\n delay: propDelay,\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n } = options;\n const ssr = useSsr();\n\n const isDefinedWidth = typeof propWidth !== \"undefined\";\n const isDefinedDelay = typeof propDelay !== \"undefined\";\n const [randomStyles, setRandomStyles] = useState<CSSProperties>(() => {\n if (typeof window === \"undefined\" || ssr || disabled) {\n return {};\n }\n\n return randomSkeletonPlaceholder({\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n });\n });\n\n useEffect(() => {\n if (!ssr || disabled || (isDefinedDelay && isDefinedWidth)) {\n return;\n }\n\n setRandomStyles(\n randomSkeletonPlaceholder({\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n })\n );\n }, [\n disabled,\n isDefinedDelay,\n isDefinedWidth,\n maxDelay,\n maxPercentage,\n minDelay,\n minPercentage,\n ssr,\n ]);\n\n let width = propWidth;\n let animationDelay = propDelay;\n if (!disabled) {\n if (!isDefinedDelay) {\n ({ animationDelay } = randomStyles);\n }\n if (!isDefinedWidth) {\n ({ width } = randomStyles);\n }\n }\n\n let style: CSSProperties | undefined = propStyle;\n if (!!width || !!animationDelay || typeof height !== \"undefined\") {\n style = {\n ...style,\n height: height ?? style?.height,\n width: width ?? style?.width,\n // Note: not including MozAnimationDelay and WebkitAnimationDelay since\n // they weren't applied when they were set. Probably no longer required?\n animationDelay: animationDelay ?? style?.animationDelay,\n };\n }\n\n return {\n style,\n className: cnb(className, !disabled && skeletonPlaceholder()),\n };\n}\n"],"names":["cnb","useEffect","useState","useSsr","randomSkeletonPlaceholder","skeletonPlaceholder","useSkeletonPlaceholder","options","style","propStyle","className","height","width","propWidth","disabled","delay","propDelay","minDelay","maxDelay","minPercentage","maxPercentage","ssr","isDefinedWidth","isDefinedDelay","randomStyles","setRandomStyles","window","animationDelay"],"mappings":"AAAA;AAEA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAA6BC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAEhE,SAASC,MAAM,QAAQ,oBAAoB;AAC3C,SAEEC,yBAAyB,EACzBC,mBAAmB,QACd,gCAAgC;AAqMvC;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,uBACdC,UAAsC,CAAC,CAAC;IAExC,MAAM,EACJC,OAAOC,SAAS,EAChBC,SAAS,EACTC,MAAM,EACNC,OAAOC,SAAS,EAChBC,WAAW,KAAK,EAChBC,OAAOC,SAAS,EAChBC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,aAAa,EACd,GAAGb;IACJ,MAAMc,MAAMlB;IAEZ,MAAMmB,iBAAiB,OAAOT,cAAc;IAC5C,MAAMU,iBAAiB,OAAOP,cAAc;IAC5C,MAAM,CAACQ,cAAcC,gBAAgB,GAAGvB,SAAwB;QAC9D,IAAI,OAAOwB,WAAW,eAAeL,OAAOP,UAAU;YACpD,OAAO,CAAC;QACV;QAEA,OAAOV,0BAA0B;YAC/Ba;YACAC;YACAC;YACAC;QACF;IACF;IAEAnB,UAAU;QACR,IAAI,CAACoB,OAAOP,YAAaS,kBAAkBD,gBAAiB;YAC1D;QACF;QAEAG,gBACErB,0BAA0B;YACxBa;YACAC;YACAC;YACAC;QACF;IAEJ,GAAG;QACDN;QACAS;QACAD;QACAJ;QACAE;QACAH;QACAE;QACAE;KACD;IAED,IAAIT,QAAQC;IACZ,IAAIc,iBAAiBX;IACrB,IAAI,CAACF,UAAU;QACb,IAAI,CAACS,gBAAgB;YAClB,CAAA,EAAEI,cAAc,EAAE,GAAGH,YAAW;QACnC;QACA,IAAI,CAACF,gBAAgB;YAClB,CAAA,EAAEV,KAAK,EAAE,GAAGY,YAAW;QAC1B;IACF;IAEA,IAAIhB,QAAmCC;IACvC,IAAI,CAAC,CAACG,SAAS,CAAC,CAACe,kBAAkB,OAAOhB,WAAW,aAAa;QAChEH,QAAQ;YACN,GAAGA,KAAK;YACRG,QAAQA,UAAUH,OAAOG;YACzBC,OAAOA,SAASJ,OAAOI;YACvB,uEAAuE;YACvE,wEAAwE;YACxEe,gBAAgBA,kBAAkBnB,OAAOmB;QAC3C;IACF;IAEA,OAAO;QACLnB;QACAE,WAAWV,IAAIU,WAAW,CAACI,YAAYT;IACzC;AACF"}
1
+ {"version":3,"sources":["../../src/transition/useSkeletonPlaceholder.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport { type CSSProperties, useEffect, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport {\n type SkeletonPlaceholderRandomOptions,\n randomSkeletonPlaceholder,\n skeletonPlaceholder,\n} from \"./skeletonPlaceholderUtils.js\";\n\n/** @since 6.0.0 */\nexport interface SkeletonPlaceholderOptions extends SkeletonPlaceholderRandomOptions {\n style?: CSSProperties;\n className?: string;\n\n /**\n * Set this to a custom `animation-delay` value (should be in milliseconds).\n *\n * @example\n * ```ts\n * delay=\"200ms\"\n * ```\n */\n delay?: string;\n\n /**\n * Set this value to a number or length unit string to set the height with\n * inline styles.\n *\n * If this is `undefined`, it will use the skeleton placeholder CSS variable\n * value instead which defaults to `1.125em`\n *\n * @defaultValue `undefined`\n */\n height?: string | number;\n\n /**\n * A custom width to apply to the skeleton placeholder.\n *\n * Set this value to an empty string if you want to control the width through\n * SCSS.\n *\n * @example No Inline Width CSS\n * ```scss\n * @use \"@react-md/core\";\n *\n * .customStyles {\n * // You could use these mixins on a parent element instead which would\n * // set the height and width to all skeleton placeholders that appear as a\n * // child instead\n * // @include core.transition-set-var(skeleton-placeholder-height, 1.5rem);\n * // @include core.transition-set-var(skeleton-placeholder-width, 40%);\n *\n * height: 1,5rem;\n * width: 40%;\n * }\n * ```\n *\n * @example No Inline Width\n * ```ts\n * import type { ReactElement } from \"@react\";\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * import styles from \"./MyComponent.module.scss\";\n *\n * export function Example(): ReactElement {\n * const skeletonProps = useSkeletonPlaceholder({\n * width: null,\n * className: styles.customStyles,\n * });\n *\n * return <div {...skeletonProps} />;\n * }\n * ```\n *\n *\n * Set this value to a number or length unit string to set the width with\n * inline styles.\n *\n * @example Custom Inline Width\n * ```ts\n * import type { ReactElement } from \"@react\";\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * export function Example(): ReactElement {\n * const skeletonProps = useSkeletonPlaceholder({\n * // any of these are valid\n * // width: 40,\n * // width: \"1rem\",\n * // width: \"1vh\",\n * // width: \"40%\",\n * width: \"1rem\",\n * });\n *\n * return <div {...skeletonProps} />;\n * }\n * ```\n *\n * If this value is `undefined`, a random percentage will be generated instead\n * using the {@link minPercentage} and {@link maxPercentage} options.\n *\n * Set this value to `null` if the size should be derived from the provided\n * `className` instead.\n *\n * @defaultValue `randomInt({ min: minPercentage, max: maxPercentage })%`\n */\n width?: number | string | null;\n\n /**\n * Settings this to `true` will prevent any of the skeleton placeholder styles\n * to be applied. This is really only useful if you can prerender parts of\n * your layout while waiting for the data to load.\n *\n * @example Pre-rendered Layout\n * ```tsx\n * import type { ReactElement } from \"@react\";\n * import { SkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n *\n * interface Data {\n * id: string;\n * name: string;\n * createdBy: string\n * createdOn: string;\n * modifiedBy: string;\n * modifiedOn: string;\n * }\n *\n * function ShowData({\n * id,\n * name,\n * createdBy,\n * createdOn,\n * modifiedBy,\n * modifiedOn,\n * }: Partial<Data>:: ReactElement {\n * const loading =\n * !name &&\n * !createdBy &&\n * !createdOn &&\n * !modifiedBy &&\n * !modifiedOn;\n *\n * return (\n * <Box grid gridClassName=\"custom-class-name\">\n * <SkeletonPlaceholder disabled={!loading}>\n * {id}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {name}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {createdOn}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {createdBy}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {modifiedOn}\n * </SkeletonPlaceholder>\n * <SkeletonPlaceholder disabled={!loading}>\n * {modifiedBy}\n * </SkeletonPlaceholder>\n * </Box>\n * );\n * }\n *\n * export function Example(): ReactElement {\n * const { data } = useLoadSomeDataQuery();\n *\n * const items = useMemo(() => {\n * // if the data has been fetched, just return the data\n * if (data) {\n * return data;\n * }\n *\n * // if the data does not exist, set up a skeleton of your layout by\n * // rendering a random number of items.\n * //\n * // NOTE: This is memoized so you don't create a random length each\n * // render\n * const length = randomInt({ min: 3, max: 10 })\n * return Array.from({ length }, (_, i) => ({ id: `placeholder-${i}` }));\n * }, [data])\n *\n * return (\n * <List>\n * {items.map((item) => <ShowData {...item} />)}\n * </List>\n * );\n * }\n * ```\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface SkeletonPlaceholderStylingProps {\n style?: CSSProperties;\n className: string;\n}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { useSkeletonPlaceholder } from \"@react-md/core/transition/useSkeletonPlaceholder\";\n * import { type ReactElement } from \"react\";\n *\n * export default function UsingTheHookExample(): ReactElement {\n * const { style, className } = useSkeletonPlaceholder();\n * return <div style={style} className={className} />;\n * }\n * ```\n *\n * @see {@link https://react-md.dev/hooks/use-skeleton-placeholder-transition | useSkeletonPlaceholder Demos}\n * @see {@link https://react-md.dev/components/skeleton-placeholder | SkeletonPlaceholder Demos}\n * @since 6.0.0\n */\nexport function useSkeletonPlaceholder(\n options: SkeletonPlaceholderOptions = {}\n): SkeletonPlaceholderStylingProps {\n const {\n style: propStyle,\n className,\n height,\n width: propWidth,\n disabled = false,\n delay: propDelay,\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n } = options;\n const ssr = useSsr();\n\n const isDefinedWidth = propWidth !== undefined;\n const isDefinedDelay = propDelay !== undefined;\n const [randomStyles, setRandomStyles] = useState<CSSProperties>(() => {\n if (globalThis.window === undefined || ssr || disabled) {\n return {};\n }\n\n return randomSkeletonPlaceholder({\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n });\n });\n\n useEffect(() => {\n if (!ssr || disabled || (isDefinedDelay && isDefinedWidth)) {\n return;\n }\n\n setRandomStyles(\n randomSkeletonPlaceholder({\n minDelay,\n maxDelay,\n minPercentage,\n maxPercentage,\n })\n );\n }, [\n disabled,\n isDefinedDelay,\n isDefinedWidth,\n maxDelay,\n maxPercentage,\n minDelay,\n minPercentage,\n ssr,\n ]);\n\n let width = propWidth;\n let animationDelay = propDelay;\n if (!disabled) {\n if (!isDefinedDelay) {\n ({ animationDelay } = randomStyles);\n }\n if (!isDefinedWidth) {\n ({ width } = randomStyles);\n }\n }\n\n let style: CSSProperties | undefined = propStyle;\n if (!!width || !!animationDelay || height !== undefined) {\n style = {\n ...style,\n height: height ?? style?.height,\n width: width ?? style?.width,\n // Note: not including MozAnimationDelay and WebkitAnimationDelay since\n // they weren't applied when they were set. Probably no longer required?\n animationDelay: animationDelay ?? style?.animationDelay,\n };\n }\n\n return {\n style,\n className: cnb(className, !disabled && skeletonPlaceholder()),\n };\n}\n"],"names":["cnb","useEffect","useState","useSsr","randomSkeletonPlaceholder","skeletonPlaceholder","useSkeletonPlaceholder","options","style","propStyle","className","height","width","propWidth","disabled","delay","propDelay","minDelay","maxDelay","minPercentage","maxPercentage","ssr","isDefinedWidth","undefined","isDefinedDelay","randomStyles","setRandomStyles","globalThis","window","animationDelay"],"mappings":"AAAA;AAEA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAA6BC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAEhE,SAASC,MAAM,QAAQ,oBAAoB;AAC3C,SAEEC,yBAAyB,EACzBC,mBAAmB,QACd,gCAAgC;AAqMvC;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,uBACdC,UAAsC,CAAC,CAAC;IAExC,MAAM,EACJC,OAAOC,SAAS,EAChBC,SAAS,EACTC,MAAM,EACNC,OAAOC,SAAS,EAChBC,WAAW,KAAK,EAChBC,OAAOC,SAAS,EAChBC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,aAAa,EACd,GAAGb;IACJ,MAAMc,MAAMlB;IAEZ,MAAMmB,iBAAiBT,cAAcU;IACrC,MAAMC,iBAAiBR,cAAcO;IACrC,MAAM,CAACE,cAAcC,gBAAgB,GAAGxB,SAAwB;QAC9D,IAAIyB,WAAWC,MAAM,KAAKL,aAAaF,OAAOP,UAAU;YACtD,OAAO,CAAC;QACV;QAEA,OAAOV,0BAA0B;YAC/Ba;YACAC;YACAC;YACAC;QACF;IACF;IAEAnB,UAAU;QACR,IAAI,CAACoB,OAAOP,YAAaU,kBAAkBF,gBAAiB;YAC1D;QACF;QAEAI,gBACEtB,0BAA0B;YACxBa;YACAC;YACAC;YACAC;QACF;IAEJ,GAAG;QACDN;QACAU;QACAF;QACAJ;QACAE;QACAH;QACAE;QACAE;KACD;IAED,IAAIT,QAAQC;IACZ,IAAIgB,iBAAiBb;IACrB,IAAI,CAACF,UAAU;QACb,IAAI,CAACU,gBAAgB;YAClB,CAAA,EAAEK,cAAc,EAAE,GAAGJ,YAAW;QACnC;QACA,IAAI,CAACH,gBAAgB;YAClB,CAAA,EAAEV,KAAK,EAAE,GAAGa,YAAW;QAC1B;IACF;IAEA,IAAIjB,QAAmCC;IACvC,IAAI,CAAC,CAACG,SAAS,CAAC,CAACiB,kBAAkBlB,WAAWY,WAAW;QACvDf,QAAQ;YACN,GAAGA,KAAK;YACRG,QAAQA,UAAUH,OAAOG;YACzBC,OAAOA,SAASJ,OAAOI;YACvB,uEAAuE;YACvE,wEAAwE;YACxEiB,gBAAgBA,kBAAkBrB,OAAOqB;QAC3C;IACF;IAEA,OAAO;QACLrB;QACAE,WAAWV,IAAIU,WAAW,CAACI,YAAYT;IACzC;AACF"}
@@ -218,11 +218,11 @@ const noop = ()=>{
218
218
  dispatch(dispatchStage);
219
219
  return;
220
220
  }
221
- const timer = window.setTimeout(()=>{
221
+ const timer = globalThis.setTimeout(()=>{
222
222
  dispatch(dispatchStage);
223
223
  }, duration);
224
224
  return ()=>{
225
- window.clearTimeout(timer);
225
+ globalThis.clearTimeout(timer);
226
226
  };
227
227
  }, [
228
228
  appearing,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/transition/useTransition.ts"],"sourcesContent":["\"use client\";\n\nimport { useReducer, useRef, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport { TRANSITION_CONFIG } from \"./config.js\";\nimport type {\n TransitionHookOptions,\n TransitionHookReturnValue,\n TransitionStage,\n TransitionState,\n} from \"./types.js\";\nimport { getTransitionTimeout } from \"./utils.js\";\n\nconst INITIAL_STATE: TransitionState = {\n appearing: false,\n rendered: true,\n stage: \"exited\",\n};\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * You'll most likely want to use the {@link useCSSTransition} hook instead\n * since this is just a low-level hook that can be used to transition using\n * timeouts.\n *\n * @see {@link https://react-md.dev/hooks/use-transition | useTransition Demos}\n * @typeParam E - The HTMLElement type used or the ref required for the\n * transition.\n * @since 4.0.0\n * @since 6.0.0 Added the `disablePortal` flag to the return value for SSR.\n */\nexport function useTransition<E extends HTMLElement>(\n options: TransitionHookOptions<E>\n): TransitionHookReturnValue<E> {\n const {\n nodeRef,\n timeout,\n transitionIn,\n reflow = false,\n temporary = false,\n appear = false,\n enter = true,\n exit = true,\n onEnter = noop,\n onEntering = noop,\n onEntered = noop,\n onExit = noop,\n onExiting = noop,\n onExited = noop,\n disablePortal: propDisablePortal,\n } = options;\n\n const configurationRef = useRef({\n timeout: getTransitionTimeout({ timeout, appear, enter, exit }),\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n } as const);\n useIsomorphicLayoutEffect(() => {\n configurationRef.current = {\n timeout: getTransitionTimeout({ timeout, appear, enter, exit }),\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n };\n }, [\n appear,\n enter,\n exit,\n onEnter,\n onEntered,\n onEntering,\n onExit,\n onExited,\n onExiting,\n reflow,\n timeout,\n ]);\n\n const ssr = useSsr();\n const [ref, refCallback] = useEnsuredRef<E>(nodeRef);\n const [disablePortal, setDisablePortal] = useState(ssr);\n const [state, dispatch] = useReducer(\n function reducer(\n state: TransitionState,\n action: TransitionStage | \"unmount\"\n ): TransitionState {\n const { appear, enter, exit } = configurationRef.current.timeout;\n const { appearing } = state;\n switch (action) {\n case \"enter\": {\n const duration = appearing ? appear : enter;\n return {\n stage: duration > 0 ? \"enter\" : \"entered\",\n rendered: true,\n appearing,\n };\n }\n case \"entering\":\n case \"entered\":\n return {\n stage: action,\n rendered: true,\n appearing,\n };\n case \"exit\": {\n const stage = exit > 0 ? \"exit\" : \"exited\";\n return {\n stage,\n rendered: !temporary || stage !== \"exited\",\n appearing: false,\n };\n }\n case \"exiting\":\n case \"exited\":\n return {\n stage: action,\n rendered: true,\n appearing: false,\n };\n case \"unmount\":\n if (state.stage === \"exited\" && !state.appearing && !state.rendered) {\n return state;\n }\n\n return {\n stage: \"exited\",\n rendered: false,\n appearing: false,\n };\n }\n },\n INITIAL_STATE,\n () => {\n let stage: TransitionStage = \"exited\";\n if (transitionIn) {\n stage = appear && !TRANSITION_CONFIG.disabled ? \"enter\" : \"entered\";\n }\n\n return {\n appearing: appear && transitionIn && !TRANSITION_CONFIG.disabled,\n rendered: !temporary || transitionIn,\n stage,\n };\n }\n );\n const { appearing, rendered, stage } = state;\n\n const isFirstRender = useRef(true);\n const isRehydrateAppear = useRef(ssr && !transitionIn);\n const defaultTransitionIn = useRef(transitionIn);\n useIsomorphicLayoutEffect(() => {\n const {\n timeout,\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n } = configurationRef.current;\n let { onExited } = configurationRef.current;\n if (isFirstRender.current) {\n // The exited hook should **not** fire on first render since the element\n // was never in the DOM.\n isFirstRender.current = false;\n onExited = noop;\n }\n\n // if the transitionIn did not change between initial render and rehydration,\n // allow the enter transition to behave like normal.\n if (\n isRehydrateAppear.current &&\n !ssr &&\n !transitionIn &&\n !defaultTransitionIn.current\n ) {\n isRehydrateAppear.current = false;\n }\n\n // Cancel any exiting/exited transitions and instead immediately start the\n // enter transition\n if (transitionIn && stage.startsWith(\"exit\")) {\n const nextStage = isRehydrateAppear.current ? \"entered\" : \"enter\";\n dispatch(nextStage);\n return;\n }\n\n // Cancel any entering/entered transitions and instead immediately start the\n // exit transition\n if (!transitionIn && stage.startsWith(\"enter\")) {\n dispatch(\"exit\");\n return;\n }\n\n if (reflow && ref.current && stage !== \"exited\" && stage !== \"entered\") {\n // force reflow by accessing scrollTop\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n ref.current.scrollTop;\n }\n\n let duration = 0;\n let nextStage: TransitionStage = stage;\n switch (stage) {\n case \"enter\":\n if (TRANSITION_CONFIG.disabled) {\n nextStage = \"entered\";\n } else {\n onEnter(appearing);\n nextStage = \"entering\";\n }\n break;\n case \"entering\":\n onEntering(appearing);\n duration = timeout.enter;\n nextStage = \"entered\";\n break;\n case \"entered\":\n onEntered(appearing);\n break;\n case \"exit\":\n if (TRANSITION_CONFIG.disabled) {\n nextStage = \"exited\";\n } else {\n onExit();\n nextStage = \"exiting\";\n }\n break;\n case \"exiting\":\n onExiting();\n duration = timeout.exit;\n nextStage = \"exited\";\n break;\n case \"exited\":\n onExited();\n setDisablePortal(false);\n break;\n }\n\n if (stage === nextStage) {\n // this is used to help catch changing the temporary prop.\n // not sure if I should really support that though...\n if (stage === \"exited\" && temporary) {\n dispatch(\"unmount\");\n }\n\n return;\n }\n\n // I used to rely on the `dispatch(\"unmount\")` above, but it seems like\n // there are some cases where re-rendering takes too long so the temporary\n // element flashes\n const dispatchStage =\n temporary && nextStage === \"exited\" ? \"unmount\" : nextStage;\n if (duration <= 0) {\n dispatch(dispatchStage);\n return;\n }\n\n const timer = window.setTimeout(() => {\n dispatch(dispatchStage);\n }, duration);\n\n return () => {\n window.clearTimeout(timer);\n };\n }, [appearing, ref, ssr, stage, temporary, transitionIn]);\n\n return {\n ref: refCallback,\n stage,\n rendered,\n appearing,\n transitionTo: dispatch,\n disablePortal: propDisablePortal || disablePortal,\n };\n}\n"],"names":["useReducer","useRef","useState","useSsr","useEnsuredRef","useIsomorphicLayoutEffect","TRANSITION_CONFIG","getTransitionTimeout","INITIAL_STATE","appearing","rendered","stage","noop","useTransition","options","nodeRef","timeout","transitionIn","reflow","temporary","appear","enter","exit","onEnter","onEntering","onEntered","onExit","onExiting","onExited","disablePortal","propDisablePortal","configurationRef","current","ssr","ref","refCallback","setDisablePortal","state","dispatch","reducer","action","duration","disabled","isFirstRender","isRehydrateAppear","defaultTransitionIn","startsWith","nextStage","scrollTop","dispatchStage","timer","window","setTimeout","clearTimeout","transitionTo"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/transition/useTransition.ts"],"sourcesContent":["\"use client\";\n\nimport { useReducer, useRef, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport { TRANSITION_CONFIG } from \"./config.js\";\nimport type {\n TransitionHookOptions,\n TransitionHookReturnValue,\n TransitionStage,\n TransitionState,\n} from \"./types.js\";\nimport { getTransitionTimeout } from \"./utils.js\";\n\nconst INITIAL_STATE: TransitionState = {\n appearing: false,\n rendered: true,\n stage: \"exited\",\n};\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * You'll most likely want to use the {@link useCSSTransition} hook instead\n * since this is just a low-level hook that can be used to transition using\n * timeouts.\n *\n * @see {@link https://react-md.dev/hooks/use-transition | useTransition Demos}\n * @typeParam E - The HTMLElement type used or the ref required for the\n * transition.\n * @since 4.0.0\n * @since 6.0.0 Added the `disablePortal` flag to the return value for SSR.\n */\nexport function useTransition<E extends HTMLElement>(\n options: TransitionHookOptions<E>\n): TransitionHookReturnValue<E> {\n const {\n nodeRef,\n timeout,\n transitionIn,\n reflow = false,\n temporary = false,\n appear = false,\n enter = true,\n exit = true,\n onEnter = noop,\n onEntering = noop,\n onEntered = noop,\n onExit = noop,\n onExiting = noop,\n onExited = noop,\n disablePortal: propDisablePortal,\n } = options;\n\n const configurationRef = useRef({\n timeout: getTransitionTimeout({ timeout, appear, enter, exit }),\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n } as const);\n useIsomorphicLayoutEffect(() => {\n configurationRef.current = {\n timeout: getTransitionTimeout({ timeout, appear, enter, exit }),\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n };\n }, [\n appear,\n enter,\n exit,\n onEnter,\n onEntered,\n onEntering,\n onExit,\n onExited,\n onExiting,\n reflow,\n timeout,\n ]);\n\n const ssr = useSsr();\n const [ref, refCallback] = useEnsuredRef<E>(nodeRef);\n const [disablePortal, setDisablePortal] = useState(ssr);\n const [state, dispatch] = useReducer(\n function reducer(\n state: TransitionState,\n action: TransitionStage | \"unmount\"\n ): TransitionState {\n const { appear, enter, exit } = configurationRef.current.timeout;\n const { appearing } = state;\n switch (action) {\n case \"enter\": {\n const duration = appearing ? appear : enter;\n return {\n stage: duration > 0 ? \"enter\" : \"entered\",\n rendered: true,\n appearing,\n };\n }\n case \"entering\":\n case \"entered\":\n return {\n stage: action,\n rendered: true,\n appearing,\n };\n case \"exit\": {\n const stage = exit > 0 ? \"exit\" : \"exited\";\n return {\n stage,\n rendered: !temporary || stage !== \"exited\",\n appearing: false,\n };\n }\n case \"exiting\":\n case \"exited\":\n return {\n stage: action,\n rendered: true,\n appearing: false,\n };\n case \"unmount\":\n if (state.stage === \"exited\" && !state.appearing && !state.rendered) {\n return state;\n }\n\n return {\n stage: \"exited\",\n rendered: false,\n appearing: false,\n };\n }\n },\n INITIAL_STATE,\n () => {\n let stage: TransitionStage = \"exited\";\n if (transitionIn) {\n stage = appear && !TRANSITION_CONFIG.disabled ? \"enter\" : \"entered\";\n }\n\n return {\n appearing: appear && transitionIn && !TRANSITION_CONFIG.disabled,\n rendered: !temporary || transitionIn,\n stage,\n };\n }\n );\n const { appearing, rendered, stage } = state;\n\n const isFirstRender = useRef(true);\n const isRehydrateAppear = useRef(ssr && !transitionIn);\n const defaultTransitionIn = useRef(transitionIn);\n useIsomorphicLayoutEffect(() => {\n const {\n timeout,\n reflow,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n } = configurationRef.current;\n let { onExited } = configurationRef.current;\n if (isFirstRender.current) {\n // The exited hook should **not** fire on first render since the element\n // was never in the DOM.\n isFirstRender.current = false;\n onExited = noop;\n }\n\n // if the transitionIn did not change between initial render and rehydration,\n // allow the enter transition to behave like normal.\n if (\n isRehydrateAppear.current &&\n !ssr &&\n !transitionIn &&\n !defaultTransitionIn.current\n ) {\n isRehydrateAppear.current = false;\n }\n\n // Cancel any exiting/exited transitions and instead immediately start the\n // enter transition\n if (transitionIn && stage.startsWith(\"exit\")) {\n const nextStage = isRehydrateAppear.current ? \"entered\" : \"enter\";\n dispatch(nextStage);\n return;\n }\n\n // Cancel any entering/entered transitions and instead immediately start the\n // exit transition\n if (!transitionIn && stage.startsWith(\"enter\")) {\n dispatch(\"exit\");\n return;\n }\n\n if (reflow && ref.current && stage !== \"exited\" && stage !== \"entered\") {\n // force reflow by accessing scrollTop\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n ref.current.scrollTop;\n }\n\n let duration = 0;\n let nextStage: TransitionStage = stage;\n switch (stage) {\n case \"enter\":\n if (TRANSITION_CONFIG.disabled) {\n nextStage = \"entered\";\n } else {\n onEnter(appearing);\n nextStage = \"entering\";\n }\n break;\n case \"entering\":\n onEntering(appearing);\n duration = timeout.enter;\n nextStage = \"entered\";\n break;\n case \"entered\":\n onEntered(appearing);\n break;\n case \"exit\":\n if (TRANSITION_CONFIG.disabled) {\n nextStage = \"exited\";\n } else {\n onExit();\n nextStage = \"exiting\";\n }\n break;\n case \"exiting\":\n onExiting();\n duration = timeout.exit;\n nextStage = \"exited\";\n break;\n case \"exited\":\n onExited();\n setDisablePortal(false);\n break;\n }\n\n if (stage === nextStage) {\n // this is used to help catch changing the temporary prop.\n // not sure if I should really support that though...\n if (stage === \"exited\" && temporary) {\n dispatch(\"unmount\");\n }\n\n return;\n }\n\n // I used to rely on the `dispatch(\"unmount\")` above, but it seems like\n // there are some cases where re-rendering takes too long so the temporary\n // element flashes\n const dispatchStage =\n temporary && nextStage === \"exited\" ? \"unmount\" : nextStage;\n if (duration <= 0) {\n dispatch(dispatchStage);\n return;\n }\n\n const timer = globalThis.setTimeout(() => {\n dispatch(dispatchStage);\n }, duration);\n\n return () => {\n globalThis.clearTimeout(timer);\n };\n }, [appearing, ref, ssr, stage, temporary, transitionIn]);\n\n return {\n ref: refCallback,\n stage,\n rendered,\n appearing,\n transitionTo: dispatch,\n disablePortal: propDisablePortal || disablePortal,\n };\n}\n"],"names":["useReducer","useRef","useState","useSsr","useEnsuredRef","useIsomorphicLayoutEffect","TRANSITION_CONFIG","getTransitionTimeout","INITIAL_STATE","appearing","rendered","stage","noop","useTransition","options","nodeRef","timeout","transitionIn","reflow","temporary","appear","enter","exit","onEnter","onEntering","onEntered","onExit","onExiting","onExited","disablePortal","propDisablePortal","configurationRef","current","ssr","ref","refCallback","setDisablePortal","state","dispatch","reducer","action","duration","disabled","isFirstRender","isRehydrateAppear","defaultTransitionIn","startsWith","nextStage","scrollTop","dispatchStage","timer","globalThis","setTimeout","clearTimeout","transitionTo"],"mappings":"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"}
@@ -38,23 +38,23 @@
38
38
  cloned.style.paddingRight = element.style.paddingRight;
39
39
  cloned.style.visibility = "hidden";
40
40
  const container = element.parentElement || document.body;
41
- container.appendChild(cloned);
41
+ container.append(cloned);
42
42
  maxHeight = cloned.scrollHeight;
43
- const style = window.getComputedStyle(cloned);
43
+ const style = globalThis.getComputedStyle(cloned);
44
44
  const isContentBox = style.boxSizing === "content-box";
45
45
  if (style.paddingTop) {
46
- paddingTop = parseFloat(style.paddingTop);
46
+ paddingTop = Number.parseFloat(style.paddingTop);
47
47
  if (isContentBox) {
48
48
  maxHeight += paddingTop;
49
49
  }
50
50
  }
51
51
  if (style.paddingBottom) {
52
- paddingBottom = parseFloat(style.paddingBottom);
52
+ paddingBottom = Number.parseFloat(style.paddingBottom);
53
53
  if (isContentBox) {
54
54
  maxHeight += paddingBottom;
55
55
  }
56
56
  }
57
- container.removeChild(cloned);
57
+ cloned.remove();
58
58
  }
59
59
  return {
60
60
  maxHeight,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/transition/utils.ts"],"sourcesContent":["import type {\n CSSTransitionClassNames,\n CSSTransitionClassNamesObject,\n TransitionActions,\n TransitionTimeout,\n TransitionTimeoutObject,\n} from \"./types.js\";\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface TransitionTimeoutOptions extends Required<TransitionActions> {\n timeout: TransitionTimeout;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function getTransitionTimeout(\n options: Readonly<TransitionTimeoutOptions>\n): Readonly<Required<TransitionTimeoutObject>> {\n const { timeout, appear, enter, exit } = options;\n if (typeof timeout === \"number\") {\n return {\n appear: appear ? timeout : 0,\n enter: enter ? timeout : 0,\n exit: exit ? timeout : 0,\n };\n }\n\n return {\n appear: (appear && (timeout.appear ?? timeout.enter)) || 0,\n enter: (enter && timeout.enter) || 0,\n exit: (exit && timeout.exit) || 0,\n };\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface CollapseSizing {\n maxHeight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n}\n\n/**\n * A small util that will find the max-height, padding-top, and padding-bottom\n * for the provided element. This is really used to be able to transition the\n * max-height value since `max-height: auto` does not transition. The only way\n * to get transition is to change max-height values manually.\n *\n * @since 4.0.0\n * @internal\n */\nexport function getElementSizing(element: HTMLElement | null): CollapseSizing {\n let maxHeight: number | undefined;\n let paddingTop: number | undefined;\n let paddingBottom: number | undefined;\n if (element) {\n // clone the element so that the total height and padding can be calculated\n // without being affected by the collapse transition inline styles\n const cloned = element.cloneNode(true) as HTMLElement;\n cloned.style.maxHeight = \"\";\n cloned.style.padding = \"\";\n cloned.style.paddingLeft = element.style.paddingLeft;\n cloned.style.paddingRight = element.style.paddingRight;\n cloned.style.visibility = \"hidden\";\n\n const container = element.parentElement || document.body;\n container.appendChild(cloned);\n maxHeight = cloned.scrollHeight;\n const style = window.getComputedStyle(cloned);\n const isContentBox = style.boxSizing === \"content-box\";\n if (style.paddingTop) {\n paddingTop = parseFloat(style.paddingTop);\n if (isContentBox) {\n maxHeight += paddingTop;\n }\n }\n\n if (style.paddingBottom) {\n paddingBottom = parseFloat(style.paddingBottom);\n if (isContentBox) {\n maxHeight += paddingBottom;\n }\n }\n container.removeChild(cloned);\n }\n\n return { maxHeight, paddingTop, paddingBottom };\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface TransitionClassNamesOptions extends TransitionTimeoutOptions {\n classNames: CSSTransitionClassNames;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function getTransitionClassNames(\n options: TransitionClassNamesOptions\n): Readonly<Required<CSSTransitionClassNamesObject>> {\n const { classNames, ...timeoutOptions } = options;\n const timeout = getTransitionTimeout(timeoutOptions);\n\n if (typeof classNames === \"string\") {\n const { appear, enter, exit } = timeout;\n return {\n appear: appear ? `${classNames}--appear` : \"\",\n appearActive: appear ? `${classNames}--appear-active` : \"\",\n appearDone: \"\",\n enter: enter ? `${classNames}--enter` : \"\",\n enterActive: enter ? `${classNames}--enter-active` : \"\",\n enterDone: \"\",\n exit: exit ? `${classNames}--exit` : \"\",\n exitActive: exit ? `${classNames}--exit-active` : \"\",\n exitDone: \"\",\n };\n }\n\n const {\n enter = \"\",\n enterActive = \"\",\n enterDone = \"\",\n exit = \"\",\n exitActive = \"\",\n exitDone = \"\",\n appear = (timeout.appear && enter) || \"\",\n appearActive = (timeout.appear && enterActive) || \"\",\n appearDone = (timeout.appear && enterDone) || \"\",\n } = classNames;\n\n return {\n appear,\n appearActive,\n appearDone,\n enter,\n enterActive,\n enterDone,\n exit,\n exitActive,\n exitDone,\n };\n}\n"],"names":["getTransitionTimeout","options","timeout","appear","enter","exit","getElementSizing","element","maxHeight","paddingTop","paddingBottom","cloned","cloneNode","style","padding","paddingLeft","paddingRight","visibility","container","parentElement","document","body","appendChild","scrollHeight","window","getComputedStyle","isContentBox","boxSizing","parseFloat","removeChild","getTransitionClassNames","classNames","timeoutOptions","appearActive","appearDone","enterActive","enterDone","exitActive","exitDone"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/transition/utils.ts"],"sourcesContent":["import type {\n CSSTransitionClassNames,\n CSSTransitionClassNamesObject,\n TransitionActions,\n TransitionTimeout,\n TransitionTimeoutObject,\n} from \"./types.js\";\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface TransitionTimeoutOptions extends Required<TransitionActions> {\n timeout: TransitionTimeout;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function getTransitionTimeout(\n options: Readonly<TransitionTimeoutOptions>\n): Readonly<Required<TransitionTimeoutObject>> {\n const { timeout, appear, enter, exit } = options;\n if (typeof timeout === \"number\") {\n return {\n appear: appear ? timeout : 0,\n enter: enter ? timeout : 0,\n exit: exit ? timeout : 0,\n };\n }\n\n return {\n appear: (appear && (timeout.appear ?? timeout.enter)) || 0,\n enter: (enter && timeout.enter) || 0,\n exit: (exit && timeout.exit) || 0,\n };\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface CollapseSizing {\n maxHeight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n}\n\n/**\n * A small util that will find the max-height, padding-top, and padding-bottom\n * for the provided element. This is really used to be able to transition the\n * max-height value since `max-height: auto` does not transition. The only way\n * to get transition is to change max-height values manually.\n *\n * @since 4.0.0\n * @internal\n */\nexport function getElementSizing(element: HTMLElement | null): CollapseSizing {\n let maxHeight: number | undefined;\n let paddingTop: number | undefined;\n let paddingBottom: number | undefined;\n if (element) {\n // clone the element so that the total height and padding can be calculated\n // without being affected by the collapse transition inline styles\n const cloned = element.cloneNode(true) as HTMLElement;\n cloned.style.maxHeight = \"\";\n cloned.style.padding = \"\";\n cloned.style.paddingLeft = element.style.paddingLeft;\n cloned.style.paddingRight = element.style.paddingRight;\n cloned.style.visibility = \"hidden\";\n\n const container = element.parentElement || document.body;\n container.append(cloned);\n maxHeight = cloned.scrollHeight;\n const style = globalThis.getComputedStyle(cloned);\n const isContentBox = style.boxSizing === \"content-box\";\n if (style.paddingTop) {\n paddingTop = Number.parseFloat(style.paddingTop);\n if (isContentBox) {\n maxHeight += paddingTop;\n }\n }\n\n if (style.paddingBottom) {\n paddingBottom = Number.parseFloat(style.paddingBottom);\n if (isContentBox) {\n maxHeight += paddingBottom;\n }\n }\n cloned.remove();\n }\n\n return { maxHeight, paddingTop, paddingBottom };\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport interface TransitionClassNamesOptions extends TransitionTimeoutOptions {\n classNames: CSSTransitionClassNames;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function getTransitionClassNames(\n options: TransitionClassNamesOptions\n): Readonly<Required<CSSTransitionClassNamesObject>> {\n const { classNames, ...timeoutOptions } = options;\n const timeout = getTransitionTimeout(timeoutOptions);\n\n if (typeof classNames === \"string\") {\n const { appear, enter, exit } = timeout;\n return {\n appear: appear ? `${classNames}--appear` : \"\",\n appearActive: appear ? `${classNames}--appear-active` : \"\",\n appearDone: \"\",\n enter: enter ? `${classNames}--enter` : \"\",\n enterActive: enter ? `${classNames}--enter-active` : \"\",\n enterDone: \"\",\n exit: exit ? `${classNames}--exit` : \"\",\n exitActive: exit ? `${classNames}--exit-active` : \"\",\n exitDone: \"\",\n };\n }\n\n const {\n enter = \"\",\n enterActive = \"\",\n enterDone = \"\",\n exit = \"\",\n exitActive = \"\",\n exitDone = \"\",\n appear = (timeout.appear && enter) || \"\",\n appearActive = (timeout.appear && enterActive) || \"\",\n appearDone = (timeout.appear && enterDone) || \"\",\n } = classNames;\n\n return {\n appear,\n appearActive,\n appearDone,\n enter,\n enterActive,\n enterDone,\n exit,\n exitActive,\n exitDone,\n };\n}\n"],"names":["getTransitionTimeout","options","timeout","appear","enter","exit","getElementSizing","element","maxHeight","paddingTop","paddingBottom","cloned","cloneNode","style","padding","paddingLeft","paddingRight","visibility","container","parentElement","document","body","append","scrollHeight","globalThis","getComputedStyle","isContentBox","boxSizing","Number","parseFloat","remove","getTransitionClassNames","classNames","timeoutOptions","appearActive","appearDone","enterActive","enterDone","exitActive","exitDone"],"mappings":"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"}
@@ -85,7 +85,7 @@ import { treeItem, treeItemContent, treeItemMedia } from "./styles.js";
85
85
  // cheating a bit so there are type errors around the event handlers
86
86
  const ContentComponent = isLink ? Link : "span";
87
87
  const leftAddonType = propLeftAddonType ?? (expanderLeft && leftAddon) ? "media" : undefined;
88
- const isMediaLeftAddon = typeof propLeftAddonType === "undefined" && leftAddonType === "media";
88
+ const isMediaLeftAddon = propLeftAddonType === undefined && leftAddonType === "media";
89
89
  const disableLeftAddonCenteredMedia = propDisableLeftAddonCenteredMedia ?? isMediaLeftAddon;
90
90
  return /*#__PURE__*/ _jsxs("li", {
91
91
  ...liProps,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tree/TreeItem.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useEffect,\n} from \"react\";\n\nimport { type ComponentWithRippleProps } from \"../interaction/types.js\";\nimport { useElementInteraction } from \"../interaction/useElementInteraction.js\";\nimport { useHigherContrastChildren } from \"../interaction/useHigherContrastChildren.js\";\nimport { ListItemChildren } from \"../list/ListItemChildren.js\";\nimport { useKeyboardMovementContext } from \"../movement/useKeyboardMovementProvider.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type OverridableTreeGroupProps, TreeGroup } from \"./TreeGroup.js\";\nimport { TreeItemExpander } from \"./TreeItemExpander.js\";\nimport { useTreeContext } from \"./TreeProvider.js\";\nimport { treeItem, treeItemContent, treeItemMedia } from \"./styles.js\";\nimport { type DefaultTreeItemNode } from \"./types.js\";\n\n/**\n * @since 6.0.0 Added `liProps` and `groupProps`.\n * @since 6.0.0 The `liRef`, `liStyle`, and `liClassName` props were removed in\n * favor of `liProps={{ ref, style, className }}`.\n * @since 6.0.0 The `itemIndex`, `listSize`, `renderChildItems`, `isLink`,\n * `contentComponent`, and `readOnly` props were removed.\n */\nexport interface TreeItemProps\n extends\n Omit<DefaultTreeItemNode, \"parentId\">,\n HTMLAttributes<HTMLLIElement>,\n ComponentWithRippleProps {\n /**\n * @defaultValue `\"tree-item-\" + useId()`\n */\n id?: string;\n\n /**\n * This is used to set the `--rmd-tree-depth` CSS variable which allows the\n * padding to increase for each nested tree.\n */\n depth: number;\n\n /**\n * Any additional props that should be passed to the surrounding `<li>`\n * element. The top-level props are passed to the `<span>` or `<a>` element\n * instead.\n */\n liProps?: PropsWithRef<HTMLAttributes<HTMLLIElement>>;\n\n /**\n * Any additional props to pass to the `TreeGroup` component.\n */\n groupProps?: PropsWithRef<OverridableTreeGroupProps>;\n\n /**\n * This should normally be the text/content to display within the tree item\n * and should **not** include nested trees.\n */\n children?: ReactNode;\n\n /**\n * The nested tree items to render within a `TreeGroup`.\n */\n childItems?: ReactNode;\n\n /** @defaultValue `false` */\n disableTransition?: boolean;\n\n /**\n * This ref is applied to the `<span>` or `<a>` element and can be used to\n * implement drag and drop behavior.\n */\n contentRef?: Ref<HTMLElement>;\n\n /**\n * Set this to `true` if the {@link childItems} should not be rendered while\n * collapsed.\n *\n * @defaultValue `false`\n */\n temporaryChildItems?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/tree | Tree Demos}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/treeview/}\n * @since 6.0.0 No longer forwards refs. The ref must be provided using\n * `contentRef` instead.\n * @since 6.0.0 The `liRef` was removed in favor of `liProps={{ ref }}`.\n * @since 6.0.0 The wrapping `<li>` element will always be `role=\"none\"` and the\n * `<span>` or `<a>` will gain the `role=\"treeitem\"` instead. This makes it\n * easier to pass event handlers because of the nested behavior of tree items.\n * @since 6.0.0 No longer provides the `aria-level`, `aria-setsize` and\n * `aria-posinset` attributes and allows the browser to compute them instead.\n */\nexport function TreeItem(props: TreeItemProps): ReactElement {\n const {\n id: propId,\n depth,\n liProps,\n disabled = false,\n disabledOpacity = false,\n groupProps,\n children: propChildren,\n className,\n itemId,\n leftAddon,\n leftAddonType: propLeftAddonType,\n leftAddonPosition,\n leftAddonClassName,\n leftAddonForceWrap,\n rightAddon,\n rightAddonType,\n rightAddonPosition,\n rightAddonClassName,\n rightAddonForceWrap,\n disableTextChildren,\n disableLeftAddonCenteredMedia: propDisableLeftAddonCenteredMedia,\n disableRightAddonCenteredMedia,\n textProps,\n textClassName,\n primaryText,\n secondaryText,\n secondaryTextProps,\n secondaryTextClassName,\n multiline,\n childItems,\n contentClassName,\n temporaryChildItems,\n disableTransition: propDisableTransition,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDragStart,\n onTouchStart,\n onTouchEnd,\n onTouchMove,\n contentRef,\n disableRipple,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"tree-item\");\n const children = useHigherContrastChildren(propChildren);\n if (disabled) {\n // you can't really disable a link other than removing the href, so\n // unset these props\n remaining.to = undefined;\n remaining.href = undefined;\n }\n\n const {\n expandedIds,\n selectedIds,\n expanderLeft,\n expansionMode,\n metadataLookup,\n linkComponent: Link,\n toggleTreeItemSelection,\n toggleTreeItemExpansion,\n disableTransition: contextDisableTransition,\n } = useTreeContext();\n const { activeDescendantId } = useKeyboardMovementContext();\n\n const isLeafNode = !childItems;\n const focused = activeDescendantId === id;\n const expanded = expandedIds.has(itemId);\n const selected = selectedIds.has(itemId);\n const disableTransition = propDisableTransition ?? contextDisableTransition;\n\n useEffect(() => {\n const lookup = metadataLookup.current;\n lookup.expandable[itemId] = !isLeafNode;\n lookup.disabledItems[itemId] = disabled;\n lookup.elementToItem[id] = itemId;\n lookup.itemToElement[itemId] = id;\n\n return () => {\n /* eslint-disable @typescript-eslint/no-dynamic-delete */\n delete lookup.disabledItems[itemId];\n delete lookup.expandable[itemId];\n delete lookup.elementToItem[id];\n delete lookup.itemToElement[itemId];\n /* eslint-enable @typescript-eslint/no-dynamic-delete */\n };\n }, [id, metadataLookup, itemId, isLeafNode, disabled, depth]);\n\n const { pressedClassName, ripples, handlers } =\n useElementInteraction<HTMLLIElement>({\n mode: disableRipple ? \"none\" : undefined,\n onBlur,\n onClick(event) {\n onClick?.(event);\n toggleTreeItemSelection(itemId);\n if (!isLeafNode && expansionMode !== \"manual\") {\n toggleTreeItemExpansion(itemId);\n }\n },\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDragStart,\n onTouchStart,\n onTouchEnd,\n onTouchMove,\n disabled,\n });\n\n const isLink = !!(remaining.to || remaining.href);\n\n // cheating a bit so there are type errors around the event handlers\n const ContentComponent = (isLink ? Link : \"span\") as \"span\";\n const leftAddonType =\n (propLeftAddonType ?? (expanderLeft && leftAddon)) ? \"media\" : undefined;\n const isMediaLeftAddon =\n typeof propLeftAddonType === \"undefined\" && leftAddonType === \"media\";\n const disableLeftAddonCenteredMedia =\n propDisableLeftAddonCenteredMedia ?? isMediaLeftAddon;\n\n return (\n <li\n {...liProps}\n role=\"none\"\n className={treeItem({\n className,\n expander: !!childItems,\n expanderLeft,\n })}\n >\n <ContentComponent\n {...remaining}\n // nodes with children should always apply the `aria-expanded` to show\n // that it is expandable while leaf nodes should remain omitted\n aria-expanded={isLeafNode ? undefined : expanded}\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n id={id}\n ref={contentRef}\n role=\"treeitem\"\n tabIndex={-1}\n {...handlers}\n className={treeItemContent({\n link: isLink,\n focused,\n selected,\n disabled,\n disabledOpacity,\n className: contentClassName,\n pressedClassName,\n })}\n >\n <ListItemChildren\n multiline={multiline}\n textClassName={textClassName}\n secondaryTextClassName={secondaryTextClassName}\n disableTextChildren={disableTextChildren}\n primaryText={primaryText}\n textProps={textProps}\n secondaryText={secondaryText}\n secondaryTextProps={secondaryTextProps}\n leftAddon={\n <TreeItemExpander\n isLeft\n itemId={itemId}\n addon={leftAddon}\n expanded={expanded}\n disabled={disabled}\n isLeafNode={isLeafNode}\n />\n }\n leftAddonType={leftAddonType}\n leftAddonPosition={leftAddonPosition}\n leftAddonClassName={treeItemMedia({\n isLeafNode,\n isMediaLeftAddon,\n className: leftAddonClassName,\n })}\n leftAddonForceWrap={leftAddonForceWrap}\n rightAddon={\n <TreeItemExpander\n itemId={itemId}\n addon={rightAddon}\n expanded={expanded}\n disabled={disabled}\n isLeafNode={isLeafNode}\n />\n }\n rightAddonType={rightAddonType}\n rightAddonPosition={rightAddonPosition}\n rightAddonClassName={rightAddonClassName}\n rightAddonForceWrap={rightAddonForceWrap}\n disableLeftAddonCenteredMedia={disableLeftAddonCenteredMedia}\n disableRightAddonCenteredMedia={disableRightAddonCenteredMedia}\n >\n {children}\n </ListItemChildren>\n {ripples}\n </ContentComponent>\n <TreeGroup\n id={`${id}-group`}\n temporary={temporaryChildItems}\n disableTransition={disableTransition}\n {...groupProps}\n depth={depth + 1}\n collapsed={isLeafNode || !expanded}\n >\n {childItems}\n </TreeGroup>\n </li>\n );\n}\n"],"names":["useEffect","useElementInteraction","useHigherContrastChildren","ListItemChildren","useKeyboardMovementContext","useEnsuredId","TreeGroup","TreeItemExpander","useTreeContext","treeItem","treeItemContent","treeItemMedia","TreeItem","props","id","propId","depth","liProps","disabled","disabledOpacity","groupProps","children","propChildren","className","itemId","leftAddon","leftAddonType","propLeftAddonType","leftAddonPosition","leftAddonClassName","leftAddonForceWrap","rightAddon","rightAddonType","rightAddonPosition","rightAddonClassName","rightAddonForceWrap","disableTextChildren","disableLeftAddonCenteredMedia","propDisableLeftAddonCenteredMedia","disableRightAddonCenteredMedia","textProps","textClassName","primaryText","secondaryText","secondaryTextProps","secondaryTextClassName","multiline","childItems","contentClassName","temporaryChildItems","disableTransition","propDisableTransition","onBlur","onClick","onKeyDown","onKeyUp","onMouseDown","onMouseUp","onMouseLeave","onDragStart","onTouchStart","onTouchEnd","onTouchMove","contentRef","disableRipple","remaining","to","undefined","href","expandedIds","selectedIds","expanderLeft","expansionMode","metadataLookup","linkComponent","Link","toggleTreeItemSelection","toggleTreeItemExpansion","contextDisableTransition","activeDescendantId","isLeafNode","focused","expanded","has","selected","lookup","current","expandable","disabledItems","elementToItem","itemToElement","pressedClassName","ripples","handlers","mode","event","isLink","ContentComponent","isMediaLeftAddon","li","role","expander","aria-expanded","aria-selected","aria-disabled","ref","tabIndex","link","isLeft","addon","temporary","collapsed"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/tree/TreeItem.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useEffect,\n} from \"react\";\n\nimport { type ComponentWithRippleProps } from \"../interaction/types.js\";\nimport { useElementInteraction } from \"../interaction/useElementInteraction.js\";\nimport { useHigherContrastChildren } from \"../interaction/useHigherContrastChildren.js\";\nimport { ListItemChildren } from \"../list/ListItemChildren.js\";\nimport { useKeyboardMovementContext } from \"../movement/useKeyboardMovementProvider.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type OverridableTreeGroupProps, TreeGroup } from \"./TreeGroup.js\";\nimport { TreeItemExpander } from \"./TreeItemExpander.js\";\nimport { useTreeContext } from \"./TreeProvider.js\";\nimport { treeItem, treeItemContent, treeItemMedia } from \"./styles.js\";\nimport { type DefaultTreeItemNode } from \"./types.js\";\n\n/**\n * @since 6.0.0 Added `liProps` and `groupProps`.\n * @since 6.0.0 The `liRef`, `liStyle`, and `liClassName` props were removed in\n * favor of `liProps={{ ref, style, className }}`.\n * @since 6.0.0 The `itemIndex`, `listSize`, `renderChildItems`, `isLink`,\n * `contentComponent`, and `readOnly` props were removed.\n */\nexport interface TreeItemProps\n extends\n Omit<DefaultTreeItemNode, \"parentId\">,\n HTMLAttributes<HTMLLIElement>,\n ComponentWithRippleProps {\n /**\n * @defaultValue `\"tree-item-\" + useId()`\n */\n id?: string;\n\n /**\n * This is used to set the `--rmd-tree-depth` CSS variable which allows the\n * padding to increase for each nested tree.\n */\n depth: number;\n\n /**\n * Any additional props that should be passed to the surrounding `<li>`\n * element. The top-level props are passed to the `<span>` or `<a>` element\n * instead.\n */\n liProps?: PropsWithRef<HTMLAttributes<HTMLLIElement>>;\n\n /**\n * Any additional props to pass to the `TreeGroup` component.\n */\n groupProps?: PropsWithRef<OverridableTreeGroupProps>;\n\n /**\n * This should normally be the text/content to display within the tree item\n * and should **not** include nested trees.\n */\n children?: ReactNode;\n\n /**\n * The nested tree items to render within a `TreeGroup`.\n */\n childItems?: ReactNode;\n\n /** @defaultValue `false` */\n disableTransition?: boolean;\n\n /**\n * This ref is applied to the `<span>` or `<a>` element and can be used to\n * implement drag and drop behavior.\n */\n contentRef?: Ref<HTMLElement>;\n\n /**\n * Set this to `true` if the {@link childItems} should not be rendered while\n * collapsed.\n *\n * @defaultValue `false`\n */\n temporaryChildItems?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/tree | Tree Demos}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/treeview/}\n * @since 6.0.0 No longer forwards refs. The ref must be provided using\n * `contentRef` instead.\n * @since 6.0.0 The `liRef` was removed in favor of `liProps={{ ref }}`.\n * @since 6.0.0 The wrapping `<li>` element will always be `role=\"none\"` and the\n * `<span>` or `<a>` will gain the `role=\"treeitem\"` instead. This makes it\n * easier to pass event handlers because of the nested behavior of tree items.\n * @since 6.0.0 No longer provides the `aria-level`, `aria-setsize` and\n * `aria-posinset` attributes and allows the browser to compute them instead.\n */\nexport function TreeItem(props: TreeItemProps): ReactElement {\n const {\n id: propId,\n depth,\n liProps,\n disabled = false,\n disabledOpacity = false,\n groupProps,\n children: propChildren,\n className,\n itemId,\n leftAddon,\n leftAddonType: propLeftAddonType,\n leftAddonPosition,\n leftAddonClassName,\n leftAddonForceWrap,\n rightAddon,\n rightAddonType,\n rightAddonPosition,\n rightAddonClassName,\n rightAddonForceWrap,\n disableTextChildren,\n disableLeftAddonCenteredMedia: propDisableLeftAddonCenteredMedia,\n disableRightAddonCenteredMedia,\n textProps,\n textClassName,\n primaryText,\n secondaryText,\n secondaryTextProps,\n secondaryTextClassName,\n multiline,\n childItems,\n contentClassName,\n temporaryChildItems,\n disableTransition: propDisableTransition,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDragStart,\n onTouchStart,\n onTouchEnd,\n onTouchMove,\n contentRef,\n disableRipple,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"tree-item\");\n const children = useHigherContrastChildren(propChildren);\n if (disabled) {\n // you can't really disable a link other than removing the href, so\n // unset these props\n remaining.to = undefined;\n remaining.href = undefined;\n }\n\n const {\n expandedIds,\n selectedIds,\n expanderLeft,\n expansionMode,\n metadataLookup,\n linkComponent: Link,\n toggleTreeItemSelection,\n toggleTreeItemExpansion,\n disableTransition: contextDisableTransition,\n } = useTreeContext();\n const { activeDescendantId } = useKeyboardMovementContext();\n\n const isLeafNode = !childItems;\n const focused = activeDescendantId === id;\n const expanded = expandedIds.has(itemId);\n const selected = selectedIds.has(itemId);\n const disableTransition = propDisableTransition ?? contextDisableTransition;\n\n useEffect(() => {\n const lookup = metadataLookup.current;\n lookup.expandable[itemId] = !isLeafNode;\n lookup.disabledItems[itemId] = disabled;\n lookup.elementToItem[id] = itemId;\n lookup.itemToElement[itemId] = id;\n\n return () => {\n /* eslint-disable @typescript-eslint/no-dynamic-delete */\n delete lookup.disabledItems[itemId];\n delete lookup.expandable[itemId];\n delete lookup.elementToItem[id];\n delete lookup.itemToElement[itemId];\n /* eslint-enable @typescript-eslint/no-dynamic-delete */\n };\n }, [id, metadataLookup, itemId, isLeafNode, disabled, depth]);\n\n const { pressedClassName, ripples, handlers } =\n useElementInteraction<HTMLLIElement>({\n mode: disableRipple ? \"none\" : undefined,\n onBlur,\n onClick(event) {\n onClick?.(event);\n toggleTreeItemSelection(itemId);\n if (!isLeafNode && expansionMode !== \"manual\") {\n toggleTreeItemExpansion(itemId);\n }\n },\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDragStart,\n onTouchStart,\n onTouchEnd,\n onTouchMove,\n disabled,\n });\n\n const isLink = !!(remaining.to || remaining.href);\n\n // cheating a bit so there are type errors around the event handlers\n const ContentComponent = (isLink ? Link : \"span\") as \"span\";\n const leftAddonType =\n (propLeftAddonType ?? (expanderLeft && leftAddon)) ? \"media\" : undefined;\n const isMediaLeftAddon =\n propLeftAddonType === undefined && leftAddonType === \"media\";\n const disableLeftAddonCenteredMedia =\n propDisableLeftAddonCenteredMedia ?? isMediaLeftAddon;\n\n return (\n <li\n {...liProps}\n role=\"none\"\n className={treeItem({\n className,\n expander: !!childItems,\n expanderLeft,\n })}\n >\n <ContentComponent\n {...remaining}\n // nodes with children should always apply the `aria-expanded` to show\n // that it is expandable while leaf nodes should remain omitted\n aria-expanded={isLeafNode ? undefined : expanded}\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n id={id}\n ref={contentRef}\n role=\"treeitem\"\n tabIndex={-1}\n {...handlers}\n className={treeItemContent({\n link: isLink,\n focused,\n selected,\n disabled,\n disabledOpacity,\n className: contentClassName,\n pressedClassName,\n })}\n >\n <ListItemChildren\n multiline={multiline}\n textClassName={textClassName}\n secondaryTextClassName={secondaryTextClassName}\n disableTextChildren={disableTextChildren}\n primaryText={primaryText}\n textProps={textProps}\n secondaryText={secondaryText}\n secondaryTextProps={secondaryTextProps}\n leftAddon={\n <TreeItemExpander\n isLeft\n itemId={itemId}\n addon={leftAddon}\n expanded={expanded}\n disabled={disabled}\n isLeafNode={isLeafNode}\n />\n }\n leftAddonType={leftAddonType}\n leftAddonPosition={leftAddonPosition}\n leftAddonClassName={treeItemMedia({\n isLeafNode,\n isMediaLeftAddon,\n className: leftAddonClassName,\n })}\n leftAddonForceWrap={leftAddonForceWrap}\n rightAddon={\n <TreeItemExpander\n itemId={itemId}\n addon={rightAddon}\n expanded={expanded}\n disabled={disabled}\n isLeafNode={isLeafNode}\n />\n }\n rightAddonType={rightAddonType}\n rightAddonPosition={rightAddonPosition}\n rightAddonClassName={rightAddonClassName}\n rightAddonForceWrap={rightAddonForceWrap}\n disableLeftAddonCenteredMedia={disableLeftAddonCenteredMedia}\n disableRightAddonCenteredMedia={disableRightAddonCenteredMedia}\n >\n {children}\n </ListItemChildren>\n {ripples}\n </ContentComponent>\n <TreeGroup\n id={`${id}-group`}\n temporary={temporaryChildItems}\n disableTransition={disableTransition}\n {...groupProps}\n depth={depth + 1}\n collapsed={isLeafNode || !expanded}\n >\n {childItems}\n </TreeGroup>\n </li>\n );\n}\n"],"names":["useEffect","useElementInteraction","useHigherContrastChildren","ListItemChildren","useKeyboardMovementContext","useEnsuredId","TreeGroup","TreeItemExpander","useTreeContext","treeItem","treeItemContent","treeItemMedia","TreeItem","props","id","propId","depth","liProps","disabled","disabledOpacity","groupProps","children","propChildren","className","itemId","leftAddon","leftAddonType","propLeftAddonType","leftAddonPosition","leftAddonClassName","leftAddonForceWrap","rightAddon","rightAddonType","rightAddonPosition","rightAddonClassName","rightAddonForceWrap","disableTextChildren","disableLeftAddonCenteredMedia","propDisableLeftAddonCenteredMedia","disableRightAddonCenteredMedia","textProps","textClassName","primaryText","secondaryText","secondaryTextProps","secondaryTextClassName","multiline","childItems","contentClassName","temporaryChildItems","disableTransition","propDisableTransition","onBlur","onClick","onKeyDown","onKeyUp","onMouseDown","onMouseUp","onMouseLeave","onDragStart","onTouchStart","onTouchEnd","onTouchMove","contentRef","disableRipple","remaining","to","undefined","href","expandedIds","selectedIds","expanderLeft","expansionMode","metadataLookup","linkComponent","Link","toggleTreeItemSelection","toggleTreeItemExpansion","contextDisableTransition","activeDescendantId","isLeafNode","focused","expanded","has","selected","lookup","current","expandable","disabledItems","elementToItem","itemToElement","pressedClassName","ripples","handlers","mode","event","isLink","ContentComponent","isMediaLeftAddon","li","role","expander","aria-expanded","aria-selected","aria-disabled","ref","tabIndex","link","isLeft","addon","temporary","collapsed"],"mappings":"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"}
@@ -26,18 +26,18 @@ import { useMemo } from "react";
26
26
  });
27
27
  }
28
28
  }
29
- if (!childItems.length) {
29
+ if (childItems.length === 0) {
30
30
  return undefined;
31
31
  }
32
32
  treeItemChildIds.set(parentId, childIds);
33
- childItems.forEach((childItem)=>{
33
+ for (const childItem of childItems){
34
34
  childItem.items = buildTree({
35
35
  sort,
36
36
  nodes,
37
37
  parentId: childItem.itemId,
38
38
  treeItemChildIds
39
39
  });
40
- });
40
+ }
41
41
  return sort(childItems);
42
42
  }
43
43
  /**
@@ -58,9 +58,11 @@ import { useMemo } from "react";
58
58
  parentId: rootId,
59
59
  treeItemChildIds
60
60
  });
61
- if (process.env.NODE_ENV !== "production" && values.length) {
61
+ if (process.env.NODE_ENV !== "production" && values.length > 0) {
62
62
  /* eslint-disable no-console */ console.warn("The following tree items are orphaned without a parent:");
63
- console.warn(values.slice());
63
+ console.warn([
64
+ ...values
65
+ ]);
64
66
  }
65
67
  return {
66
68
  items: items || [],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tree/useTreeItems.ts"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport type {\n DefaultTreeItemNode,\n TreeData,\n TreeItemNode,\n TreeItemSorter,\n} from \"./types.js\";\n\n/**\n * A lookup to find all the child ids for a specific parent. This was added to\n * support the `*` keyboard behavior of opening all tree items at the current\n * level.\n *\n * @since 6.0.0\n * @internal\n */\nexport type TreeItemChildIds = Map<string | null, Set<string>>;\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport type RenderableTreeItemNode<\n T extends TreeItemNode = DefaultTreeItemNode,\n> = T & {\n items?: readonly RenderableTreeItemNode<T>[];\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface BuildTreeOptions<T extends TreeItemNode> {\n sort: TreeItemSorter<T>;\n nodes: T[];\n parentId: string | null;\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * This util performantly builds a nested list of tree items from a giant flat\n * list of items by linking items together with the provided `parentId`. This\n * will also recursively build the tree and _hopefully_ all items will be added.\n *\n * @since 6.0.0 Updated to include the {@link TreeItemChildIds}\n */\nexport function buildTree<T extends TreeItemNode>(\n options: BuildTreeOptions<T>\n): readonly RenderableTreeItemNode<T>[] | undefined {\n const { sort, nodes, parentId, treeItemChildIds } = options;\n const childIds = treeItemChildIds.get(parentId) || new Set();\n const childItems: RenderableTreeItemNode<T>[] = [];\n\n // doing a \"reverse\" order filter/move so that the items array shrinks while\n // looping. This makes it so that the entire items array doesn't need to\n // continually be looped through as more items are added to the tree, only the\n // remaining items will have to be looped\n let i = nodes.length;\n while (i > 0) {\n i -= 1;\n if (nodes[i] && nodes[i].parentId === parentId) {\n const [item] = nodes.splice(i, 1);\n childIds.add(item.itemId);\n // shallow cloning so childItems doesn't get applied to the original data\n // set\n childItems.unshift({ ...item });\n }\n }\n\n if (!childItems.length) {\n return undefined;\n }\n\n treeItemChildIds.set(parentId, childIds);\n childItems.forEach((childItem) => {\n childItem.items = buildTree({\n sort,\n nodes,\n parentId: childItem.itemId,\n treeItemChildIds,\n });\n });\n\n return sort(childItems);\n}\n\n/**\n * @since 6.0.0\n */\nexport interface TreeItemOptions<T extends TreeItemNode> {\n data: TreeData<T>;\n sort: TreeItemSorter<T>;\n rootId: string | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface TreeItems<T extends TreeItemNode> {\n items: readonly RenderableTreeItemNode<T>[];\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * This is mostly an internal hook, but can be used to build tree-like\n * data structures without the need of the `Tree` component.\n *\n * @see {@link https://react-md.dev/components/tree | Tree Demos}\n * @since 6.0.0 converted to use an object argument instead of\n * multiple arguments. Also logs any orphaned items that do not have a parent\n */\nexport function useTreeItems<T extends TreeItemNode>(\n options: TreeItemOptions<T>\n): TreeItems<T> {\n const { data, sort, rootId } = options;\n\n return useMemo<TreeItems<T>>(() => {\n const values = Object.values(data);\n const treeItemChildIds = new Map<string, Set<string>>();\n const items = buildTree<T>({\n sort,\n nodes: values,\n parentId: rootId,\n treeItemChildIds,\n });\n\n if (process.env.NODE_ENV !== \"production\" && values.length) {\n /* eslint-disable no-console */\n console.warn(\"The following tree items are orphaned without a parent:\");\n console.warn(values.slice());\n }\n\n return {\n items: items || [],\n treeItemChildIds,\n };\n }, [data, rootId, sort]);\n}\n"],"names":["useMemo","buildTree","options","sort","nodes","parentId","treeItemChildIds","childIds","get","Set","childItems","i","length","item","splice","add","itemId","unshift","undefined","set","forEach","childItem","items","useTreeItems","data","rootId","values","Object","Map","process","env","NODE_ENV","console","warn","slice"],"mappings":"AAAA,SAASA,OAAO,QAAQ,QAAQ;AAwChC;;;;;;CAMC,GACD,OAAO,SAASC,UACdC,OAA4B;IAE5B,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,gBAAgB,EAAE,GAAGJ;IACpD,MAAMK,WAAWD,iBAAiBE,GAAG,CAACH,aAAa,IAAII;IACvD,MAAMC,aAA0C,EAAE;IAElD,4EAA4E;IAC5E,wEAAwE;IACxE,8EAA8E;IAC9E,yCAAyC;IACzC,IAAIC,IAAIP,MAAMQ,MAAM;IACpB,MAAOD,IAAI,EAAG;QACZA,KAAK;QACL,IAAIP,KAAK,CAACO,EAAE,IAAIP,KAAK,CAACO,EAAE,CAACN,QAAQ,KAAKA,UAAU;YAC9C,MAAM,CAACQ,KAAK,GAAGT,MAAMU,MAAM,CAACH,GAAG;YAC/BJ,SAASQ,GAAG,CAACF,KAAKG,MAAM;YACxB,yEAAyE;YACzE,MAAM;YACNN,WAAWO,OAAO,CAAC;gBAAE,GAAGJ,IAAI;YAAC;QAC/B;IACF;IAEA,IAAI,CAACH,WAAWE,MAAM,EAAE;QACtB,OAAOM;IACT;IAEAZ,iBAAiBa,GAAG,CAACd,UAAUE;IAC/BG,WAAWU,OAAO,CAAC,CAACC;QAClBA,UAAUC,KAAK,GAAGrB,UAAU;YAC1BE;YACAC;YACAC,UAAUgB,UAAUL,MAAM;YAC1BV;QACF;IACF;IAEA,OAAOH,KAAKO;AACd;AAmBA;;;;;;;CAOC,GACD,OAAO,SAASa,aACdrB,OAA2B;IAE3B,MAAM,EAAEsB,IAAI,EAAErB,IAAI,EAAEsB,MAAM,EAAE,GAAGvB;IAE/B,OAAOF,QAAsB;QAC3B,MAAM0B,SAASC,OAAOD,MAAM,CAACF;QAC7B,MAAMlB,mBAAmB,IAAIsB;QAC7B,MAAMN,QAAQrB,UAAa;YACzBE;YACAC,OAAOsB;YACPrB,UAAUoB;YACVnB;QACF;QAEA,IAAIuB,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBAAgBL,OAAOd,MAAM,EAAE;YAC1D,6BAA6B,GAC7BoB,QAAQC,IAAI,CAAC;YACbD,QAAQC,IAAI,CAACP,OAAOQ,KAAK;QAC3B;QAEA,OAAO;YACLZ,OAAOA,SAAS,EAAE;YAClBhB;QACF;IACF,GAAG;QAACkB;QAAMC;QAAQtB;KAAK;AACzB"}
1
+ {"version":3,"sources":["../../src/tree/useTreeItems.ts"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport type {\n DefaultTreeItemNode,\n TreeData,\n TreeItemNode,\n TreeItemSorter,\n} from \"./types.js\";\n\n/**\n * A lookup to find all the child ids for a specific parent. This was added to\n * support the `*` keyboard behavior of opening all tree items at the current\n * level.\n *\n * @since 6.0.0\n * @internal\n */\nexport type TreeItemChildIds = Map<string | null, Set<string>>;\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport type RenderableTreeItemNode<\n T extends TreeItemNode = DefaultTreeItemNode,\n> = T & {\n items?: readonly RenderableTreeItemNode<T>[];\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface BuildTreeOptions<T extends TreeItemNode> {\n sort: TreeItemSorter<T>;\n nodes: T[];\n parentId: string | null;\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * This util performantly builds a nested list of tree items from a giant flat\n * list of items by linking items together with the provided `parentId`. This\n * will also recursively build the tree and _hopefully_ all items will be added.\n *\n * @since 6.0.0 Updated to include the {@link TreeItemChildIds}\n */\nexport function buildTree<T extends TreeItemNode>(\n options: BuildTreeOptions<T>\n): readonly RenderableTreeItemNode<T>[] | undefined {\n const { sort, nodes, parentId, treeItemChildIds } = options;\n const childIds = treeItemChildIds.get(parentId) || new Set();\n const childItems: RenderableTreeItemNode<T>[] = [];\n\n // doing a \"reverse\" order filter/move so that the items array shrinks while\n // looping. This makes it so that the entire items array doesn't need to\n // continually be looped through as more items are added to the tree, only the\n // remaining items will have to be looped\n let i = nodes.length;\n while (i > 0) {\n i -= 1;\n if (nodes[i] && nodes[i].parentId === parentId) {\n const [item] = nodes.splice(i, 1);\n childIds.add(item.itemId);\n // shallow cloning so childItems doesn't get applied to the original data\n // set\n childItems.unshift({ ...item });\n }\n }\n\n if (childItems.length === 0) {\n return undefined;\n }\n\n treeItemChildIds.set(parentId, childIds);\n for (const childItem of childItems) {\n childItem.items = buildTree({\n sort,\n nodes,\n parentId: childItem.itemId,\n treeItemChildIds,\n });\n }\n\n return sort(childItems);\n}\n\n/**\n * @since 6.0.0\n */\nexport interface TreeItemOptions<T extends TreeItemNode> {\n data: TreeData<T>;\n sort: TreeItemSorter<T>;\n rootId: string | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface TreeItems<T extends TreeItemNode> {\n items: readonly RenderableTreeItemNode<T>[];\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * This is mostly an internal hook, but can be used to build tree-like\n * data structures without the need of the `Tree` component.\n *\n * @see {@link https://react-md.dev/components/tree | Tree Demos}\n * @since 6.0.0 converted to use an object argument instead of\n * multiple arguments. Also logs any orphaned items that do not have a parent\n */\nexport function useTreeItems<T extends TreeItemNode>(\n options: TreeItemOptions<T>\n): TreeItems<T> {\n const { data, sort, rootId } = options;\n\n return useMemo<TreeItems<T>>(() => {\n const values = Object.values(data);\n const treeItemChildIds = new Map<string, Set<string>>();\n const items = buildTree<T>({\n sort,\n nodes: values,\n parentId: rootId,\n treeItemChildIds,\n });\n\n if (process.env.NODE_ENV !== \"production\" && values.length > 0) {\n /* eslint-disable no-console */\n console.warn(\"The following tree items are orphaned without a parent:\");\n console.warn([...values]);\n }\n\n return {\n items: items || [],\n treeItemChildIds,\n };\n }, [data, rootId, sort]);\n}\n"],"names":["useMemo","buildTree","options","sort","nodes","parentId","treeItemChildIds","childIds","get","Set","childItems","i","length","item","splice","add","itemId","unshift","undefined","set","childItem","items","useTreeItems","data","rootId","values","Object","Map","process","env","NODE_ENV","console","warn"],"mappings":"AAAA,SAASA,OAAO,QAAQ,QAAQ;AAwChC;;;;;;CAMC,GACD,OAAO,SAASC,UACdC,OAA4B;IAE5B,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,gBAAgB,EAAE,GAAGJ;IACpD,MAAMK,WAAWD,iBAAiBE,GAAG,CAACH,aAAa,IAAII;IACvD,MAAMC,aAA0C,EAAE;IAElD,4EAA4E;IAC5E,wEAAwE;IACxE,8EAA8E;IAC9E,yCAAyC;IACzC,IAAIC,IAAIP,MAAMQ,MAAM;IACpB,MAAOD,IAAI,EAAG;QACZA,KAAK;QACL,IAAIP,KAAK,CAACO,EAAE,IAAIP,KAAK,CAACO,EAAE,CAACN,QAAQ,KAAKA,UAAU;YAC9C,MAAM,CAACQ,KAAK,GAAGT,MAAMU,MAAM,CAACH,GAAG;YAC/BJ,SAASQ,GAAG,CAACF,KAAKG,MAAM;YACxB,yEAAyE;YACzE,MAAM;YACNN,WAAWO,OAAO,CAAC;gBAAE,GAAGJ,IAAI;YAAC;QAC/B;IACF;IAEA,IAAIH,WAAWE,MAAM,KAAK,GAAG;QAC3B,OAAOM;IACT;IAEAZ,iBAAiBa,GAAG,CAACd,UAAUE;IAC/B,KAAK,MAAMa,aAAaV,WAAY;QAClCU,UAAUC,KAAK,GAAGpB,UAAU;YAC1BE;YACAC;YACAC,UAAUe,UAAUJ,MAAM;YAC1BV;QACF;IACF;IAEA,OAAOH,KAAKO;AACd;AAmBA;;;;;;;CAOC,GACD,OAAO,SAASY,aACdpB,OAA2B;IAE3B,MAAM,EAAEqB,IAAI,EAAEpB,IAAI,EAAEqB,MAAM,EAAE,GAAGtB;IAE/B,OAAOF,QAAsB;QAC3B,MAAMyB,SAASC,OAAOD,MAAM,CAACF;QAC7B,MAAMjB,mBAAmB,IAAIqB;QAC7B,MAAMN,QAAQpB,UAAa;YACzBE;YACAC,OAAOqB;YACPpB,UAAUmB;YACVlB;QACF;QAEA,IAAIsB,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBAAgBL,OAAOb,MAAM,GAAG,GAAG;YAC9D,6BAA6B,GAC7BmB,QAAQC,IAAI,CAAC;YACbD,QAAQC,IAAI,CAAC;mBAAIP;aAAO;QAC1B;QAEA,OAAO;YACLJ,OAAOA,SAAS,EAAE;YAClBf;QACF;IACF,GAAG;QAACiB;QAAMC;QAAQrB;KAAK;AACzB"}
@@ -93,7 +93,7 @@ import { getNextFocusableIndex } from "../movement/utils.js";
93
93
  const expandableIds = [
94
94
  ...itemIds
95
95
  ].filter((itemId)=>expandable[itemId]);
96
- if (expandableIds.length) {
96
+ if (expandableIds.length > 0) {
97
97
  expandMultipleTreeItems((prev)=>new Set([
98
98
  ...prev,
99
99
  ...expandableIds
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tree/useTreeMovement.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n Ref,\n} from \"react\";\nimport { useRef } from \"react\";\n\nimport type { KeyboardMovementProviderImplementation } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { getNextFocusableIndex } from \"../movement/utils.js\";\nimport type { NonNullMutableRef } from \"../types.js\";\nimport type { TreeItemMetadataLookup } from \"./TreeProvider.js\";\nimport type { TreeData, TreeItemNode } from \"./types.js\";\nimport type { TreeExpansion } from \"./useTreeExpansion.js\";\nimport type { TreeItemChildIds } from \"./useTreeItems.js\";\n\n/**\n * This helps catch the edge case where the collapse transition has occurred for\n * a tree item group, but the user uses the `ArrowDown` key before it has\n * finished. So to do this:\n *\n * - find the parent group of the tree item\n * - find the tree item that controls the group (the element before the group)\n * - check if the `aria-expanded` state is `\"false\"` meaning it is considered\n * closed\n *\n * @internal\n * @since 6.0.0\n */\nconst isParentItemCollapsing = (item: HTMLElement): boolean =>\n item\n .closest(\"[role='group']\")\n ?.previousElementSibling?.getAttribute(\"aria-expanded\") === \"false\";\n\n/**\n * @since 6.0.0\n * @internal\n */\nconst getVisibleTreeItems = (\n container: HTMLElement\n): readonly HTMLElement[] => {\n const items = [\n ...container.querySelectorAll<HTMLElement>('[role=\"treeitem\"]'),\n ];\n\n return items.filter(\n (item) =>\n // do not include items that have a `hidden` parent group\n item.offsetParent &&\n // do not include items that are about to become hidden\n !isParentItemCollapsing(item)\n );\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\ninterface TreeMovementOptions<T extends TreeItemNode> extends TreeExpansion {\n ref?: Ref<HTMLUListElement>;\n data: TreeData<T>;\n onClick: MouseEventHandler<HTMLUListElement> | undefined;\n onFocus: FocusEventHandler<HTMLUListElement> | undefined;\n onKeyDown: KeyboardEventHandler<HTMLUListElement> | undefined;\n selectedIds: ReadonlySet<string>;\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\ninterface TreeMovement extends KeyboardMovementProviderImplementation<HTMLUListElement> {\n /**\n * This will be mutated by the `TreeItem` component and used to handle\n * keyboard movement.\n */\n metadataLookup: NonNullMutableRef<TreeItemMetadataLookup>;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport function useTreeMovement<T extends TreeItemNode>(\n options: TreeMovementOptions<T>\n): TreeMovement {\n const {\n ref,\n onClick,\n onFocus,\n onKeyDown,\n data,\n expandedIds,\n selectedIds,\n treeItemChildIds,\n toggleTreeItemExpansion,\n expandMultipleTreeItems,\n } = options;\n\n const metadataLookup = useRef<TreeItemMetadataLookup>({\n expandable: {},\n disabledItems: {},\n elementToItem: {},\n itemToElement: {},\n });\n const movement = useKeyboardMovementProvider({\n ref,\n onClick,\n onFocus,\n onKeyDown,\n extendKeyDown(movementData) {\n const { event, activeDescendantId, currentFocusIndex, setFocusIndex } =\n movementData;\n const { expandable, disabledItems, elementToItem, itemToElement } =\n metadataLookup.current;\n const itemId = elementToItem[activeDescendantId];\n const item = data[itemId];\n\n /* c8 ignore start */\n if (!item) {\n return;\n }\n /* c8 ignore stop */\n\n const disabled = disabledItems[itemId];\n const expanded = expandedIds.has(itemId);\n\n let flagged = false;\n switch (event.key) {\n case \"ArrowLeft\":\n if (expanded && !disabled) {\n flagged = true;\n toggleTreeItemExpansion(itemId);\n } else if (item.parentId) {\n // do not flag for this case since setFocusIndex already does this\n const parentId = itemToElement[item.parentId];\n const focusables = getVisibleTreeItems(event.currentTarget);\n const index = focusables.findIndex(\n (element) => element.id === parentId\n );\n setFocusIndex(index, focusables);\n }\n\n break;\n case \"ArrowRight\":\n if (expandable[itemId] && !disabled) {\n if (!expanded) {\n flagged = true;\n toggleTreeItemExpansion(itemId);\n } else {\n // do not flag for this case since setFocusIndex already does this\n const focusables = getVisibleTreeItems(event.currentTarget);\n const index = getNextFocusableIndex({\n loopable: false,\n increment: true,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n });\n\n setFocusIndex(index, focusables);\n }\n }\n\n break;\n case \"*\": {\n flagged = true;\n const itemIds = treeItemChildIds.get(item.parentId);\n if (itemIds) {\n const expandableIds = [...itemIds].filter(\n (itemId) => expandable[itemId]\n );\n if (expandableIds.length) {\n expandMultipleTreeItems(\n (prev) => new Set([...prev, ...expandableIds])\n );\n currentFocusIndex.current = -1;\n }\n }\n break;\n }\n }\n\n if (flagged) {\n event.stopPropagation();\n event.preventDefault();\n }\n },\n searchable: true,\n tabIndexBehavior: \"virtual\",\n getFocusableElements: getVisibleTreeItems,\n getDefaultFocusedIndex(options) {\n const { focusables } = options;\n const { elementToItem } = metadataLookup.current;\n\n return focusables.findIndex((element) =>\n selectedIds.has(elementToItem[element.id])\n );\n },\n });\n\n return {\n metadataLookup,\n ...movement,\n };\n}\n"],"names":["useRef","useKeyboardMovementProvider","getNextFocusableIndex","isParentItemCollapsing","item","closest","previousElementSibling","getAttribute","getVisibleTreeItems","container","items","querySelectorAll","filter","offsetParent","useTreeMovement","options","ref","onClick","onFocus","onKeyDown","data","expandedIds","selectedIds","treeItemChildIds","toggleTreeItemExpansion","expandMultipleTreeItems","metadataLookup","expandable","disabledItems","elementToItem","itemToElement","movement","extendKeyDown","movementData","event","activeDescendantId","currentFocusIndex","setFocusIndex","current","itemId","disabled","expanded","has","flagged","key","parentId","focusables","currentTarget","index","findIndex","element","id","loopable","increment","includeDisabled","itemIds","get","expandableIds","length","prev","Set","stopPropagation","preventDefault","searchable","tabIndexBehavior","getFocusableElements","getDefaultFocusedIndex"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/tree/useTreeMovement.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n Ref,\n} from \"react\";\nimport { useRef } from \"react\";\n\nimport type { KeyboardMovementProviderImplementation } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { getNextFocusableIndex } from \"../movement/utils.js\";\nimport type { NonNullMutableRef } from \"../types.js\";\nimport type { TreeItemMetadataLookup } from \"./TreeProvider.js\";\nimport type { TreeData, TreeItemNode } from \"./types.js\";\nimport type { TreeExpansion } from \"./useTreeExpansion.js\";\nimport type { TreeItemChildIds } from \"./useTreeItems.js\";\n\n/**\n * This helps catch the edge case where the collapse transition has occurred for\n * a tree item group, but the user uses the `ArrowDown` key before it has\n * finished. So to do this:\n *\n * - find the parent group of the tree item\n * - find the tree item that controls the group (the element before the group)\n * - check if the `aria-expanded` state is `\"false\"` meaning it is considered\n * closed\n *\n * @internal\n * @since 6.0.0\n */\nconst isParentItemCollapsing = (item: HTMLElement): boolean =>\n item\n .closest(\"[role='group']\")\n ?.previousElementSibling?.getAttribute(\"aria-expanded\") === \"false\";\n\n/**\n * @since 6.0.0\n * @internal\n */\nconst getVisibleTreeItems = (\n container: HTMLElement\n): readonly HTMLElement[] => {\n const items = [\n ...container.querySelectorAll<HTMLElement>('[role=\"treeitem\"]'),\n ];\n\n return items.filter(\n (item) =>\n // do not include items that have a `hidden` parent group\n item.offsetParent &&\n // do not include items that are about to become hidden\n !isParentItemCollapsing(item)\n );\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\ninterface TreeMovementOptions<T extends TreeItemNode> extends TreeExpansion {\n ref?: Ref<HTMLUListElement>;\n data: TreeData<T>;\n onClick: MouseEventHandler<HTMLUListElement> | undefined;\n onFocus: FocusEventHandler<HTMLUListElement> | undefined;\n onKeyDown: KeyboardEventHandler<HTMLUListElement> | undefined;\n selectedIds: ReadonlySet<string>;\n treeItemChildIds: TreeItemChildIds;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\ninterface TreeMovement extends KeyboardMovementProviderImplementation<HTMLUListElement> {\n /**\n * This will be mutated by the `TreeItem` component and used to handle\n * keyboard movement.\n */\n metadataLookup: NonNullMutableRef<TreeItemMetadataLookup>;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport function useTreeMovement<T extends TreeItemNode>(\n options: TreeMovementOptions<T>\n): TreeMovement {\n const {\n ref,\n onClick,\n onFocus,\n onKeyDown,\n data,\n expandedIds,\n selectedIds,\n treeItemChildIds,\n toggleTreeItemExpansion,\n expandMultipleTreeItems,\n } = options;\n\n const metadataLookup = useRef<TreeItemMetadataLookup>({\n expandable: {},\n disabledItems: {},\n elementToItem: {},\n itemToElement: {},\n });\n const movement = useKeyboardMovementProvider({\n ref,\n onClick,\n onFocus,\n onKeyDown,\n extendKeyDown(movementData) {\n const { event, activeDescendantId, currentFocusIndex, setFocusIndex } =\n movementData;\n const { expandable, disabledItems, elementToItem, itemToElement } =\n metadataLookup.current;\n const itemId = elementToItem[activeDescendantId];\n const item = data[itemId];\n\n /* c8 ignore start */\n if (!item) {\n return;\n }\n /* c8 ignore stop */\n\n const disabled = disabledItems[itemId];\n const expanded = expandedIds.has(itemId);\n\n let flagged = false;\n switch (event.key) {\n case \"ArrowLeft\":\n if (expanded && !disabled) {\n flagged = true;\n toggleTreeItemExpansion(itemId);\n } else if (item.parentId) {\n // do not flag for this case since setFocusIndex already does this\n const parentId = itemToElement[item.parentId];\n const focusables = getVisibleTreeItems(event.currentTarget);\n const index = focusables.findIndex(\n (element) => element.id === parentId\n );\n setFocusIndex(index, focusables);\n }\n\n break;\n case \"ArrowRight\":\n if (expandable[itemId] && !disabled) {\n if (!expanded) {\n flagged = true;\n toggleTreeItemExpansion(itemId);\n } else {\n // do not flag for this case since setFocusIndex already does this\n const focusables = getVisibleTreeItems(event.currentTarget);\n const index = getNextFocusableIndex({\n loopable: false,\n increment: true,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n });\n\n setFocusIndex(index, focusables);\n }\n }\n\n break;\n case \"*\": {\n flagged = true;\n const itemIds = treeItemChildIds.get(item.parentId);\n if (itemIds) {\n const expandableIds = [...itemIds].filter(\n (itemId) => expandable[itemId]\n );\n if (expandableIds.length > 0) {\n expandMultipleTreeItems(\n (prev) => new Set([...prev, ...expandableIds])\n );\n currentFocusIndex.current = -1;\n }\n }\n break;\n }\n }\n\n if (flagged) {\n event.stopPropagation();\n event.preventDefault();\n }\n },\n searchable: true,\n tabIndexBehavior: \"virtual\",\n getFocusableElements: getVisibleTreeItems,\n getDefaultFocusedIndex(options) {\n const { focusables } = options;\n const { elementToItem } = metadataLookup.current;\n\n return focusables.findIndex((element) =>\n selectedIds.has(elementToItem[element.id])\n );\n },\n });\n\n return {\n metadataLookup,\n ...movement,\n };\n}\n"],"names":["useRef","useKeyboardMovementProvider","getNextFocusableIndex","isParentItemCollapsing","item","closest","previousElementSibling","getAttribute","getVisibleTreeItems","container","items","querySelectorAll","filter","offsetParent","useTreeMovement","options","ref","onClick","onFocus","onKeyDown","data","expandedIds","selectedIds","treeItemChildIds","toggleTreeItemExpansion","expandMultipleTreeItems","metadataLookup","expandable","disabledItems","elementToItem","itemToElement","movement","extendKeyDown","movementData","event","activeDescendantId","currentFocusIndex","setFocusIndex","current","itemId","disabled","expanded","has","flagged","key","parentId","focusables","currentTarget","index","findIndex","element","id","loopable","increment","includeDisabled","itemIds","get","expandableIds","length","prev","Set","stopPropagation","preventDefault","searchable","tabIndexBehavior","getFocusableElements","getDefaultFocusedIndex"],"mappings":"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"}
@@ -36,16 +36,13 @@
36
36
  * @since 6.0.0 Renamed from `getChildItems` to `getChildTreeItems`.
37
37
  */ export function getChildTreeItems(data, parentId, recursive = false) {
38
38
  const items = Array.isArray(data) ? data : Object.values(data);
39
- return items.reduce((list, item)=>{
40
- if (parentId !== item.parentId) {
41
- return list;
39
+ const treeItems = [];
40
+ for (const item of items){
41
+ if (parentId === item.parentId) {
42
+ treeItems.push(item, ...recursive ? getChildTreeItems(items, item.itemId, recursive) : []);
42
43
  }
43
- return [
44
- ...list,
45
- item,
46
- ...recursive ? getChildTreeItems(items, item.itemId, recursive) : []
47
- ];
48
- }, []);
44
+ }
45
+ return treeItems;
49
46
  }
50
47
 
51
48
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tree/utils.ts"],"sourcesContent":["import {\n type DefaultTreeItemNode,\n type TreeData,\n type TreeItemNode,\n} from \"./types.js\";\n\n/**\n * This will get all the items from the provided itemId up to the root of the\n * tree that can be used for drag and drop behavior or building a breadcrumb\n * list.\n *\n * @param data - The flattened tree data to navigate.\n * @param itemId - The item id to start the search at.\n * @returns an ordered list of the current item followed by all the direct\n * parents of that item.\n * @since 6.0.0 Renamed from `getItemsFrom` to `getTreeItemsFrom`.\n */\nexport function getTreeItemsFrom<T extends TreeItemNode = DefaultTreeItemNode>(\n data: TreeData<T>,\n itemId: string | null\n): readonly T[] {\n const items: T[] = [];\n let currentId = itemId;\n while (currentId) {\n const item = data[currentId];\n currentId = item?.parentId ?? null;\n if (item) {\n items.push(item);\n }\n }\n\n return items;\n}\n\n/**\n * Gets all the child items for a specific parent item id. If the `recursive`\n * argument is enabled, all children of the items will also be returned instead\n * of only the top level items.\n *\n * @param data - Either the flattened tree data or a list of all the tree data\n * to iterate over\n * @param parentId - The parent id to get children of\n * @param recursive - Boolean if the children's children should also be returned\n * @returns a list of all the items for a specific parent item id. Note: if the\n * recursive param is enabled, the list will be ordered so that the children of\n * a item will appear before the next item at the same level. So you either need\n * to sort by `parentId` or something else if you want a specific order.\n * @since 6.0.0 Renamed from `getChildItems` to `getChildTreeItems`.\n */\nexport function getChildTreeItems<T extends TreeItemNode = DefaultTreeItemNode>(\n data: TreeData<T> | readonly T[],\n parentId: string | null,\n recursive = false\n): readonly T[] {\n const items: readonly T[] = Array.isArray(data) ? data : Object.values(data);\n\n return items.reduce<T[]>((list, item) => {\n if (parentId !== item.parentId) {\n return list;\n }\n\n return [\n ...list,\n item,\n ...(recursive ? getChildTreeItems(items, item.itemId, recursive) : []),\n ];\n }, []);\n}\n"],"names":["getTreeItemsFrom","data","itemId","items","currentId","item","parentId","push","getChildTreeItems","recursive","Array","isArray","Object","values","reduce","list"],"mappings":"AAMA;;;;;;;;;;CAUC,GACD,OAAO,SAASA,iBACdC,IAAiB,EACjBC,MAAqB;IAErB,MAAMC,QAAa,EAAE;IACrB,IAAIC,YAAYF;IAChB,MAAOE,UAAW;QAChB,MAAMC,OAAOJ,IAAI,CAACG,UAAU;QAC5BA,YAAYC,MAAMC,YAAY;QAC9B,IAAID,MAAM;YACRF,MAAMI,IAAI,CAACF;QACb;IACF;IAEA,OAAOF;AACT;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASK,kBACdP,IAAgC,EAChCK,QAAuB,EACvBG,YAAY,KAAK;IAEjB,MAAMN,QAAsBO,MAAMC,OAAO,CAACV,QAAQA,OAAOW,OAAOC,MAAM,CAACZ;IAEvE,OAAOE,MAAMW,MAAM,CAAM,CAACC,MAAMV;QAC9B,IAAIC,aAAaD,KAAKC,QAAQ,EAAE;YAC9B,OAAOS;QACT;QAEA,OAAO;eACFA;YACHV;eACII,YAAYD,kBAAkBL,OAAOE,KAAKH,MAAM,EAAEO,aAAa,EAAE;SACtE;IACH,GAAG,EAAE;AACP"}
1
+ {"version":3,"sources":["../../src/tree/utils.ts"],"sourcesContent":["import {\n type DefaultTreeItemNode,\n type TreeData,\n type TreeItemNode,\n} from \"./types.js\";\n\n/**\n * This will get all the items from the provided itemId up to the root of the\n * tree that can be used for drag and drop behavior or building a breadcrumb\n * list.\n *\n * @param data - The flattened tree data to navigate.\n * @param itemId - The item id to start the search at.\n * @returns an ordered list of the current item followed by all the direct\n * parents of that item.\n * @since 6.0.0 Renamed from `getItemsFrom` to `getTreeItemsFrom`.\n */\nexport function getTreeItemsFrom<T extends TreeItemNode = DefaultTreeItemNode>(\n data: TreeData<T>,\n itemId: string | null\n): readonly T[] {\n const items: T[] = [];\n let currentId = itemId;\n while (currentId) {\n const item = data[currentId];\n currentId = item?.parentId ?? null;\n if (item) {\n items.push(item);\n }\n }\n\n return items;\n}\n\n/**\n * Gets all the child items for a specific parent item id. If the `recursive`\n * argument is enabled, all children of the items will also be returned instead\n * of only the top level items.\n *\n * @param data - Either the flattened tree data or a list of all the tree data\n * to iterate over\n * @param parentId - The parent id to get children of\n * @param recursive - Boolean if the children's children should also be returned\n * @returns a list of all the items for a specific parent item id. Note: if the\n * recursive param is enabled, the list will be ordered so that the children of\n * a item will appear before the next item at the same level. So you either need\n * to sort by `parentId` or something else if you want a specific order.\n * @since 6.0.0 Renamed from `getChildItems` to `getChildTreeItems`.\n */\nexport function getChildTreeItems<T extends TreeItemNode = DefaultTreeItemNode>(\n data: TreeData<T> | readonly T[],\n parentId: string | null,\n recursive = false\n): readonly T[] {\n const items: readonly T[] = Array.isArray(data) ? data : Object.values(data);\n\n const treeItems: T[] = [];\n for (const item of items) {\n if (parentId === item.parentId) {\n treeItems.push(\n item,\n ...(recursive ? getChildTreeItems(items, item.itemId, recursive) : [])\n );\n }\n }\n\n return treeItems;\n}\n"],"names":["getTreeItemsFrom","data","itemId","items","currentId","item","parentId","push","getChildTreeItems","recursive","Array","isArray","Object","values","treeItems"],"mappings":"AAMA;;;;;;;;;;CAUC,GACD,OAAO,SAASA,iBACdC,IAAiB,EACjBC,MAAqB;IAErB,MAAMC,QAAa,EAAE;IACrB,IAAIC,YAAYF;IAChB,MAAOE,UAAW;QAChB,MAAMC,OAAOJ,IAAI,CAACG,UAAU;QAC5BA,YAAYC,MAAMC,YAAY;QAC9B,IAAID,MAAM;YACRF,MAAMI,IAAI,CAACF;QACb;IACF;IAEA,OAAOF;AACT;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASK,kBACdP,IAAgC,EAChCK,QAAuB,EACvBG,YAAY,KAAK;IAEjB,MAAMN,QAAsBO,MAAMC,OAAO,CAACV,QAAQA,OAAOW,OAAOC,MAAM,CAACZ;IAEvE,MAAMa,YAAiB,EAAE;IACzB,KAAK,MAAMT,QAAQF,MAAO;QACxB,IAAIG,aAAaD,KAAKC,QAAQ,EAAE;YAC9BQ,UAAUP,IAAI,CACZF,SACII,YAAYD,kBAAkBL,OAAOE,KAAKH,MAAM,EAAEO,aAAa,EAAE;QAEzE;IACF;IAEA,OAAOK;AACT"}
@@ -51,7 +51,8 @@ const SPECIAL_CHARACTERS_REGEXP = /[.*+?^${}()|[\]\\]/g;
51
51
  }
52
52
  const parts = [];
53
53
  const text = removeAccents(child).trim();
54
- const regex = new RegExp("(" + cleanQuery.replace(SPECIAL_CHARACTERS_REGEXP, "\\$&") + ")", "gi");
54
+ const escapedQuery = cleanQuery.replaceAll(SPECIAL_CHARACTERS_REGEXP, String.raw`\$&`);
55
+ const regex = new RegExp(`(${escapedQuery})`, "gi");
55
56
  let match;
56
57
  let lastIndex = 0;
57
58
  while((match = regex.exec(text)) !== null){
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/typography/HighlightText.tsx"],"sourcesContent":["import {\n Children,\n type ComponentType,\n type ReactElement,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { remove as removeAccents } from \"remove-accents\";\n\nimport { HighlightTextMark } from \"./HighlightTextMark.js\";\n\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_special_characters\nconst SPECIAL_CHARACTERS_REGEXP = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextMatch {\n /**\n * The cleaned query that has diacritics, leading whitespace, and trailing\n * whitespace removed.\n */\n query: string;\n\n /**\n * The raw query string that was provided.\n */\n rawQuery: string;\n\n /**\n * The full untouched text content for the HighlightText component.\n */\n rawText: string;\n\n /**\n * The current index in the {@link rawText} that is being matched against.\n */\n index: number;\n\n /**\n * The last index the query has been matched.\n */\n lastIndex: number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextComponentProps {\n /** {@inheritDoc HighlightTextMatch} */\n match: HighlightTextMatch;\n\n /**\n * The matched content.\n */\n children: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport type HighlightTextComponent = ComponentType<HighlightTextComponentProps>;\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextProps {\n /**\n * This prop can be used to provide a custom highlight behavior. It will be\n * provided the {@link HighlightTextComponentProps}\n *\n * @defaultValue `HighlightTextMark`\n */\n highlight?: HighlightTextComponent;\n\n /**\n * The query text to highlight in the children. When this is an empty string\n * or whitespace only, nothing will be highlighted.\n */\n query: string;\n\n /**\n * The content to highlight based on the query text where highlighting only\n * works for text children. The component will attempt to find all child text\n * using the `React.Children` API, but might be inconsistent.\n */\n children: ReactNode;\n\n /**\n * Set to `true` if only the first match should be highlighted instead of all\n * occurrences.\n *\n * @defaultValue `false`\n */\n firstMatchOnly?: boolean;\n}\n\n/**\n * The `HighlightText` component can be used to highlight text matching the\n * provided query ignoring case.\n *\n * @example Simple Example\n * ```tsx\n * import { HighlightText } from \"@react-md/core/typography/HighlightText\";\n * import { Typography } from \"@react-md/core/typography/Typography\";\n * import { type ReactElement } from \"react\";\n *\n * export default function SimpleExample(): ReactElement {\n * return (\n * <Typography>\n * <HighlightText query=\"lorem ipsum\">\n * Lorem ipsum dolor sit amet, consectetur adipiscing elit. In eget metus\n * ut mi mattis dapibus. Praesent interdum sapien ut posuere convallis.\n * Donec et tristique ex. Aliquam erat volutpat. Donec sit amet dui\n * egestas, tempus quam id, hendrerit risus. Nullam tincidunt quam ut dui\n * aliquet ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing\n * elit. Sed rhoncus, purus vitae tincidunt placerat, quam diam lobortis\n * magna, et aliquam ante diam id nunc. Cras blandit leo eu nisi\n * elementum, nec gravida ligula pharetra. Etiam molestie luctus orci,\n * vel hendrerit lacus eleifend ut. Nullam placerat dolor ac mi congue,\n * non auctor metus consectetur. Ut pretium mollis vulputate.\n * </HighlightText>\n * </Typography>\n * );\n * }\n *\n * ```\n * @see {@link https://react-md.dev/components/highlight-text | HighlightText Demos}\n * @since 6.0.0\n */\nexport function HighlightText(\n props: Readonly<HighlightTextProps>\n): ReactElement {\n const {\n query,\n children,\n highlight: Highlight = HighlightTextMark,\n firstMatchOnly,\n } = props;\n\n return (\n <>\n {useMemo<ReactNode>(\n () =>\n Children.map(children, (child) => {\n if (!query || !child || typeof child !== \"string\") {\n return child;\n }\n\n const cleanQuery = removeAccents(query).trim();\n if (!cleanQuery) {\n return <>{child}</>;\n }\n\n const parts: ReactNode[] = [];\n const text = removeAccents(child).trim();\n const regex = new RegExp(\n \"(\" + cleanQuery.replace(SPECIAL_CHARACTERS_REGEXP, \"\\\\$&\") + \")\",\n \"gi\"\n );\n\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n while ((match = regex.exec(text)) !== null) {\n const { index } = match;\n if (index > lastIndex) {\n parts.push(child.slice(lastIndex, index));\n }\n\n ({ lastIndex } = regex);\n parts.push(\n <Highlight\n key={index}\n match={{\n index,\n lastIndex,\n query: cleanQuery,\n rawQuery: query,\n rawText: child,\n }}\n >\n {child.slice(index, lastIndex)}\n </Highlight>\n );\n\n if (firstMatchOnly) {\n break;\n }\n }\n\n if (lastIndex < child.length) {\n parts.push(child.slice(lastIndex));\n }\n\n return parts;\n }),\n [Highlight, children, firstMatchOnly, query]\n )}\n </>\n );\n}\n"],"names":["Children","useMemo","remove","removeAccents","HighlightTextMark","SPECIAL_CHARACTERS_REGEXP","HighlightText","props","query","children","highlight","Highlight","firstMatchOnly","map","child","cleanQuery","trim","parts","text","regex","RegExp","replace","match","lastIndex","exec","index","push","slice","rawQuery","rawText","length"],"mappings":";AAAA,SACEA,QAAQ,EAIRC,OAAO,QACF,QAAQ;AACf,SAASC,UAAUC,aAAa,QAAQ,iBAAiB;AAEzD,SAASC,iBAAiB,QAAQ,yBAAyB;AAE3D,0GAA0G;AAC1G,MAAMC,4BAA4B;AAqFlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCC,GACD,OAAO,SAASC,cACdC,KAAmC;IAEnC,MAAM,EACJC,KAAK,EACLC,QAAQ,EACRC,WAAWC,YAAYP,iBAAiB,EACxCQ,cAAc,EACf,GAAGL;IAEJ,qBACE;kBACGN,QACC,IACED,SAASa,GAAG,CAACJ,UAAU,CAACK;gBACtB,IAAI,CAACN,SAAS,CAACM,SAAS,OAAOA,UAAU,UAAU;oBACjD,OAAOA;gBACT;gBAEA,MAAMC,aAAaZ,cAAcK,OAAOQ,IAAI;gBAC5C,IAAI,CAACD,YAAY;oBACf,qBAAO;kCAAGD;;gBACZ;gBAEA,MAAMG,QAAqB,EAAE;gBAC7B,MAAMC,OAAOf,cAAcW,OAAOE,IAAI;gBACtC,MAAMG,QAAQ,IAAIC,OAChB,MAAML,WAAWM,OAAO,CAAChB,2BAA2B,UAAU,KAC9D;gBAGF,IAAIiB;gBACJ,IAAIC,YAAY;gBAChB,MAAO,AAACD,CAAAA,QAAQH,MAAMK,IAAI,CAACN,KAAI,MAAO,KAAM;oBAC1C,MAAM,EAAEO,KAAK,EAAE,GAAGH;oBAClB,IAAIG,QAAQF,WAAW;wBACrBN,MAAMS,IAAI,CAACZ,MAAMa,KAAK,CAACJ,WAAWE;oBACpC;oBAEC,CAAA,EAAEF,SAAS,EAAE,GAAGJ,KAAI;oBACrBF,MAAMS,IAAI,eACR,KAACf;wBAECW,OAAO;4BACLG;4BACAF;4BACAf,OAAOO;4BACPa,UAAUpB;4BACVqB,SAASf;wBACX;kCAECA,MAAMa,KAAK,CAACF,OAAOF;uBATfE;oBAaT,IAAIb,gBAAgB;wBAClB;oBACF;gBACF;gBAEA,IAAIW,YAAYT,MAAMgB,MAAM,EAAE;oBAC5Bb,MAAMS,IAAI,CAACZ,MAAMa,KAAK,CAACJ;gBACzB;gBAEA,OAAON;YACT,IACF;YAACN;YAAWF;YAAUG;YAAgBJ;SAAM;;AAIpD"}
1
+ {"version":3,"sources":["../../src/typography/HighlightText.tsx"],"sourcesContent":["import {\n Children,\n type ComponentType,\n type ReactElement,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { remove as removeAccents } from \"remove-accents\";\n\nimport { HighlightTextMark } from \"./HighlightTextMark.js\";\n\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_special_characters\nconst SPECIAL_CHARACTERS_REGEXP = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextMatch {\n /**\n * The cleaned query that has diacritics, leading whitespace, and trailing\n * whitespace removed.\n */\n query: string;\n\n /**\n * The raw query string that was provided.\n */\n rawQuery: string;\n\n /**\n * The full untouched text content for the HighlightText component.\n */\n rawText: string;\n\n /**\n * The current index in the {@link rawText} that is being matched against.\n */\n index: number;\n\n /**\n * The last index the query has been matched.\n */\n lastIndex: number;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextComponentProps {\n /** {@inheritDoc HighlightTextMatch} */\n match: HighlightTextMatch;\n\n /**\n * The matched content.\n */\n children: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport type HighlightTextComponent = ComponentType<HighlightTextComponentProps>;\n\n/**\n * @since 6.0.0\n */\nexport interface HighlightTextProps {\n /**\n * This prop can be used to provide a custom highlight behavior. It will be\n * provided the {@link HighlightTextComponentProps}\n *\n * @defaultValue `HighlightTextMark`\n */\n highlight?: HighlightTextComponent;\n\n /**\n * The query text to highlight in the children. When this is an empty string\n * or whitespace only, nothing will be highlighted.\n */\n query: string;\n\n /**\n * The content to highlight based on the query text where highlighting only\n * works for text children. The component will attempt to find all child text\n * using the `React.Children` API, but might be inconsistent.\n */\n children: ReactNode;\n\n /**\n * Set to `true` if only the first match should be highlighted instead of all\n * occurrences.\n *\n * @defaultValue `false`\n */\n firstMatchOnly?: boolean;\n}\n\n/**\n * The `HighlightText` component can be used to highlight text matching the\n * provided query ignoring case.\n *\n * @example Simple Example\n * ```tsx\n * import { HighlightText } from \"@react-md/core/typography/HighlightText\";\n * import { Typography } from \"@react-md/core/typography/Typography\";\n * import { type ReactElement } from \"react\";\n *\n * export default function SimpleExample(): ReactElement {\n * return (\n * <Typography>\n * <HighlightText query=\"lorem ipsum\">\n * Lorem ipsum dolor sit amet, consectetur adipiscing elit. In eget metus\n * ut mi mattis dapibus. Praesent interdum sapien ut posuere convallis.\n * Donec et tristique ex. Aliquam erat volutpat. Donec sit amet dui\n * egestas, tempus quam id, hendrerit risus. Nullam tincidunt quam ut dui\n * aliquet ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing\n * elit. Sed rhoncus, purus vitae tincidunt placerat, quam diam lobortis\n * magna, et aliquam ante diam id nunc. Cras blandit leo eu nisi\n * elementum, nec gravida ligula pharetra. Etiam molestie luctus orci,\n * vel hendrerit lacus eleifend ut. Nullam placerat dolor ac mi congue,\n * non auctor metus consectetur. Ut pretium mollis vulputate.\n * </HighlightText>\n * </Typography>\n * );\n * }\n *\n * ```\n * @see {@link https://react-md.dev/components/highlight-text | HighlightText Demos}\n * @since 6.0.0\n */\nexport function HighlightText(\n props: Readonly<HighlightTextProps>\n): ReactElement {\n const {\n query,\n children,\n highlight: Highlight = HighlightTextMark,\n firstMatchOnly,\n } = props;\n\n return (\n <>\n {useMemo<ReactNode>(\n () =>\n Children.map(children, (child) => {\n if (!query || !child || typeof child !== \"string\") {\n return child;\n }\n\n const cleanQuery = removeAccents(query).trim();\n if (!cleanQuery) {\n return <>{child}</>;\n }\n\n const parts: ReactNode[] = [];\n const text = removeAccents(child).trim();\n const escapedQuery = cleanQuery.replaceAll(\n SPECIAL_CHARACTERS_REGEXP,\n String.raw`\\$&`\n );\n const regex = new RegExp(`(${escapedQuery})`, \"gi\");\n\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n while ((match = regex.exec(text)) !== null) {\n const { index } = match;\n if (index > lastIndex) {\n parts.push(child.slice(lastIndex, index));\n }\n\n ({ lastIndex } = regex);\n parts.push(\n <Highlight\n key={index}\n match={{\n index,\n lastIndex,\n query: cleanQuery,\n rawQuery: query,\n rawText: child,\n }}\n >\n {child.slice(index, lastIndex)}\n </Highlight>\n );\n\n if (firstMatchOnly) {\n break;\n }\n }\n\n if (lastIndex < child.length) {\n parts.push(child.slice(lastIndex));\n }\n\n return parts;\n }),\n [Highlight, children, firstMatchOnly, query]\n )}\n </>\n );\n}\n"],"names":["Children","useMemo","remove","removeAccents","HighlightTextMark","SPECIAL_CHARACTERS_REGEXP","HighlightText","props","query","children","highlight","Highlight","firstMatchOnly","map","child","cleanQuery","trim","parts","text","escapedQuery","replaceAll","String","raw","regex","RegExp","match","lastIndex","exec","index","push","slice","rawQuery","rawText","length"],"mappings":";AAAA,SACEA,QAAQ,EAIRC,OAAO,QACF,QAAQ;AACf,SAASC,UAAUC,aAAa,QAAQ,iBAAiB;AAEzD,SAASC,iBAAiB,QAAQ,yBAAyB;AAE3D,0GAA0G;AAC1G,MAAMC,4BAA4B;AAqFlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCC,GACD,OAAO,SAASC,cACdC,KAAmC;IAEnC,MAAM,EACJC,KAAK,EACLC,QAAQ,EACRC,WAAWC,YAAYP,iBAAiB,EACxCQ,cAAc,EACf,GAAGL;IAEJ,qBACE;kBACGN,QACC,IACED,SAASa,GAAG,CAACJ,UAAU,CAACK;gBACtB,IAAI,CAACN,SAAS,CAACM,SAAS,OAAOA,UAAU,UAAU;oBACjD,OAAOA;gBACT;gBAEA,MAAMC,aAAaZ,cAAcK,OAAOQ,IAAI;gBAC5C,IAAI,CAACD,YAAY;oBACf,qBAAO;kCAAGD;;gBACZ;gBAEA,MAAMG,QAAqB,EAAE;gBAC7B,MAAMC,OAAOf,cAAcW,OAAOE,IAAI;gBACtC,MAAMG,eAAeJ,WAAWK,UAAU,CACxCf,2BACAgB,OAAOC,GAAG,CAAC,GAAG,CAAC;gBAEjB,MAAMC,QAAQ,IAAIC,OAAO,CAAC,CAAC,EAAEL,aAAa,CAAC,CAAC,EAAE;gBAE9C,IAAIM;gBACJ,IAAIC,YAAY;gBAChB,MAAO,AAACD,CAAAA,QAAQF,MAAMI,IAAI,CAACT,KAAI,MAAO,KAAM;oBAC1C,MAAM,EAAEU,KAAK,EAAE,GAAGH;oBAClB,IAAIG,QAAQF,WAAW;wBACrBT,MAAMY,IAAI,CAACf,MAAMgB,KAAK,CAACJ,WAAWE;oBACpC;oBAEC,CAAA,EAAEF,SAAS,EAAE,GAAGH,KAAI;oBACrBN,MAAMY,IAAI,eACR,KAAClB;wBAECc,OAAO;4BACLG;4BACAF;4BACAlB,OAAOO;4BACPgB,UAAUvB;4BACVwB,SAASlB;wBACX;kCAECA,MAAMgB,KAAK,CAACF,OAAOF;uBATfE;oBAaT,IAAIhB,gBAAgB;wBAClB;oBACF;gBACF;gBAEA,IAAIc,YAAYZ,MAAMmB,MAAM,EAAE;oBAC5BhB,MAAMY,IAAI,CAACf,MAAMgB,KAAK,CAACJ;gBACzB;gBAEA,OAAOT;YACT,IACF;YAACN;YAAWF;YAAUG;YAAgBJ;SAAM;;AAIpD"}
@@ -29,12 +29,18 @@ import { cssUtils } from "../cssUtils.js";
29
29
  const { as: AsComponent = "span", className, phoneOnly, focusable, children, tabIndex, ...remaining } = props;
30
30
  // do some type-casting so ref works
31
31
  const Component = AsComponent;
32
+ let srOnly = true;
33
+ if (focusable) {
34
+ srOnly = "focusable";
35
+ } else if (phoneOnly) {
36
+ srOnly = "phone";
37
+ }
32
38
  return /*#__PURE__*/ _jsx(Component, {
33
39
  ...remaining,
34
40
  ref: ref,
35
41
  tabIndex: tabIndex ?? (focusable ? 0 : undefined),
36
42
  className: cssUtils({
37
- srOnly: focusable ? "focusable" : phoneOnly ? "phone" : true,
43
+ srOnly,
38
44
  className
39
45
  }),
40
46
  children: children