@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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/positioning/utils.ts"],"sourcesContent":["import { type PositionAnchor } from \"./types.js\";\n\n/** @internal */\nexport interface XCoordConfig {\n xMargin: number;\n elWidth: number;\n initialX?: number;\n containerRect: DOMRect;\n}\n\n/** @internal */\nexport interface YCoordConfig {\n yMargin: number;\n elHeight: number;\n initialY?: number;\n containerRect: DOMRect;\n}\n\ntype Left = number;\ntype Top = number;\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * (outer) left of the container element. So the right bounds of the fixed\n * element will be equal to the left bounds of the container element (before the\n * xMargin is applied).\n *\n * @internal\n */\nexport function getLeftCoord({\n xMargin,\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left) - elWidth - xMargin;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * inner-left of the container element. So the left bounds of both the container\n * and fixed elements will overlap (before the xMargin is applied)\n *\n * @internal\n */\nexport function getInnerLeftCoord({\n xMargin,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left) + xMargin;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * center of the container element. So the center point of the fixed element\n * should be the center point of the container element.\n *\n * Note: Unlike all the other horizontal positioning logic, the center position\n * does not use the xMargin.\n *\n * @internal\n */\nexport function getCenterXCoord({\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n const containerCenter = containerRect.width / 2;\n const elementCenter = elWidth / 2;\n return (initialX ?? containerRect.left + containerCenter) - elementCenter;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * inner-right of the container element. So the right bounds for both the\n * container and fixed elements will overlap (before the xMargin is applied).\n *\n * @internal\n */\nexport function getInnerRightCoord({\n xMargin,\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (\n (initialX ?? containerRect.left + containerRect.width) - elWidth - xMargin\n );\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * (outer) right of the container element. So the left bounds of the fixed\n * element will overlap with the right bounds of the container element (before\n * the xMargin is applied).\n *\n * @internal\n */\nexport function getRightCoord({\n xMargin,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left + containerRect.width) + xMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed above the\n * container element. So the bottom bounds of the fixed element will overlap\n * with the top bounds of the container element (before the yMargin is applied).\n *\n * @internal\n */\nexport function getAboveCoord({\n yMargin,\n initialY,\n elHeight,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top) - elHeight - yMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the top\n * of the container element. So the top bounds for both the container and fixed\n * elements will overlap (before the yMargin is applied).\n *\n * @internal\n */\nexport function getTopCoord({\n yMargin,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top) + yMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed vertically\n * centered relative to the container element. So the vertical center point for\n * the fixed element should overlap the vertical center point of the container\n * element.\n *\n * Note: Unlike all the other vertical positioning logic, the center position\n * does not use the yMargin.\n *\n * @internal\n */\nexport function getCenterYCoord({\n yMargin,\n elHeight,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n const containerCenter = containerRect.height / 2;\n const elementCenter = elHeight / 2;\n return (\n (initialY ?? containerRect.top + containerCenter + yMargin) - elementCenter\n );\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the\n * bottom of the container element. So the top bounds of the fixed element\n * should overlap the bottom bounds of the container element (before the yMargin\n * is applied).\n *\n * @internal\n */\nexport function getBottomCoord({\n yMargin,\n initialY,\n elHeight,\n containerRect,\n}: YCoordConfig): Top {\n return (\n (initialY ?? containerRect.top + containerRect.height) - elHeight - yMargin\n );\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the\n * bottom of the container element. So the bottom bounds of both the container\n * and fixed elements should overlap (before the yMargin is applied).\n *\n * @internal\n */\nexport function getBelowCoord({\n yMargin,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top + containerRect.height) + yMargin;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface TransformOriginOptions extends PositionAnchor {\n transformOriginY?: number;\n}\n\n/**\n * This is a simple util that'll generate a css `transform-origin` string so\n * that the fixed element can animate from the correct point based on the\n * provided anchor.\n *\n * @param options - The anchor that should be used to create the transform origin\n * for.\n * @returns the transform origin string\n * @internal\n */\nexport function getTransformOrigin(options: TransformOriginOptions): string {\n const { transformOriginY: yPosition } = options;\n\n let x = \"0\";\n switch (options.x) {\n case \"right\":\n case \"inner-left\":\n x = \"0\";\n break;\n case \"center\":\n x = \"50%\";\n break;\n case \"left\":\n case \"inner-right\":\n x = \"100%\";\n break;\n default:\n x = \"0\";\n }\n\n let y = \"0\";\n if (typeof yPosition === \"number\") {\n y = `${yPosition}px`;\n } else {\n switch (options.y) {\n case \"above\":\n case \"bottom\":\n y = \"100%\";\n break;\n case \"center\":\n y = \"50%\";\n break;\n case \"below\":\n case \"top\":\n y = \"0\";\n break;\n default:\n y = \"0\";\n }\n }\n\n return `${x} ${y}`;\n}\n\n/**\n * Attempts to find a sizing container based on the provided HTMLElement. By\n * default, the sizing element will just be the provided element unless:\n * - the item has a known role within react-md that can target known classes\n * - the item has a `data-sizing-selector` attribute that is a valid query\n * selector for the nested item.\n *\n * NOTE: The `data-sizing-selector` will be run from the current element instead\n * of the `document`.\n *\n * @param el - The element to find a sizing container for.\n * @returns the sizing container relative to the provided element, or `null` if\n * none could be found.\n * @throws This error will be thrown if using the `data-query-selector` and the\n * query selector does not return an element on the page.\n * @internal\n */\nexport function findSizingContainer(\n el: HTMLElement | null\n): HTMLElement | null {\n if (!el) {\n return null;\n }\n\n if (/(tree|list)item/.test(el.getAttribute(\"role\") || \"\")) {\n const content = el.querySelector(\n \".rmd-tree-item__content, .rmd-item-text\"\n ) as HTMLElement;\n if (content) {\n return content;\n }\n } else if (el.getAttribute(\"type\") === \"file\") {\n const label = document.querySelector<HTMLLabelElement>(`[for=\"${el.id}\"]`);\n if (label) {\n return label;\n }\n }\n\n const data = el.getAttribute(\"data-sizing-selector\");\n if (data) {\n const content = el.querySelector(data) as HTMLElement;\n if (content) {\n return content;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n throw new Error(\n \"Unable to find a child element using the `data-sizing-selector`\"\n );\n }\n }\n\n return el;\n}\n\n/**\n * This util is used to get the \"true\" `element.getBoundingClientRect()` that\n * ensures that transitions using transforms don't mess up the sizing so that\n * position calculations are easier to do.\n *\n * @param element - The element to get a rect for.\n * @returns either a DOMRect for the element\n * @internal\n */\nexport function getElementRect(element: HTMLElement): DOMRect {\n const cloned = element.cloneNode(true) as HTMLElement;\n // remove the id so there won't be two elements with the same id on the page\n cloned.removeAttribute(\"id\");\n\n // remove the role just in case the role would alert screen readers once added\n // to the dom\n cloned.removeAttribute(\"role\");\n\n // ensure the cloned node won't shift the page or be visible\n cloned.style.position = \"fixed\";\n cloned.style.visibility = \"hidden\";\n\n // reset positioning to get a \"pure\" calculation. otherwise this will mess up\n // the height and width if the element is able to line wrap.\n cloned.style.left = \"\";\n cloned.style.top = \"\";\n cloned.style.right = \"\";\n cloned.style.bottom = \"\";\n\n // reset transforms so that custom animations don't mess with the sizing\n cloned.style.transform = \"none\";\n\n const parent = element.parentElement || document.body;\n parent.appendChild(cloned);\n\n const rect = cloned.getBoundingClientRect();\n parent.removeChild(cloned);\n\n return rect;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\ninterface IsWithinViewportOptions {\n fixedElement: HTMLElement;\n fixedToElement: HTMLElement;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function isWithinViewport(options: IsWithinViewportOptions): boolean {\n const { fixedElement, fixedToElement } = options;\n const fixedElementRect = fixedElement.getBoundingClientRect();\n const fixedToElementRect = fixedToElement.getBoundingClientRect();\n const vh = window.innerHeight;\n const vw = window.innerWidth;\n const top = Math.min(fixedElementRect.top, fixedToElementRect.top);\n const right = Math.max(fixedElementRect.right, fixedToElementRect.right);\n const bottom = Math.max(fixedElementRect.bottom, fixedToElementRect.bottom);\n const left = Math.min(fixedElementRect.left, fixedToElementRect.left);\n\n return bottom >= 0 && top <= vh && right >= 0 && left <= vw;\n}\n"],"names":["getLeftCoord","xMargin","elWidth","initialX","containerRect","left","getInnerLeftCoord","getCenterXCoord","containerCenter","width","elementCenter","getInnerRightCoord","getRightCoord","getAboveCoord","yMargin","initialY","elHeight","top","getTopCoord","getCenterYCoord","height","getBottomCoord","getBelowCoord","getTransformOrigin","options","transformOriginY","yPosition","x","y","findSizingContainer","el","test","getAttribute","content","querySelector","label","document","id","data","process","env","NODE_ENV","Error","getElementRect","element","cloned","cloneNode","removeAttribute","style","position","visibility","right","bottom","transform","parent","parentElement","body","appendChild","rect","getBoundingClientRect","removeChild","isWithinViewport","fixedElement","fixedToElement","fixedElementRect","fixedToElementRect","vh","window","innerHeight","vw","innerWidth","Math","min","max"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/positioning/utils.ts"],"sourcesContent":["import { type PositionAnchor } from \"./types.js\";\n\n/** @internal */\nexport interface XCoordConfig {\n xMargin: number;\n elWidth: number;\n initialX?: number;\n containerRect: DOMRect;\n}\n\n/** @internal */\nexport interface YCoordConfig {\n yMargin: number;\n elHeight: number;\n initialY?: number;\n containerRect: DOMRect;\n}\n\ntype Left = number;\ntype Top = number;\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * (outer) left of the container element. So the right bounds of the fixed\n * element will be equal to the left bounds of the container element (before the\n * xMargin is applied).\n *\n * @internal\n */\nexport function getLeftCoord({\n xMargin,\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left) - elWidth - xMargin;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * inner-left of the container element. So the left bounds of both the container\n * and fixed elements will overlap (before the xMargin is applied)\n *\n * @internal\n */\nexport function getInnerLeftCoord({\n xMargin,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left) + xMargin;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * center of the container element. So the center point of the fixed element\n * should be the center point of the container element.\n *\n * Note: Unlike all the other horizontal positioning logic, the center position\n * does not use the xMargin.\n *\n * @internal\n */\nexport function getCenterXCoord({\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n const containerCenter = containerRect.width / 2;\n const elementCenter = elWidth / 2;\n return (initialX ?? containerRect.left + containerCenter) - elementCenter;\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * inner-right of the container element. So the right bounds for both the\n * container and fixed elements will overlap (before the xMargin is applied).\n *\n * @internal\n */\nexport function getInnerRightCoord({\n xMargin,\n elWidth,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (\n (initialX ?? containerRect.left + containerRect.width) - elWidth - xMargin\n );\n}\n\n/**\n * Creates the `left` style value for an element that should be fixed to the\n * (outer) right of the container element. So the left bounds of the fixed\n * element will overlap with the right bounds of the container element (before\n * the xMargin is applied).\n *\n * @internal\n */\nexport function getRightCoord({\n xMargin,\n initialX,\n containerRect,\n}: XCoordConfig): Left {\n return (initialX ?? containerRect.left + containerRect.width) + xMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed above the\n * container element. So the bottom bounds of the fixed element will overlap\n * with the top bounds of the container element (before the yMargin is applied).\n *\n * @internal\n */\nexport function getAboveCoord({\n yMargin,\n initialY,\n elHeight,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top) - elHeight - yMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the top\n * of the container element. So the top bounds for both the container and fixed\n * elements will overlap (before the yMargin is applied).\n *\n * @internal\n */\nexport function getTopCoord({\n yMargin,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top) + yMargin;\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed vertically\n * centered relative to the container element. So the vertical center point for\n * the fixed element should overlap the vertical center point of the container\n * element.\n *\n * Note: Unlike all the other vertical positioning logic, the center position\n * does not use the yMargin.\n *\n * @internal\n */\nexport function getCenterYCoord({\n yMargin,\n elHeight,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n const containerCenter = containerRect.height / 2;\n const elementCenter = elHeight / 2;\n return (\n (initialY ?? containerRect.top + containerCenter + yMargin) - elementCenter\n );\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the\n * bottom of the container element. So the top bounds of the fixed element\n * should overlap the bottom bounds of the container element (before the yMargin\n * is applied).\n *\n * @internal\n */\nexport function getBottomCoord({\n yMargin,\n initialY,\n elHeight,\n containerRect,\n}: YCoordConfig): Top {\n return (\n (initialY ?? containerRect.top + containerRect.height) - elHeight - yMargin\n );\n}\n\n/**\n * Creates the `top` style value for an element that should be fixed to the\n * bottom of the container element. So the bottom bounds of both the container\n * and fixed elements should overlap (before the yMargin is applied).\n *\n * @internal\n */\nexport function getBelowCoord({\n yMargin,\n initialY,\n containerRect,\n}: YCoordConfig): Top {\n return (initialY ?? containerRect.top + containerRect.height) + yMargin;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface TransformOriginOptions extends PositionAnchor {\n transformOriginY?: number;\n}\n\n/**\n * This is a simple util that'll generate a css `transform-origin` string so\n * that the fixed element can animate from the correct point based on the\n * provided anchor.\n *\n * @param options - The anchor that should be used to create the transform origin\n * for.\n * @returns the transform origin string\n * @internal\n */\nexport function getTransformOrigin(options: TransformOriginOptions): string {\n const { transformOriginY: yPosition } = options;\n\n let x = \"0\";\n switch (options.x) {\n case \"right\":\n case \"inner-left\":\n x = \"0\";\n break;\n case \"center\":\n x = \"50%\";\n break;\n case \"left\":\n case \"inner-right\":\n x = \"100%\";\n break;\n default:\n x = \"0\";\n }\n\n let y = \"0\";\n if (typeof yPosition === \"number\") {\n y = `${yPosition}px`;\n } else {\n switch (options.y) {\n case \"above\":\n case \"bottom\":\n y = \"100%\";\n break;\n case \"center\":\n y = \"50%\";\n break;\n case \"below\":\n case \"top\":\n y = \"0\";\n break;\n default:\n y = \"0\";\n }\n }\n\n return `${x} ${y}`;\n}\n\n/**\n * Attempts to find a sizing container based on the provided HTMLElement. By\n * default, the sizing element will just be the provided element unless:\n * - the item has a known role within react-md that can target known classes\n * - the item has a `data-sizing-selector` attribute that is a valid query\n * selector for the nested item.\n *\n * NOTE: The `data-sizing-selector` will be run from the current element instead\n * of the `document`.\n *\n * @param el - The element to find a sizing container for.\n * @returns the sizing container relative to the provided element, or `null` if\n * none could be found.\n * @throws This error will be thrown if using the `data-query-selector` and the\n * query selector does not return an element on the page.\n * @internal\n */\nexport function findSizingContainer(\n el: HTMLElement | null\n): HTMLElement | null {\n if (!el) {\n return null;\n }\n\n if (/(tree|list)item/.test(el.getAttribute(\"role\") || \"\")) {\n const content = el.querySelector(\n \".rmd-tree-item__content, .rmd-item-text\"\n ) as HTMLElement;\n if (content) {\n return content;\n }\n } else if (el.getAttribute(\"type\") === \"file\") {\n const label = document.querySelector<HTMLLabelElement>(`[for=\"${el.id}\"]`);\n if (label) {\n return label;\n }\n }\n\n const data = el.dataset.sizingSelector;\n if (data) {\n const content = el.querySelector(data) as HTMLElement;\n if (content) {\n return content;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n throw new Error(\n \"Unable to find a child element using the `data-sizing-selector`\"\n );\n }\n }\n\n return el;\n}\n\n/**\n * This util is used to get the \"true\" `element.getBoundingClientRect()` that\n * ensures that transitions using transforms don't mess up the sizing so that\n * position calculations are easier to do.\n *\n * @param element - The element to get a rect for.\n * @returns either a DOMRect for the element\n * @internal\n */\nexport function getElementRect(element: HTMLElement): DOMRect {\n const cloned = element.cloneNode(true) as HTMLElement;\n // remove the id so there won't be two elements with the same id on the page\n cloned.removeAttribute(\"id\");\n\n // remove the role just in case the role would alert screen readers once added\n // to the dom\n cloned.removeAttribute(\"role\");\n\n // ensure the cloned node won't shift the page or be visible\n cloned.style.position = \"fixed\";\n cloned.style.visibility = \"hidden\";\n\n // reset positioning to get a \"pure\" calculation. otherwise this will mess up\n // the height and width if the element is able to line wrap.\n cloned.style.left = \"\";\n cloned.style.top = \"\";\n cloned.style.right = \"\";\n cloned.style.bottom = \"\";\n\n // reset transforms so that custom animations don't mess with the sizing\n cloned.style.transform = \"none\";\n\n const parent = element.parentElement || document.body;\n parent.append(cloned);\n\n const rect = cloned.getBoundingClientRect();\n cloned.remove();\n\n return rect;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\ninterface IsWithinViewportOptions {\n fixedElement: HTMLElement;\n fixedToElement: HTMLElement;\n}\n\n/**\n * @since 4.0.0\n * @internal\n */\nexport function isWithinViewport(options: IsWithinViewportOptions): boolean {\n const { fixedElement, fixedToElement } = options;\n const fixedElementRect = fixedElement.getBoundingClientRect();\n const fixedToElementRect = fixedToElement.getBoundingClientRect();\n const vh = window.innerHeight;\n const vw = window.innerWidth;\n const top = Math.min(fixedElementRect.top, fixedToElementRect.top);\n const right = Math.max(fixedElementRect.right, fixedToElementRect.right);\n const bottom = Math.max(fixedElementRect.bottom, fixedToElementRect.bottom);\n const left = Math.min(fixedElementRect.left, fixedToElementRect.left);\n\n return bottom >= 0 && top <= vh && right >= 0 && left <= vw;\n}\n"],"names":["getLeftCoord","xMargin","elWidth","initialX","containerRect","left","getInnerLeftCoord","getCenterXCoord","containerCenter","width","elementCenter","getInnerRightCoord","getRightCoord","getAboveCoord","yMargin","initialY","elHeight","top","getTopCoord","getCenterYCoord","height","getBottomCoord","getBelowCoord","getTransformOrigin","options","transformOriginY","yPosition","x","y","findSizingContainer","el","test","getAttribute","content","querySelector","label","document","id","data","dataset","sizingSelector","process","env","NODE_ENV","Error","getElementRect","element","cloned","cloneNode","removeAttribute","style","position","visibility","right","bottom","transform","parent","parentElement","body","append","rect","getBoundingClientRect","remove","isWithinViewport","fixedElement","fixedToElement","fixedElementRect","fixedToElementRect","vh","window","innerHeight","vw","innerWidth","Math","min","max"],"mappings":"AAqBA;;;;;;;CAOC,GACD,OAAO,SAASA,aAAa,EAC3BC,OAAO,EACPC,OAAO,EACPC,QAAQ,EACRC,aAAa,EACA;IACb,OAAO,AAACD,CAAAA,YAAYC,cAAcC,IAAI,AAAD,IAAKH,UAAUD;AACtD;AAEA;;;;;;CAMC,GACD,OAAO,SAASK,kBAAkB,EAChCL,OAAO,EACPE,QAAQ,EACRC,aAAa,EACA;IACb,OAAO,AAACD,CAAAA,YAAYC,cAAcC,IAAI,AAAD,IAAKJ;AAC5C;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASM,gBAAgB,EAC9BL,OAAO,EACPC,QAAQ,EACRC,aAAa,EACA;IACb,MAAMI,kBAAkBJ,cAAcK,KAAK,GAAG;IAC9C,MAAMC,gBAAgBR,UAAU;IAChC,OAAO,AAACC,CAAAA,YAAYC,cAAcC,IAAI,GAAGG,eAAc,IAAKE;AAC9D;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,mBAAmB,EACjCV,OAAO,EACPC,OAAO,EACPC,QAAQ,EACRC,aAAa,EACA;IACb,OACE,AAACD,CAAAA,YAAYC,cAAcC,IAAI,GAAGD,cAAcK,KAAK,AAAD,IAAKP,UAAUD;AAEvE;AAEA;;;;;;;CAOC,GACD,OAAO,SAASW,cAAc,EAC5BX,OAAO,EACPE,QAAQ,EACRC,aAAa,EACA;IACb,OAAO,AAACD,CAAAA,YAAYC,cAAcC,IAAI,GAAGD,cAAcK,KAAK,AAAD,IAAKR;AAClE;AAEA;;;;;;CAMC,GACD,OAAO,SAASY,cAAc,EAC5BC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRZ,aAAa,EACA;IACb,OAAO,AAACW,CAAAA,YAAYX,cAAca,GAAG,AAAD,IAAKD,WAAWF;AACtD;AAEA;;;;;;CAMC,GACD,OAAO,SAASI,YAAY,EAC1BJ,OAAO,EACPC,QAAQ,EACRX,aAAa,EACA;IACb,OAAO,AAACW,CAAAA,YAAYX,cAAca,GAAG,AAAD,IAAKH;AAC3C;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASK,gBAAgB,EAC9BL,OAAO,EACPE,QAAQ,EACRD,QAAQ,EACRX,aAAa,EACA;IACb,MAAMI,kBAAkBJ,cAAcgB,MAAM,GAAG;IAC/C,MAAMV,gBAAgBM,WAAW;IACjC,OACE,AAACD,CAAAA,YAAYX,cAAca,GAAG,GAAGT,kBAAkBM,OAAM,IAAKJ;AAElE;AAEA;;;;;;;CAOC,GACD,OAAO,SAASW,eAAe,EAC7BP,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRZ,aAAa,EACA;IACb,OACE,AAACW,CAAAA,YAAYX,cAAca,GAAG,GAAGb,cAAcgB,MAAM,AAAD,IAAKJ,WAAWF;AAExE;AAEA;;;;;;CAMC,GACD,OAAO,SAASQ,cAAc,EAC5BR,OAAO,EACPC,QAAQ,EACRX,aAAa,EACA;IACb,OAAO,AAACW,CAAAA,YAAYX,cAAca,GAAG,GAAGb,cAAcgB,MAAM,AAAD,IAAKN;AAClE;AAUA;;;;;;;;;CASC,GACD,OAAO,SAASS,mBAAmBC,OAA+B;IAChE,MAAM,EAAEC,kBAAkBC,SAAS,EAAE,GAAGF;IAExC,IAAIG,IAAI;IACR,OAAQH,QAAQG,CAAC;QACf,KAAK;QACL,KAAK;YACHA,IAAI;YACJ;QACF,KAAK;YACHA,IAAI;YACJ;QACF,KAAK;QACL,KAAK;YACHA,IAAI;YACJ;QACF;YACEA,IAAI;IACR;IAEA,IAAIC,IAAI;IACR,IAAI,OAAOF,cAAc,UAAU;QACjCE,IAAI,GAAGF,UAAU,EAAE,CAAC;IACtB,OAAO;QACL,OAAQF,QAAQI,CAAC;YACf,KAAK;YACL,KAAK;gBACHA,IAAI;gBACJ;YACF,KAAK;gBACHA,IAAI;gBACJ;YACF,KAAK;YACL,KAAK;gBACHA,IAAI;gBACJ;YACF;gBACEA,IAAI;QACR;IACF;IAEA,OAAO,GAAGD,EAAE,CAAC,EAAEC,GAAG;AACpB;AAEA;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,SAASC,oBACdC,EAAsB;IAEtB,IAAI,CAACA,IAAI;QACP,OAAO;IACT;IAEA,IAAI,kBAAkBC,IAAI,CAACD,GAAGE,YAAY,CAAC,WAAW,KAAK;QACzD,MAAMC,UAAUH,GAAGI,aAAa,CAC9B;QAEF,IAAID,SAAS;YACX,OAAOA;QACT;IACF,OAAO,IAAIH,GAAGE,YAAY,CAAC,YAAY,QAAQ;QAC7C,MAAMG,QAAQC,SAASF,aAAa,CAAmB,CAAC,MAAM,EAAEJ,GAAGO,EAAE,CAAC,EAAE,CAAC;QACzE,IAAIF,OAAO;YACT,OAAOA;QACT;IACF;IAEA,MAAMG,OAAOR,GAAGS,OAAO,CAACC,cAAc;IACtC,IAAIF,MAAM;QACR,MAAML,UAAUH,GAAGI,aAAa,CAACI;QACjC,IAAIL,SAAS;YACX,OAAOA;QACT;QAEA,IAAIQ,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,MAAM,IAAIC,MACR;QAEJ;IACF;IAEA,OAAOd;AACT;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASe,eAAeC,OAAoB;IACjD,MAAMC,SAASD,QAAQE,SAAS,CAAC;IACjC,4EAA4E;IAC5ED,OAAOE,eAAe,CAAC;IAEvB,8EAA8E;IAC9E,aAAa;IACbF,OAAOE,eAAe,CAAC;IAEvB,4DAA4D;IAC5DF,OAAOG,KAAK,CAACC,QAAQ,GAAG;IACxBJ,OAAOG,KAAK,CAACE,UAAU,GAAG;IAE1B,6EAA6E;IAC7E,4DAA4D;IAC5DL,OAAOG,KAAK,CAAC7C,IAAI,GAAG;IACpB0C,OAAOG,KAAK,CAACjC,GAAG,GAAG;IACnB8B,OAAOG,KAAK,CAACG,KAAK,GAAG;IACrBN,OAAOG,KAAK,CAACI,MAAM,GAAG;IAEtB,wEAAwE;IACxEP,OAAOG,KAAK,CAACK,SAAS,GAAG;IAEzB,MAAMC,SAASV,QAAQW,aAAa,IAAIrB,SAASsB,IAAI;IACrDF,OAAOG,MAAM,CAACZ;IAEd,MAAMa,OAAOb,OAAOc,qBAAqB;IACzCd,OAAOe,MAAM;IAEb,OAAOF;AACT;AAWA;;;CAGC,GACD,OAAO,SAASG,iBAAiBvC,OAAgC;IAC/D,MAAM,EAAEwC,YAAY,EAAEC,cAAc,EAAE,GAAGzC;IACzC,MAAM0C,mBAAmBF,aAAaH,qBAAqB;IAC3D,MAAMM,qBAAqBF,eAAeJ,qBAAqB;IAC/D,MAAMO,KAAKC,OAAOC,WAAW;IAC7B,MAAMC,KAAKF,OAAOG,UAAU;IAC5B,MAAMvD,MAAMwD,KAAKC,GAAG,CAACR,iBAAiBjD,GAAG,EAAEkD,mBAAmBlD,GAAG;IACjE,MAAMoC,QAAQoB,KAAKE,GAAG,CAACT,iBAAiBb,KAAK,EAAEc,mBAAmBd,KAAK;IACvE,MAAMC,SAASmB,KAAKE,GAAG,CAACT,iBAAiBZ,MAAM,EAAEa,mBAAmBb,MAAM;IAC1E,MAAMjD,OAAOoE,KAAKC,GAAG,CAACR,iBAAiB7D,IAAI,EAAE8D,mBAAmB9D,IAAI;IAEpE,OAAOiD,UAAU,KAAKrC,OAAOmD,MAAMf,SAAS,KAAKhD,QAAQkE;AAC3D"}
@@ -2,7 +2,7 @@ let cache;
2
2
  /**
3
3
  * @internal
4
4
  */ export function getScrollbarWidth(force = false) {
5
- /* istanbul ignore if */ if (typeof window === "undefined") {
5
+ /* istanbul ignore if */ if (globalThis.window === undefined) {
6
6
  return 0;
7
7
  }
8
8
  let value = cache;
@@ -12,14 +12,14 @@ let cache;
12
12
  const outer = document.createElement("div");
13
13
  outer.style.visibility = "hidden";
14
14
  outer.style.overflow = "scroll";
15
- document.body.appendChild(outer);
15
+ document.body.append(outer);
16
16
  const inner = document.createElement("div");
17
- outer.appendChild(inner);
17
+ outer.append(inner);
18
18
  // the scrollbar width can be determined by comparing the width of the parent
19
19
  // element that has scrollbars to the child element that does not.
20
20
  value = outer.offsetWidth - inner.offsetWidth;
21
21
  cache = value;
22
- document.body.removeChild(outer);
22
+ outer.remove();
23
23
  return value;
24
24
  }
25
25
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/scroll/getScrollbarWidth.ts"],"sourcesContent":["let cache: number | undefined;\n\n/**\n * @internal\n */\nexport function getScrollbarWidth(force = false): number {\n /* istanbul ignore if */\n if (typeof window === \"undefined\") {\n return 0;\n }\n\n let value = cache;\n if (!force && typeof value === \"number\") {\n return value;\n }\n\n const outer = document.createElement(\"div\");\n outer.style.visibility = \"hidden\";\n outer.style.overflow = \"scroll\";\n document.body.appendChild(outer);\n\n const inner = document.createElement(\"div\");\n outer.appendChild(inner);\n\n // the scrollbar width can be determined by comparing the width of the parent\n // element that has scrollbars to the child element that does not.\n value = outer.offsetWidth - inner.offsetWidth;\n cache = value;\n document.body.removeChild(outer);\n\n return value;\n}\n"],"names":["cache","getScrollbarWidth","force","window","value","outer","document","createElement","style","visibility","overflow","body","appendChild","inner","offsetWidth","removeChild"],"mappings":"AAAA,IAAIA;AAEJ;;CAEC,GACD,OAAO,SAASC,kBAAkBC,QAAQ,KAAK;IAC7C,sBAAsB,GACtB,IAAI,OAAOC,WAAW,aAAa;QACjC,OAAO;IACT;IAEA,IAAIC,QAAQJ;IACZ,IAAI,CAACE,SAAS,OAAOE,UAAU,UAAU;QACvC,OAAOA;IACT;IAEA,MAAMC,QAAQC,SAASC,aAAa,CAAC;IACrCF,MAAMG,KAAK,CAACC,UAAU,GAAG;IACzBJ,MAAMG,KAAK,CAACE,QAAQ,GAAG;IACvBJ,SAASK,IAAI,CAACC,WAAW,CAACP;IAE1B,MAAMQ,QAAQP,SAASC,aAAa,CAAC;IACrCF,MAAMO,WAAW,CAACC;IAElB,6EAA6E;IAC7E,kEAAkE;IAClET,QAAQC,MAAMS,WAAW,GAAGD,MAAMC,WAAW;IAC7Cd,QAAQI;IACRE,SAASK,IAAI,CAACI,WAAW,CAACV;IAE1B,OAAOD;AACT"}
1
+ {"version":3,"sources":["../../src/scroll/getScrollbarWidth.ts"],"sourcesContent":["let cache: number | undefined;\n\n/**\n * @internal\n */\nexport function getScrollbarWidth(force = false): number {\n /* istanbul ignore if */\n if (globalThis.window === undefined) {\n return 0;\n }\n\n let value = cache;\n if (!force && typeof value === \"number\") {\n return value;\n }\n\n const outer = document.createElement(\"div\");\n outer.style.visibility = \"hidden\";\n outer.style.overflow = \"scroll\";\n document.body.append(outer);\n\n const inner = document.createElement(\"div\");\n outer.append(inner);\n\n // the scrollbar width can be determined by comparing the width of the parent\n // element that has scrollbars to the child element that does not.\n value = outer.offsetWidth - inner.offsetWidth;\n cache = value;\n outer.remove();\n\n return value;\n}\n"],"names":["cache","getScrollbarWidth","force","globalThis","window","undefined","value","outer","document","createElement","style","visibility","overflow","body","append","inner","offsetWidth","remove"],"mappings":"AAAA,IAAIA;AAEJ;;CAEC,GACD,OAAO,SAASC,kBAAkBC,QAAQ,KAAK;IAC7C,sBAAsB,GACtB,IAAIC,WAAWC,MAAM,KAAKC,WAAW;QACnC,OAAO;IACT;IAEA,IAAIC,QAAQN;IACZ,IAAI,CAACE,SAAS,OAAOI,UAAU,UAAU;QACvC,OAAOA;IACT;IAEA,MAAMC,QAAQC,SAASC,aAAa,CAAC;IACrCF,MAAMG,KAAK,CAACC,UAAU,GAAG;IACzBJ,MAAMG,KAAK,CAACE,QAAQ,GAAG;IACvBJ,SAASK,IAAI,CAACC,MAAM,CAACP;IAErB,MAAMQ,QAAQP,SAASC,aAAa,CAAC;IACrCF,MAAMO,MAAM,CAACC;IAEb,6EAA6E;IAC7E,kEAAkE;IAClET,QAAQC,MAAMS,WAAW,GAAGD,MAAMC,WAAW;IAC7ChB,QAAQM;IACRC,MAAMU,MAAM;IAEZ,OAAOX;AACT"}
@@ -34,8 +34,9 @@ import { defaultExtractor, search } from "./utils.js";
34
34
  * @since 6.0.0
35
35
  * @see {@link fuzzySearch}
36
36
  */ export function createFuzzyRegExp(query) {
37
- return new RegExp(query.split("").join("\\w*").replace(/(\(|\||\)|\\(?!w\*)|\[|\|-|\.|\^|\+|\$|\?|^(?!w)\*)/g, "\\$1")// Couldn't get the matching of two '*' working, so replace them here..
38
- .replace(/\*\*/g, "*\\*"), "i");
37
+ return new RegExp(query// eslint-disable-next-line unicorn/prefer-spread
38
+ .split("").join(String.raw`\w*`).replaceAll(/(\(|\||\)|\\(?!w\*)|\[|\|-|\.|\^|\+|\$|\?|^(?!w)\*)/g, String.raw`\$1`)// Couldn't get the matching of two '*' working, so replace them here..
39
+ .replaceAll("**", String.raw`*\*`), "i");
39
40
  }
40
41
  export function fuzzySearch(options) {
41
42
  const { list, type = "filter", query, extractor = DEFAULT_EXTRACTOR, whitespace } = options;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/searching/fuzzy.ts"],"sourcesContent":["import { type AutomaticTextExtraction, type TextExtractor } from \"../types.js\";\nimport { type BaseSearchOptions } from \"./types.js\";\nimport { defaultExtractor, search } from \"./utils.js\";\n\n/**\n * @since 6.2.0\n * @internal\n */\nconst DEFAULT_EXTRACTOR = defaultExtractor(\"fuzzySearch\");\n\n/**\n * @example\n * ```tsx\n * import { createFuzzyRegExp } from \"@react-md/core/searching/fuzzy\":\n * import { toSearchQuery } from \"@react-md/core/searching/toSearchQuery\":\n * import { useDeferredValue, useMemo, useState, type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState(\"\");\n * const deferredValue = useDeferredValue(value)\n *\n * const match = useMemo(() => {\n * const query = toSearchQuery(deferredValue);\n * if (!query) {\n * return;\n * }\n *\n * const fuzzyRegExp = createFuzzyRegExp(query);\n * return options.find(option => fuzzyRegExp.test(option.label)):\n * }, [options])\n *\n * if (match) {\n * // do something\n * }\n * }\n *\n * ```\n *\n * @since 6.0.0\n * @see {@link fuzzySearch}\n */\nexport function createFuzzyRegExp(query: string): RegExp {\n return new RegExp(\n query\n .split(\"\")\n .join(\"\\\\w*\")\n .replace(/(\\(|\\||\\)|\\\\(?!w\\*)|\\[|\\|-|\\.|\\^|\\+|\\$|\\?|^(?!w)\\*)/g, \"\\\\$1\")\n // Couldn't get the matching of two '*' working, so replace them here..\n .replace(/\\*\\*/g, \"*\\\\*\"),\n \"i\"\n );\n}\n\n/**\n * @since 6.0.0\n */\nexport type FuzzySearchOptions<T> = BaseSearchOptions<T>;\n\n/**\n * Filters a list by making sure that all the letters appear in order ignoring\n * case, punctuation, whitespace, and special characters. This is kind of the\n * same filtering that appears in text editors.\n *\n * @example Simple Example\n * ```ts\n * const list = [\n * \"at\",\n * \"charAt\",\n * \"charCodeAt\",\n * \"codePointAt\",\n * \"concat\",\n * \"constructor\",\n * \"endsWith\",\n * \"includes\",\n * \"indexOf\",\n * \"lastIndexOf\",\n * \"length\",\n * \"localeCompare\",\n * \"match\",\n * \"matchAll\",\n * \"normalize\",\n * \"padEnd\",\n * \"padStart\",\n * \"repeat\",\n * \"replace\",\n * \"replaceAll\",\n * \"search\",\n * \"slice\",\n * \"split\",\n * \"startsWith\",\n * \"substring\",\n * \"toLocaleLowerCase\",\n * \"toLocaleUpperCase\",\n * \"toLowerCase\",\n * \"toString\",\n * \"toUpperCase\",\n * \"trim\",\n * \"trimEnd\",\n * \"trimStart\",\n * \"valueOf\",\n * ];\n *\n * fuzzySearch({\n * list,\n * query: \"la\",\n * });\n * // [\n * // \"lastIndexOf\",\n * // ^^\n * // \"localeCompare\",\n * // ^ ^\n * // \"replace\",\n * // ^^\n * // \"replaceAll\",\n * // ^^\n * // \"toLocaleLowerCase\",\n * // ^ ^\n * // \"toLocaleUpperCase\",\n * // ^ ^\n * // \"toLowerCase\",\n * // ^ ^\n * // ]\n *\n * fuzzySearch({\n * list,\n * query: \"ad\",\n * type: \"search\",\n * });\n * // \"charCodeAt\"\n * // ^ ^\n * ```\n *\n * @since 6.0.0\n */\nexport function fuzzySearch<T extends AutomaticTextExtraction>(\n options: FuzzySearchOptions<T> & { type?: \"filter\" }\n): readonly T[];\nexport function fuzzySearch<T extends AutomaticTextExtraction>(\n options: FuzzySearchOptions<T> & { type?: \"search\" }\n): T | undefined;\nexport function fuzzySearch<T>(\n option: FuzzySearchOptions<T> & {\n extractor: TextExtractor<T>;\n type?: \"filter\";\n }\n): readonly T[];\nexport function fuzzySearch<T>(\n option: FuzzySearchOptions<T> & {\n extractor: TextExtractor<T>;\n type?: \"search\";\n }\n): T | undefined;\nexport function fuzzySearch<T>(\n options: FuzzySearchOptions<T>\n): readonly T[] | T | undefined {\n const {\n list,\n type = \"filter\",\n query,\n extractor = DEFAULT_EXTRACTOR,\n whitespace,\n } = options;\n\n // lazy initialize the RegExp since the base `filter` function will modify the\n // query and never call the filter function if:\n // - there is no query\n // - the list is empty\n let regexp: RegExp;\n return search({\n type,\n list,\n query,\n extractor,\n whitespace,\n filter(query, value) {\n return (\n value.length > 0 && (regexp ??= createFuzzyRegExp(query)).test(value)\n );\n },\n });\n}\n"],"names":["defaultExtractor","search","DEFAULT_EXTRACTOR","createFuzzyRegExp","query","RegExp","split","join","replace","fuzzySearch","options","list","type","extractor","whitespace","regexp","filter","value","length","test"],"mappings":"AAEA,SAASA,gBAAgB,EAAEC,MAAM,QAAQ,aAAa;AAEtD;;;CAGC,GACD,MAAMC,oBAAoBF,iBAAiB;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,OAAO,SAASG,kBAAkBC,KAAa;IAC7C,OAAO,IAAIC,OACTD,MACGE,KAAK,CAAC,IACNC,IAAI,CAAC,QACLC,OAAO,CAAC,wDAAwD,OACjE,uEAAuE;KACtEA,OAAO,CAAC,SAAS,SACpB;AAEJ;AAqGA,OAAO,SAASC,YACdC,OAA8B;IAE9B,MAAM,EACJC,IAAI,EACJC,OAAO,QAAQ,EACfR,KAAK,EACLS,YAAYX,iBAAiB,EAC7BY,UAAU,EACX,GAAGJ;IAEJ,8EAA8E;IAC9E,+CAA+C;IAC/C,sBAAsB;IACtB,sBAAsB;IACtB,IAAIK;IACJ,OAAOd,OAAO;QACZW;QACAD;QACAP;QACAS;QACAC;QACAE,QAAOZ,KAAK,EAAEa,KAAK;YACjB,OACEA,MAAMC,MAAM,GAAG,KAAK,AAACH,CAAAA,WAAWZ,kBAAkBC,MAAK,EAAGe,IAAI,CAACF;QAEnE;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/searching/fuzzy.ts"],"sourcesContent":["import { type AutomaticTextExtraction, type TextExtractor } from \"../types.js\";\nimport { type BaseSearchOptions } from \"./types.js\";\nimport { defaultExtractor, search } from \"./utils.js\";\n\n/**\n * @since 6.2.0\n * @internal\n */\nconst DEFAULT_EXTRACTOR = defaultExtractor(\"fuzzySearch\");\n\n/**\n * @example\n * ```tsx\n * import { createFuzzyRegExp } from \"@react-md/core/searching/fuzzy\":\n * import { toSearchQuery } from \"@react-md/core/searching/toSearchQuery\":\n * import { useDeferredValue, useMemo, useState, type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const [value, setValue] = useState(\"\");\n * const deferredValue = useDeferredValue(value)\n *\n * const match = useMemo(() => {\n * const query = toSearchQuery(deferredValue);\n * if (!query) {\n * return;\n * }\n *\n * const fuzzyRegExp = createFuzzyRegExp(query);\n * return options.find(option => fuzzyRegExp.test(option.label)):\n * }, [options])\n *\n * if (match) {\n * // do something\n * }\n * }\n *\n * ```\n *\n * @since 6.0.0\n * @see {@link fuzzySearch}\n */\nexport function createFuzzyRegExp(query: string): RegExp {\n return new RegExp(\n query\n // eslint-disable-next-line unicorn/prefer-spread\n .split(\"\")\n .join(String.raw`\\w*`)\n .replaceAll(\n /(\\(|\\||\\)|\\\\(?!w\\*)|\\[|\\|-|\\.|\\^|\\+|\\$|\\?|^(?!w)\\*)/g,\n String.raw`\\$1`\n )\n // Couldn't get the matching of two '*' working, so replace them here..\n .replaceAll(\"**\", String.raw`*\\*`),\n \"i\"\n );\n}\n\n/**\n * @since 6.0.0\n */\nexport type FuzzySearchOptions<T> = BaseSearchOptions<T>;\n\n/**\n * Filters a list by making sure that all the letters appear in order ignoring\n * case, punctuation, whitespace, and special characters. This is kind of the\n * same filtering that appears in text editors.\n *\n * @example Simple Example\n * ```ts\n * const list = [\n * \"at\",\n * \"charAt\",\n * \"charCodeAt\",\n * \"codePointAt\",\n * \"concat\",\n * \"constructor\",\n * \"endsWith\",\n * \"includes\",\n * \"indexOf\",\n * \"lastIndexOf\",\n * \"length\",\n * \"localeCompare\",\n * \"match\",\n * \"matchAll\",\n * \"normalize\",\n * \"padEnd\",\n * \"padStart\",\n * \"repeat\",\n * \"replace\",\n * \"replaceAll\",\n * \"search\",\n * \"slice\",\n * \"split\",\n * \"startsWith\",\n * \"substring\",\n * \"toLocaleLowerCase\",\n * \"toLocaleUpperCase\",\n * \"toLowerCase\",\n * \"toString\",\n * \"toUpperCase\",\n * \"trim\",\n * \"trimEnd\",\n * \"trimStart\",\n * \"valueOf\",\n * ];\n *\n * fuzzySearch({\n * list,\n * query: \"la\",\n * });\n * // [\n * // \"lastIndexOf\",\n * // ^^\n * // \"localeCompare\",\n * // ^ ^\n * // \"replace\",\n * // ^^\n * // \"replaceAll\",\n * // ^^\n * // \"toLocaleLowerCase\",\n * // ^ ^\n * // \"toLocaleUpperCase\",\n * // ^ ^\n * // \"toLowerCase\",\n * // ^ ^\n * // ]\n *\n * fuzzySearch({\n * list,\n * query: \"ad\",\n * type: \"search\",\n * });\n * // \"charCodeAt\"\n * // ^ ^\n * ```\n *\n * @since 6.0.0\n */\nexport function fuzzySearch<T extends AutomaticTextExtraction>(\n options: FuzzySearchOptions<T> & { type?: \"filter\" }\n): readonly T[];\nexport function fuzzySearch<T extends AutomaticTextExtraction>(\n options: FuzzySearchOptions<T> & { type?: \"search\" }\n): T | undefined;\nexport function fuzzySearch<T>(\n option: FuzzySearchOptions<T> & {\n extractor: TextExtractor<T>;\n type?: \"filter\";\n }\n): readonly T[];\nexport function fuzzySearch<T>(\n option: FuzzySearchOptions<T> & {\n extractor: TextExtractor<T>;\n type?: \"search\";\n }\n): T | undefined;\nexport function fuzzySearch<T>(\n options: FuzzySearchOptions<T>\n): readonly T[] | T | undefined {\n const {\n list,\n type = \"filter\",\n query,\n extractor = DEFAULT_EXTRACTOR,\n whitespace,\n } = options;\n\n // lazy initialize the RegExp since the base `filter` function will modify the\n // query and never call the filter function if:\n // - there is no query\n // - the list is empty\n let regexp: RegExp;\n return search({\n type,\n list,\n query,\n extractor,\n whitespace,\n filter(query, value) {\n return (\n value.length > 0 && (regexp ??= createFuzzyRegExp(query)).test(value)\n );\n },\n });\n}\n"],"names":["defaultExtractor","search","DEFAULT_EXTRACTOR","createFuzzyRegExp","query","RegExp","split","join","String","raw","replaceAll","fuzzySearch","options","list","type","extractor","whitespace","regexp","filter","value","length","test"],"mappings":"AAEA,SAASA,gBAAgB,EAAEC,MAAM,QAAQ,aAAa;AAEtD;;;CAGC,GACD,MAAMC,oBAAoBF,iBAAiB;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,OAAO,SAASG,kBAAkBC,KAAa;IAC7C,OAAO,IAAIC,OACTD,KACE,iDAAiD;KAChDE,KAAK,CAAC,IACNC,IAAI,CAACC,OAAOC,GAAG,CAAC,GAAG,CAAC,EACpBC,UAAU,CACT,wDACAF,OAAOC,GAAG,CAAC,GAAG,CAAC,CAEjB,uEAAuE;KACtEC,UAAU,CAAC,MAAMF,OAAOC,GAAG,CAAC,GAAG,CAAC,GACnC;AAEJ;AAqGA,OAAO,SAASE,YACdC,OAA8B;IAE9B,MAAM,EACJC,IAAI,EACJC,OAAO,QAAQ,EACfV,KAAK,EACLW,YAAYb,iBAAiB,EAC7Bc,UAAU,EACX,GAAGJ;IAEJ,8EAA8E;IAC9E,+CAA+C;IAC/C,sBAAsB;IACtB,sBAAsB;IACtB,IAAIK;IACJ,OAAOhB,OAAO;QACZa;QACAD;QACAT;QACAW;QACAC;QACAE,QAAOd,KAAK,EAAEe,KAAK;YACjB,OACEA,MAAMC,MAAM,GAAG,KAAK,AAACH,CAAAA,WAAWd,kBAAkBC,MAAK,EAAGiB,IAAI,CAACF;QAEnE;IACF;AACF"}
@@ -5,7 +5,7 @@
5
5
  */ export function toSearchQuery(s, whitespace = "keep") {
6
6
  let q = s.toLowerCase();
7
7
  if (whitespace === "ignore") {
8
- q = q.replace(/\s/g, "");
8
+ q = q.replaceAll(/\s/g, "");
9
9
  } else if (whitespace === "trim") {
10
10
  q = q.trim();
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/searching/toSearchQuery.ts"],"sourcesContent":["import { type WhitespaceFilter } from \"./types.js\";\n\n/**\n * @param s - The string to convert\n * @param whitespace - (default: `\"keep\"`)\n * @since 6.0.0\n */\nexport function toSearchQuery(\n s: string,\n whitespace: WhitespaceFilter = \"keep\"\n): string {\n let q = s.toLowerCase();\n if (whitespace === \"ignore\") {\n q = q.replace(/\\s/g, \"\");\n } else if (whitespace === \"trim\") {\n q = q.trim();\n }\n\n return q;\n}\n"],"names":["toSearchQuery","s","whitespace","q","toLowerCase","replace","trim"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,SAASA,cACdC,CAAS,EACTC,aAA+B,MAAM;IAErC,IAAIC,IAAIF,EAAEG,WAAW;IACrB,IAAIF,eAAe,UAAU;QAC3BC,IAAIA,EAAEE,OAAO,CAAC,OAAO;IACvB,OAAO,IAAIH,eAAe,QAAQ;QAChCC,IAAIA,EAAEG,IAAI;IACZ;IAEA,OAAOH;AACT"}
1
+ {"version":3,"sources":["../../src/searching/toSearchQuery.ts"],"sourcesContent":["import { type WhitespaceFilter } from \"./types.js\";\n\n/**\n * @param s - The string to convert\n * @param whitespace - (default: `\"keep\"`)\n * @since 6.0.0\n */\nexport function toSearchQuery(\n s: string,\n whitespace: WhitespaceFilter = \"keep\"\n): string {\n let q = s.toLowerCase();\n if (whitespace === \"ignore\") {\n q = q.replaceAll(/\\s/g, \"\");\n } else if (whitespace === \"trim\") {\n q = q.trim();\n }\n\n return q;\n}\n"],"names":["toSearchQuery","s","whitespace","q","toLowerCase","replaceAll","trim"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,SAASA,cACdC,CAAS,EACTC,aAA+B,MAAM;IAErC,IAAIC,IAAIF,EAAEG,WAAW;IACrB,IAAIF,eAAe,UAAU;QAC3BC,IAAIA,EAAEE,UAAU,CAAC,OAAO;IAC1B,OAAO,IAAIH,eAAe,QAAQ;QAChCC,IAAIA,EAAEG,IAAI;IACZ;IAEA,OAAOH;AACT"}
@@ -23,7 +23,7 @@ import { toSearchQuery } from "./toSearchQuery.js";
23
23
  */ export function search(options) {
24
24
  const { list, type, query, filter, extractor, whitespace = "keep" } = options;
25
25
  const fallback = type === "search" ? undefined : list;
26
- if (!list.length) {
26
+ if (list.length === 0) {
27
27
  return fallback;
28
28
  }
29
29
  const q = toSearchQuery(query, whitespace);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/searching/utils.ts"],"sourcesContent":["import { type TextExtractor } from \"../types.js\";\nimport { toSearchQuery } from \"./toSearchQuery.js\";\nimport { type BaseSearchOptions } from \"./types.js\";\n\n/**\n * @since 6.0.0\n * @since 6.2.0 Added support for `item.name` and `item.label`.\n * @internal\n */\nexport const defaultExtractor =\n (usageName: string, propName = \"extractor\") =>\n (item: unknown): string => {\n if (typeof item === \"string\") {\n return item;\n }\n\n if (item && typeof item === \"object\") {\n if (\"label\" in item && typeof item.label === \"string\") {\n return item.label;\n }\n\n if (\"name\" in item && typeof item.name === \"string\") {\n return item.name;\n }\n }\n\n throw new Error(\n `\\`${usageName}\\` requires the \\`${propName}\\` prop for lists that do not contain strings or known object types.`\n );\n };\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface SearchOptions<T> extends BaseSearchOptions<T> {\n type: \"search\" | \"filter\";\n filter: (query: string, value: string) => boolean;\n extractor: TextExtractor<T>;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function search<T>(\n options: SearchOptions<T>\n): readonly T[] | T | undefined {\n const { list, type, query, filter, extractor, whitespace = \"keep\" } = options;\n const fallback = type === \"search\" ? undefined : list;\n if (!list.length) {\n return fallback;\n }\n\n const q = toSearchQuery(query, whitespace);\n if (!q) {\n return fallback;\n }\n\n const fn = type === \"search\" ? \"find\" : \"filter\";\n return list[fn]((item) =>\n filter(q, toSearchQuery(extractor(item), whitespace))\n );\n}\n"],"names":["toSearchQuery","defaultExtractor","usageName","propName","item","label","name","Error","search","options","list","type","query","filter","extractor","whitespace","fallback","undefined","length","q","fn"],"mappings":"AACA,SAASA,aAAa,QAAQ,qBAAqB;AAGnD;;;;CAIC,GACD,OAAO,MAAMC,mBACX,CAACC,WAAmBC,WAAW,WAAW,GAC1C,CAACC;QACC,IAAI,OAAOA,SAAS,UAAU;YAC5B,OAAOA;QACT;QAEA,IAAIA,QAAQ,OAAOA,SAAS,UAAU;YACpC,IAAI,WAAWA,QAAQ,OAAOA,KAAKC,KAAK,KAAK,UAAU;gBACrD,OAAOD,KAAKC,KAAK;YACnB;YAEA,IAAI,UAAUD,QAAQ,OAAOA,KAAKE,IAAI,KAAK,UAAU;gBACnD,OAAOF,KAAKE,IAAI;YAClB;QACF;QAEA,MAAM,IAAIC,MACR,CAAC,EAAE,EAAEL,UAAU,kBAAkB,EAAEC,SAAS,oEAAoE,CAAC;IAErH,EAAE;AAYJ;;;CAGC,GACD,OAAO,SAASK,OACdC,OAAyB;IAEzB,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,KAAK,EAAEC,MAAM,EAAEC,SAAS,EAAEC,aAAa,MAAM,EAAE,GAAGN;IACtE,MAAMO,WAAWL,SAAS,WAAWM,YAAYP;IACjD,IAAI,CAACA,KAAKQ,MAAM,EAAE;QAChB,OAAOF;IACT;IAEA,MAAMG,IAAInB,cAAcY,OAAOG;IAC/B,IAAI,CAACI,GAAG;QACN,OAAOH;IACT;IAEA,MAAMI,KAAKT,SAAS,WAAW,SAAS;IACxC,OAAOD,IAAI,CAACU,GAAG,CAAC,CAAChB,OACfS,OAAOM,GAAGnB,cAAcc,UAAUV,OAAOW;AAE7C"}
1
+ {"version":3,"sources":["../../src/searching/utils.ts"],"sourcesContent":["import { type TextExtractor } from \"../types.js\";\nimport { toSearchQuery } from \"./toSearchQuery.js\";\nimport { type BaseSearchOptions } from \"./types.js\";\n\n/**\n * @since 6.0.0\n * @since 6.2.0 Added support for `item.name` and `item.label`.\n * @internal\n */\nexport const defaultExtractor =\n (usageName: string, propName = \"extractor\") =>\n (item: unknown): string => {\n if (typeof item === \"string\") {\n return item;\n }\n\n if (item && typeof item === \"object\") {\n if (\"label\" in item && typeof item.label === \"string\") {\n return item.label;\n }\n\n if (\"name\" in item && typeof item.name === \"string\") {\n return item.name;\n }\n }\n\n throw new Error(\n `\\`${usageName}\\` requires the \\`${propName}\\` prop for lists that do not contain strings or known object types.`\n );\n };\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface SearchOptions<T> extends BaseSearchOptions<T> {\n type: \"search\" | \"filter\";\n filter: (query: string, value: string) => boolean;\n extractor: TextExtractor<T>;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function search<T>(\n options: SearchOptions<T>\n): readonly T[] | T | undefined {\n const { list, type, query, filter, extractor, whitespace = \"keep\" } = options;\n const fallback = type === \"search\" ? undefined : list;\n if (list.length === 0) {\n return fallback;\n }\n\n const q = toSearchQuery(query, whitespace);\n if (!q) {\n return fallback;\n }\n\n const fn = type === \"search\" ? \"find\" : \"filter\";\n return list[fn]((item) =>\n filter(q, toSearchQuery(extractor(item), whitespace))\n );\n}\n"],"names":["toSearchQuery","defaultExtractor","usageName","propName","item","label","name","Error","search","options","list","type","query","filter","extractor","whitespace","fallback","undefined","length","q","fn"],"mappings":"AACA,SAASA,aAAa,QAAQ,qBAAqB;AAGnD;;;;CAIC,GACD,OAAO,MAAMC,mBACX,CAACC,WAAmBC,WAAW,WAAW,GAC1C,CAACC;QACC,IAAI,OAAOA,SAAS,UAAU;YAC5B,OAAOA;QACT;QAEA,IAAIA,QAAQ,OAAOA,SAAS,UAAU;YACpC,IAAI,WAAWA,QAAQ,OAAOA,KAAKC,KAAK,KAAK,UAAU;gBACrD,OAAOD,KAAKC,KAAK;YACnB;YAEA,IAAI,UAAUD,QAAQ,OAAOA,KAAKE,IAAI,KAAK,UAAU;gBACnD,OAAOF,KAAKE,IAAI;YAClB;QACF;QAEA,MAAM,IAAIC,MACR,CAAC,EAAE,EAAEL,UAAU,kBAAkB,EAAEC,SAAS,oEAAoE,CAAC;IAErH,EAAE;AAYJ;;;CAGC,GACD,OAAO,SAASK,OACdC,OAAyB;IAEzB,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,KAAK,EAAEC,MAAM,EAAEC,SAAS,EAAEC,aAAa,MAAM,EAAE,GAAGN;IACtE,MAAMO,WAAWL,SAAS,WAAWM,YAAYP;IACjD,IAAIA,KAAKQ,MAAM,KAAK,GAAG;QACrB,OAAOF;IACT;IAEA,MAAMG,IAAInB,cAAcY,OAAOG;IAC/B,IAAI,CAACI,GAAG;QACN,OAAOH;IACT;IAEA,MAAMI,KAAKT,SAAS,WAAW,SAAS;IACxC,OAAOD,IAAI,CAACU,GAAG,CAAC,CAAChB,OACfS,OAAOM,GAAGnB,cAAcc,UAAUV,OAAOW;AAE7C"}
@@ -37,7 +37,7 @@ import { toast } from "./toastStyles.js";
37
37
  });
38
38
  }
39
39
  let closeIcon = propCloseIcon;
40
- if (typeof closeButtonProps?.children !== "undefined") {
40
+ if (closeButtonProps?.children !== undefined) {
41
41
  closeIcon = closeButtonProps.children;
42
42
  }
43
43
  const action = !!actionButton;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/snackbar/Toast.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type AriaRole,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n forwardRef,\n isValidElement,\n} from \"react\";\n\nimport { type ButtonProps } from \"../button/Button.js\";\nimport {\n type CSSTransitionClassNames,\n type TransitionCallbacks,\n type TransitionTimeout,\n} from \"../transition/types.js\";\nimport { useScaleTransition } from \"../transition/useScaleTransition.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { ToastActionButton } from \"./ToastActionButton.js\";\nimport { ToastCloseButton } from \"./ToastCloseButton.js\";\nimport { ToastContent, type ToastContentProps } from \"./ToastContent.js\";\nimport { type BaseToastClasNameOptions, toast } from \"./toastStyles.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableToastProps\n extends\n HTMLAttributes<HTMLDivElement>,\n BaseToastClasNameOptions,\n TransitionCallbacks {\n /**\n * Note: this default value will only be generated in the `Toast` component.\n *\n * @defaultValue `\"toast-\" + useId()`\n */\n id?: string;\n\n /**\n * Note: This is set while creating the toast.\n *\n * @defaultValue `visibleTime === null ? \"alert\" : \"status\"`\n */\n role?: AriaRole;\n\n /**\n * Set this to `true` to stack the content above the {@link action}. It is not\n * recommended to enable this prop if the {@link closeButton} is enabled.\n *\n * @defaultValue `false`\n */\n stacked?: boolean;\n\n /**\n * If this is not provided, a `ResizeObserver` will be used to determine if\n * there are multiple lines of content.\n */\n multiline?: boolean;\n\n /**\n * When this is a string or React element, it will be rendered as the\n * `children` within a `Button`\n */\n action?: ButtonProps | ReactElement | string;\n\n /**\n * This can be used to replace the custom action button behavior.\n */\n actionButton?: ReactNode;\n\n /**\n * @defaultValue `getIcon(\"close\")`\n */\n closeIcon?: ReactNode;\n\n /**\n * Set this to `true` if a close button should be rendered to the right of the\n * `children`.\n *\n * @defaultValue `!!closeButtonProps`\n */\n closeButton?: boolean;\n\n /**\n * Use this prop to override most of the close button behavior. The\n */\n closeButtonProps?: ButtonProps;\n\n /**\n * Any additional props that should be provided to the `<div>` that surrounds\n * the toast `children`.\n */\n contentProps?: PropsWithRef<ToastContentProps>;\n\n /**\n * Set this to `true` if the `children` for the toast should no longer be\n * wrapped in an additional `<div>` that applies some toast layout styles.\n * This should normally only be used for custom `Toast` implementations.\n *\n * @see the `Snackbar`'s `renderToast` prop for an example.\n */\n disableToastContent?: boolean;\n\n /**\n * The toast's transition timeout for entering and exiting. This is **not**\n * how long the toast should remain visible.\n *\n * @defaultValue `SCALE_TIMEOUT`\n */\n timeout?: TransitionTimeout;\n\n /**\n * The toast's transition class names for entering and exiting.\n *\n * @defaultValue `SCALE_CLASSNAMES`\n */\n classNames?: CSSTransitionClassNames;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ToastProps extends ConfigurableToastProps {\n paused?: boolean;\n visible: boolean;\n}\n\n/**\n * **Client Component**\n *\n * This component is just used for toast styling and does not implement any of\n * the visibility behavior.\n *\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @since 6.0.0\n */\nexport const Toast = forwardRef<HTMLDivElement, ToastProps>(\n function Toast(props, ref) {\n const {\n id: propId,\n className,\n timeout,\n classNames,\n theme = \"surface\",\n action: propAction,\n actionButton: propActionButton,\n paused,\n visible,\n closeIcon: propCloseIcon,\n closeButtonProps,\n closeButton = !!closeButtonProps,\n contentProps,\n disableToastContent,\n stacked,\n multiline,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n children,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"toast\");\n\n let actionButton = propActionButton;\n if (propAction) {\n let overrides: ButtonProps = {};\n let buttonChildren: ReactNode;\n // have to use `any` to correctly filter out all react elements\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (isValidElement<any>(propAction) || typeof propAction !== \"object\") {\n buttonChildren = propAction;\n } else {\n ({ children: buttonChildren, ...overrides } = propAction);\n }\n\n actionButton = (\n <ToastActionButton\n theme={theme === \"surface\" ? \"secondary\" : \"clear\"}\n reordered={stacked && closeButton}\n {...overrides}\n >\n {buttonChildren}\n </ToastActionButton>\n );\n }\n\n let closeIcon = propCloseIcon;\n if (typeof closeButtonProps?.children !== \"undefined\") {\n closeIcon = closeButtonProps.children;\n }\n\n const action = !!actionButton;\n const reordered = stacked && action && closeButton;\n const { elementProps, rendered } = useScaleTransition({\n appear: true,\n nodeRef: ref,\n className: toast({\n className,\n theme,\n action,\n paused,\n stacked,\n reordered,\n closeButton,\n }),\n timeout,\n classNames,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n temporary: true,\n transitionIn: visible,\n exitedHidden: true,\n });\n\n // this might get rid of the weird popping-back-in for a split second\n // that sometimes happens on mobile firefox\n if (!rendered) {\n return null;\n }\n\n return (\n <div {...remaining} {...elementProps} id={id}>\n <ToastContent\n action={action}\n stacked={stacked}\n multiline={multiline}\n closeButton={closeButton}\n disableWrapper={disableToastContent}\n {...contentProps}\n >\n {children}\n </ToastContent>\n {actionButton}\n {closeButton && (\n <ToastCloseButton reordered={reordered} {...closeButtonProps}>\n {closeIcon}\n </ToastCloseButton>\n )}\n </div>\n );\n }\n);\n"],"names":["forwardRef","isValidElement","useScaleTransition","useEnsuredId","ToastActionButton","ToastCloseButton","ToastContent","toast","Toast","props","ref","id","propId","className","timeout","classNames","theme","action","propAction","actionButton","propActionButton","paused","visible","closeIcon","propCloseIcon","closeButtonProps","closeButton","contentProps","disableToastContent","stacked","multiline","onEnter","onEntering","onEntered","onExit","onExiting","onExited","children","remaining","overrides","buttonChildren","reordered","elementProps","rendered","appear","nodeRef","temporary","transitionIn","exitedHidden","div","disableWrapper"],"mappings":"AAAA;;AAEA,SAKEA,UAAU,EACVC,cAAc,QACT,QAAQ;AAQf,SAASC,kBAAkB,QAAQ,sCAAsC;AAEzE,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,YAAY,QAAgC,oBAAoB;AACzE,SAAwCC,KAAK,QAAQ,mBAAmB;AA0GxE;;;;;;;;CAQC,GACD,OAAO,MAAMC,sBAAQR,WACnB,SAASQ,MAAMC,KAAK,EAAEC,GAAG;IACvB,MAAM,EACJC,IAAIC,MAAM,EACVC,SAAS,EACTC,OAAO,EACPC,UAAU,EACVC,QAAQ,SAAS,EACjBC,QAAQC,UAAU,EAClBC,cAAcC,gBAAgB,EAC9BC,MAAM,EACNC,OAAO,EACPC,WAAWC,aAAa,EACxBC,gBAAgB,EAChBC,cAAc,CAAC,CAACD,gBAAgB,EAChCE,YAAY,EACZC,mBAAmB,EACnBC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACR,GAAGC,WACJ,GAAG7B;IACJ,MAAME,KAAKR,aAAaS,QAAQ;IAEhC,IAAIO,eAAeC;IACnB,IAAIF,YAAY;QACd,IAAIqB,YAAyB,CAAC;QAC9B,IAAIC;QACJ,+DAA+D;QAC/D,8DAA8D;QAC9D,kBAAIvC,eAAoBiB,eAAe,OAAOA,eAAe,UAAU;YACrEsB,iBAAiBtB;QACnB,OAAO;YACJ,CAAA,EAAEmB,UAAUG,cAAc,EAAE,GAAGD,WAAW,GAAGrB,UAAS;QACzD;QAEAC,6BACE,KAACf;YACCY,OAAOA,UAAU,YAAY,cAAc;YAC3CyB,WAAWZ,WAAWH;YACrB,GAAGa,SAAS;sBAEZC;;IAGP;IAEA,IAAIjB,YAAYC;IAChB,IAAI,OAAOC,kBAAkBY,aAAa,aAAa;QACrDd,YAAYE,iBAAiBY,QAAQ;IACvC;IAEA,MAAMpB,SAAS,CAAC,CAACE;IACjB,MAAMsB,YAAYZ,WAAWZ,UAAUS;IACvC,MAAM,EAAEgB,YAAY,EAAEC,QAAQ,EAAE,GAAGzC,mBAAmB;QACpD0C,QAAQ;QACRC,SAASnC;QACTG,WAAWN,MAAM;YACfM;YACAG;YACAC;YACAI;YACAQ;YACAY;YACAf;QACF;QACAZ;QACAC;QACAgB;QACAC;QACAC;QACAC;QACAC;QACAC;QACAU,WAAW;QACXC,cAAczB;QACd0B,cAAc;IAChB;IAEA,qEAAqE;IACrE,2CAA2C;IAC3C,IAAI,CAACL,UAAU;QACb,OAAO;IACT;IAEA,qBACE,MAACM;QAAK,GAAGX,SAAS;QAAG,GAAGI,YAAY;QAAE/B,IAAIA;;0BACxC,KAACL;gBACCW,QAAQA;gBACRY,SAASA;gBACTC,WAAWA;gBACXJ,aAAaA;gBACbwB,gBAAgBtB;gBACf,GAAGD,YAAY;0BAEfU;;YAEFlB;YACAO,6BACC,KAACrB;gBAAiBoC,WAAWA;gBAAY,GAAGhB,gBAAgB;0BACzDF;;;;AAKX,GACA"}
1
+ {"version":3,"sources":["../../src/snackbar/Toast.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type AriaRole,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n forwardRef,\n isValidElement,\n} from \"react\";\n\nimport { type ButtonProps } from \"../button/Button.js\";\nimport {\n type CSSTransitionClassNames,\n type TransitionCallbacks,\n type TransitionTimeout,\n} from \"../transition/types.js\";\nimport { useScaleTransition } from \"../transition/useScaleTransition.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { ToastActionButton } from \"./ToastActionButton.js\";\nimport { ToastCloseButton } from \"./ToastCloseButton.js\";\nimport { ToastContent, type ToastContentProps } from \"./ToastContent.js\";\nimport { type BaseToastClasNameOptions, toast } from \"./toastStyles.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableToastProps\n extends\n HTMLAttributes<HTMLDivElement>,\n BaseToastClasNameOptions,\n TransitionCallbacks {\n /**\n * Note: this default value will only be generated in the `Toast` component.\n *\n * @defaultValue `\"toast-\" + useId()`\n */\n id?: string;\n\n /**\n * Note: This is set while creating the toast.\n *\n * @defaultValue `visibleTime === null ? \"alert\" : \"status\"`\n */\n role?: AriaRole;\n\n /**\n * Set this to `true` to stack the content above the {@link action}. It is not\n * recommended to enable this prop if the {@link closeButton} is enabled.\n *\n * @defaultValue `false`\n */\n stacked?: boolean;\n\n /**\n * If this is not provided, a `ResizeObserver` will be used to determine if\n * there are multiple lines of content.\n */\n multiline?: boolean;\n\n /**\n * When this is a string or React element, it will be rendered as the\n * `children` within a `Button`\n */\n action?: ButtonProps | ReactElement | string;\n\n /**\n * This can be used to replace the custom action button behavior.\n */\n actionButton?: ReactNode;\n\n /**\n * @defaultValue `getIcon(\"close\")`\n */\n closeIcon?: ReactNode;\n\n /**\n * Set this to `true` if a close button should be rendered to the right of the\n * `children`.\n *\n * @defaultValue `!!closeButtonProps`\n */\n closeButton?: boolean;\n\n /**\n * Use this prop to override most of the close button behavior. The\n */\n closeButtonProps?: ButtonProps;\n\n /**\n * Any additional props that should be provided to the `<div>` that surrounds\n * the toast `children`.\n */\n contentProps?: PropsWithRef<ToastContentProps>;\n\n /**\n * Set this to `true` if the `children` for the toast should no longer be\n * wrapped in an additional `<div>` that applies some toast layout styles.\n * This should normally only be used for custom `Toast` implementations.\n *\n * @see the `Snackbar`'s `renderToast` prop for an example.\n */\n disableToastContent?: boolean;\n\n /**\n * The toast's transition timeout for entering and exiting. This is **not**\n * how long the toast should remain visible.\n *\n * @defaultValue `SCALE_TIMEOUT`\n */\n timeout?: TransitionTimeout;\n\n /**\n * The toast's transition class names for entering and exiting.\n *\n * @defaultValue `SCALE_CLASSNAMES`\n */\n classNames?: CSSTransitionClassNames;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ToastProps extends ConfigurableToastProps {\n paused?: boolean;\n visible: boolean;\n}\n\n/**\n * **Client Component**\n *\n * This component is just used for toast styling and does not implement any of\n * the visibility behavior.\n *\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @since 6.0.0\n */\nexport const Toast = forwardRef<HTMLDivElement, ToastProps>(\n function Toast(props, ref) {\n const {\n id: propId,\n className,\n timeout,\n classNames,\n theme = \"surface\",\n action: propAction,\n actionButton: propActionButton,\n paused,\n visible,\n closeIcon: propCloseIcon,\n closeButtonProps,\n closeButton = !!closeButtonProps,\n contentProps,\n disableToastContent,\n stacked,\n multiline,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n children,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"toast\");\n\n let actionButton = propActionButton;\n if (propAction) {\n let overrides: ButtonProps = {};\n let buttonChildren: ReactNode;\n // have to use `any` to correctly filter out all react elements\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (isValidElement<any>(propAction) || typeof propAction !== \"object\") {\n buttonChildren = propAction;\n } else {\n ({ children: buttonChildren, ...overrides } = propAction);\n }\n\n actionButton = (\n <ToastActionButton\n theme={theme === \"surface\" ? \"secondary\" : \"clear\"}\n reordered={stacked && closeButton}\n {...overrides}\n >\n {buttonChildren}\n </ToastActionButton>\n );\n }\n\n let closeIcon = propCloseIcon;\n if (closeButtonProps?.children !== undefined) {\n closeIcon = closeButtonProps.children;\n }\n\n const action = !!actionButton;\n const reordered = stacked && action && closeButton;\n const { elementProps, rendered } = useScaleTransition({\n appear: true,\n nodeRef: ref,\n className: toast({\n className,\n theme,\n action,\n paused,\n stacked,\n reordered,\n closeButton,\n }),\n timeout,\n classNames,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n temporary: true,\n transitionIn: visible,\n exitedHidden: true,\n });\n\n // this might get rid of the weird popping-back-in for a split second\n // that sometimes happens on mobile firefox\n if (!rendered) {\n return null;\n }\n\n return (\n <div {...remaining} {...elementProps} id={id}>\n <ToastContent\n action={action}\n stacked={stacked}\n multiline={multiline}\n closeButton={closeButton}\n disableWrapper={disableToastContent}\n {...contentProps}\n >\n {children}\n </ToastContent>\n {actionButton}\n {closeButton && (\n <ToastCloseButton reordered={reordered} {...closeButtonProps}>\n {closeIcon}\n </ToastCloseButton>\n )}\n </div>\n );\n }\n);\n"],"names":["forwardRef","isValidElement","useScaleTransition","useEnsuredId","ToastActionButton","ToastCloseButton","ToastContent","toast","Toast","props","ref","id","propId","className","timeout","classNames","theme","action","propAction","actionButton","propActionButton","paused","visible","closeIcon","propCloseIcon","closeButtonProps","closeButton","contentProps","disableToastContent","stacked","multiline","onEnter","onEntering","onEntered","onExit","onExiting","onExited","children","remaining","overrides","buttonChildren","reordered","undefined","elementProps","rendered","appear","nodeRef","temporary","transitionIn","exitedHidden","div","disableWrapper"],"mappings":"AAAA;;AAEA,SAKEA,UAAU,EACVC,cAAc,QACT,QAAQ;AAQf,SAASC,kBAAkB,QAAQ,sCAAsC;AAEzE,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,YAAY,QAAgC,oBAAoB;AACzE,SAAwCC,KAAK,QAAQ,mBAAmB;AA0GxE;;;;;;;;CAQC,GACD,OAAO,MAAMC,sBAAQR,WACnB,SAASQ,MAAMC,KAAK,EAAEC,GAAG;IACvB,MAAM,EACJC,IAAIC,MAAM,EACVC,SAAS,EACTC,OAAO,EACPC,UAAU,EACVC,QAAQ,SAAS,EACjBC,QAAQC,UAAU,EAClBC,cAAcC,gBAAgB,EAC9BC,MAAM,EACNC,OAAO,EACPC,WAAWC,aAAa,EACxBC,gBAAgB,EAChBC,cAAc,CAAC,CAACD,gBAAgB,EAChCE,YAAY,EACZC,mBAAmB,EACnBC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACR,GAAGC,WACJ,GAAG7B;IACJ,MAAME,KAAKR,aAAaS,QAAQ;IAEhC,IAAIO,eAAeC;IACnB,IAAIF,YAAY;QACd,IAAIqB,YAAyB,CAAC;QAC9B,IAAIC;QACJ,+DAA+D;QAC/D,8DAA8D;QAC9D,kBAAIvC,eAAoBiB,eAAe,OAAOA,eAAe,UAAU;YACrEsB,iBAAiBtB;QACnB,OAAO;YACJ,CAAA,EAAEmB,UAAUG,cAAc,EAAE,GAAGD,WAAW,GAAGrB,UAAS;QACzD;QAEAC,6BACE,KAACf;YACCY,OAAOA,UAAU,YAAY,cAAc;YAC3CyB,WAAWZ,WAAWH;YACrB,GAAGa,SAAS;sBAEZC;;IAGP;IAEA,IAAIjB,YAAYC;IAChB,IAAIC,kBAAkBY,aAAaK,WAAW;QAC5CnB,YAAYE,iBAAiBY,QAAQ;IACvC;IAEA,MAAMpB,SAAS,CAAC,CAACE;IACjB,MAAMsB,YAAYZ,WAAWZ,UAAUS;IACvC,MAAM,EAAEiB,YAAY,EAAEC,QAAQ,EAAE,GAAG1C,mBAAmB;QACpD2C,QAAQ;QACRC,SAASpC;QACTG,WAAWN,MAAM;YACfM;YACAG;YACAC;YACAI;YACAQ;YACAY;YACAf;QACF;QACAZ;QACAC;QACAgB;QACAC;QACAC;QACAC;QACAC;QACAC;QACAW,WAAW;QACXC,cAAc1B;QACd2B,cAAc;IAChB;IAEA,qEAAqE;IACrE,2CAA2C;IAC3C,IAAI,CAACL,UAAU;QACb,OAAO;IACT;IAEA,qBACE,MAACM;QAAK,GAAGZ,SAAS;QAAG,GAAGK,YAAY;QAAEhC,IAAIA;;0BACxC,KAACL;gBACCW,QAAQA;gBACRY,SAASA;gBACTC,WAAWA;gBACXJ,aAAaA;gBACbyB,gBAAgBvB;gBACf,GAAGD,YAAY;0BAEfU;;YAEFlB;YACAO,6BACC,KAACrB;gBAAiBoC,WAAWA;gBAAY,GAAGhB,gBAAgB;0BACzDF;;;;AAKX,GACA"}
@@ -17,8 +17,8 @@ import { toastContent } from "./toastContentStyles.js";
17
17
  disableWidth: true,
18
18
  onUpdate: useCallback((entry)=>{
19
19
  const element = entry.target;
20
- const style = window.getComputedStyle(element);
21
- const lineHeight = parseFloat(style.lineHeight);
20
+ const style = globalThis.getComputedStyle(element);
21
+ const lineHeight = Number.parseFloat(style.lineHeight);
22
22
  if (Number.isNaN(lineHeight)) {
23
23
  return;
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/snackbar/ToastContent.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef, useCallback, useState } from \"react\";\n\nimport { useResizeObserver } from \"../useResizeObserver.js\";\nimport { toastContent } from \"./toastContentStyles.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ToastContentProps extends HTMLAttributes<HTMLDivElement> {\n /** @defaultValue `false` */\n action?: boolean;\n\n /** @defaultValue `false` */\n stacked?: boolean;\n\n /**\n * Set this to `true` if you know that the {@link children} span multiple\n * lines. When this is omitted, a `ResizeObserver` will be used to\n * automatically detect multiline content.\n */\n multiline?: boolean;\n\n /** @defaultValue `false` */\n closeButton?: boolean;\n\n /**\n * Set this to `true` if you do not want to wrap the `children` in a `<div>`\n * that applies some toast layout styles. This should really only be used for\n * custom `Toast` implementations.\n *\n * @internal\n * @defaultValue `false`\n */\n disableWrapper?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @since 6.0.0\n */\nexport const ToastContent = forwardRef<HTMLDivElement, ToastContentProps>(\n function ToastContent(props, ref) {\n const {\n className,\n children,\n action,\n stacked,\n multiline: propMultiline,\n closeButton,\n disableWrapper,\n ...remaining\n } = props;\n\n const [isMultiline, setMultiline] = useState(false);\n const nodeRef = useResizeObserver({\n ref,\n disabled: disableWrapper || typeof propMultiline === \"boolean\",\n disableWidth: true,\n onUpdate: useCallback((entry) => {\n const element = entry.target;\n const style = window.getComputedStyle(element);\n const lineHeight = parseFloat(style.lineHeight);\n if (Number.isNaN(lineHeight)) {\n return;\n }\n\n setMultiline(element.scrollHeight > lineHeight);\n }, []),\n });\n const multiline = propMultiline ?? isMultiline;\n\n if (disableWrapper) {\n return <>{children}</>;\n }\n\n return (\n <div\n {...remaining}\n ref={nodeRef}\n className={toastContent({\n action,\n stacked,\n multiline,\n closeButton,\n className,\n })}\n >\n {children}\n </div>\n );\n }\n);\n"],"names":["forwardRef","useCallback","useState","useResizeObserver","toastContent","ToastContent","props","ref","className","children","action","stacked","multiline","propMultiline","closeButton","disableWrapper","remaining","isMultiline","setMultiline","nodeRef","disabled","disableWidth","onUpdate","entry","element","target","style","window","getComputedStyle","lineHeight","parseFloat","Number","isNaN","scrollHeight","div"],"mappings":"AAAA;;AAEA,SAA8BA,UAAU,EAAEC,WAAW,EAAEC,QAAQ,QAAQ,QAAQ;AAE/E,SAASC,iBAAiB,QAAQ,0BAA0B;AAC5D,SAASC,YAAY,QAAQ,0BAA0B;AAiCvD;;;;;CAKC,GACD,OAAO,MAAMC,6BAAeL,WAC1B,SAASK,aAAaC,KAAK,EAAEC,GAAG;IAC9B,MAAM,EACJC,SAAS,EACTC,QAAQ,EACRC,MAAM,EACNC,OAAO,EACPC,WAAWC,aAAa,EACxBC,WAAW,EACXC,cAAc,EACd,GAAGC,WACJ,GAAGV;IAEJ,MAAM,CAACW,aAAaC,aAAa,GAAGhB,SAAS;IAC7C,MAAMiB,UAAUhB,kBAAkB;QAChCI;QACAa,UAAUL,kBAAkB,OAAOF,kBAAkB;QACrDQ,cAAc;QACdC,UAAUrB,YAAY,CAACsB;YACrB,MAAMC,UAAUD,MAAME,MAAM;YAC5B,MAAMC,QAAQC,OAAOC,gBAAgB,CAACJ;YACtC,MAAMK,aAAaC,WAAWJ,MAAMG,UAAU;YAC9C,IAAIE,OAAOC,KAAK,CAACH,aAAa;gBAC5B;YACF;YAEAX,aAAaM,QAAQS,YAAY,GAAGJ;QACtC,GAAG,EAAE;IACP;IACA,MAAMjB,YAAYC,iBAAiBI;IAEnC,IAAIF,gBAAgB;QAClB,qBAAO;sBAAGN;;IACZ;IAEA,qBACE,KAACyB;QACE,GAAGlB,SAAS;QACbT,KAAKY;QACLX,WAAWJ,aAAa;YACtBM;YACAC;YACAC;YACAE;YACAN;QACF;kBAECC;;AAGP,GACA"}
1
+ {"version":3,"sources":["../../src/snackbar/ToastContent.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef, useCallback, useState } from \"react\";\n\nimport { useResizeObserver } from \"../useResizeObserver.js\";\nimport { toastContent } from \"./toastContentStyles.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ToastContentProps extends HTMLAttributes<HTMLDivElement> {\n /** @defaultValue `false` */\n action?: boolean;\n\n /** @defaultValue `false` */\n stacked?: boolean;\n\n /**\n * Set this to `true` if you know that the {@link children} span multiple\n * lines. When this is omitted, a `ResizeObserver` will be used to\n * automatically detect multiline content.\n */\n multiline?: boolean;\n\n /** @defaultValue `false` */\n closeButton?: boolean;\n\n /**\n * Set this to `true` if you do not want to wrap the `children` in a `<div>`\n * that applies some toast layout styles. This should really only be used for\n * custom `Toast` implementations.\n *\n * @internal\n * @defaultValue `false`\n */\n disableWrapper?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @since 6.0.0\n */\nexport const ToastContent = forwardRef<HTMLDivElement, ToastContentProps>(\n function ToastContent(props, ref) {\n const {\n className,\n children,\n action,\n stacked,\n multiline: propMultiline,\n closeButton,\n disableWrapper,\n ...remaining\n } = props;\n\n const [isMultiline, setMultiline] = useState(false);\n const nodeRef = useResizeObserver({\n ref,\n disabled: disableWrapper || typeof propMultiline === \"boolean\",\n disableWidth: true,\n onUpdate: useCallback((entry) => {\n const element = entry.target;\n const style = globalThis.getComputedStyle(element);\n const lineHeight = Number.parseFloat(style.lineHeight);\n if (Number.isNaN(lineHeight)) {\n return;\n }\n\n setMultiline(element.scrollHeight > lineHeight);\n }, []),\n });\n const multiline = propMultiline ?? isMultiline;\n\n if (disableWrapper) {\n return <>{children}</>;\n }\n\n return (\n <div\n {...remaining}\n ref={nodeRef}\n className={toastContent({\n action,\n stacked,\n multiline,\n closeButton,\n className,\n })}\n >\n {children}\n </div>\n );\n }\n);\n"],"names":["forwardRef","useCallback","useState","useResizeObserver","toastContent","ToastContent","props","ref","className","children","action","stacked","multiline","propMultiline","closeButton","disableWrapper","remaining","isMultiline","setMultiline","nodeRef","disabled","disableWidth","onUpdate","entry","element","target","style","globalThis","getComputedStyle","lineHeight","Number","parseFloat","isNaN","scrollHeight","div"],"mappings":"AAAA;;AAEA,SAA8BA,UAAU,EAAEC,WAAW,EAAEC,QAAQ,QAAQ,QAAQ;AAE/E,SAASC,iBAAiB,QAAQ,0BAA0B;AAC5D,SAASC,YAAY,QAAQ,0BAA0B;AAiCvD;;;;;CAKC,GACD,OAAO,MAAMC,6BAAeL,WAC1B,SAASK,aAAaC,KAAK,EAAEC,GAAG;IAC9B,MAAM,EACJC,SAAS,EACTC,QAAQ,EACRC,MAAM,EACNC,OAAO,EACPC,WAAWC,aAAa,EACxBC,WAAW,EACXC,cAAc,EACd,GAAGC,WACJ,GAAGV;IAEJ,MAAM,CAACW,aAAaC,aAAa,GAAGhB,SAAS;IAC7C,MAAMiB,UAAUhB,kBAAkB;QAChCI;QACAa,UAAUL,kBAAkB,OAAOF,kBAAkB;QACrDQ,cAAc;QACdC,UAAUrB,YAAY,CAACsB;YACrB,MAAMC,UAAUD,MAAME,MAAM;YAC5B,MAAMC,QAAQC,WAAWC,gBAAgB,CAACJ;YAC1C,MAAMK,aAAaC,OAAOC,UAAU,CAACL,MAAMG,UAAU;YACrD,IAAIC,OAAOE,KAAK,CAACH,aAAa;gBAC5B;YACF;YAEAX,aAAaM,QAAQS,YAAY,GAAGJ;QACtC,GAAG,EAAE;IACP;IACA,MAAMjB,YAAYC,iBAAiBI;IAEnC,IAAIF,gBAAgB;QAClB,qBAAO;sBAAGN;;IACZ;IAEA,qBACE,KAACyB;QACE,GAAGlB,SAAS;QACbT,KAAKY;QACLX,WAAWJ,aAAa;YACtBM;YACAC;YACAC;YACAE;YACAN;QACF;kBAECC;;AAGP,GACA"}
@@ -106,7 +106,7 @@ export interface ToastVisibilityTimers {
106
106
  inactive: boolean;
107
107
  startTime: number;
108
108
  elapsedTime: number;
109
- exitTimeout?: number;
109
+ exitTimeout?: NodeJS.Timeout;
110
110
  }
111
111
  /**
112
112
  * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}
@@ -87,9 +87,9 @@ var _queue = /*#__PURE__*/ new WeakMap(), _timers = /*#__PURE__*/ new WeakMap(),
87
87
  _class_private_field_set(this, _queue, [
88
88
  ..._class_private_field_get(this, _queue)
89
89
  ]);
90
- _class_private_field_get(this, _listeners).forEach((callback)=>{
90
+ for (const callback of _class_private_field_get(this, _listeners)){
91
91
  callback(_class_private_field_get(this, _queue));
92
- });
92
+ }
93
93
  }
94
94
  });
95
95
  _class_private_field_init(this, _getToastIndex, {
@@ -302,13 +302,13 @@ var _queue = /*#__PURE__*/ new WeakMap(), _timers = /*#__PURE__*/ new WeakMap(),
302
302
  startTime: Date.now(),
303
303
  elapsedTime: 0
304
304
  };
305
- window.clearTimeout(timers.exitTimeout);
305
+ globalThis.clearTimeout(timers.exitTimeout);
306
306
  let duration = visibleTime;
307
307
  if (timers.elapsedTime) {
308
308
  duration -= timers.elapsedTime;
309
309
  }
310
310
  timers.inactive = false;
311
- timers.exitTimeout = window.setTimeout(()=>{
311
+ timers.exitTimeout = globalThis.setTimeout(()=>{
312
312
  this.removeToast(toastId, true);
313
313
  }, duration);
314
314
  _class_private_field_get(this, _timers).set(toastId, timers);
@@ -324,11 +324,11 @@ var _queue = /*#__PURE__*/ new WeakMap(), _timers = /*#__PURE__*/ new WeakMap(),
324
324
  if (!toast || !cached || cached.inactive) {
325
325
  return;
326
326
  }
327
- window.clearTimeout(cached.exitTimeout);
327
+ globalThis.clearTimeout(cached.exitTimeout);
328
328
  const timers = {
329
- ...cached
329
+ ...cached,
330
+ inactive: true
330
331
  };
331
- timers.inactive = true;
332
332
  timers.elapsedTime = Date.now() - timers.startTime + timers.elapsedTime;
333
333
  _class_private_field_get(this, _timers).set(toastId, timers);
334
334
  _class_private_field_get(this, _updateToast).call(this, toastId, {
@@ -391,7 +391,7 @@ var _queue = /*#__PURE__*/ new WeakMap(), _timers = /*#__PURE__*/ new WeakMap(),
391
391
  * ```
392
392
  */ _define_property(this, "clearTimer", (toastId)=>{
393
393
  const timer = _class_private_field_get(this, _timers).get(toastId);
394
- window.clearTimeout(timer?.exitTimeout);
394
+ globalThis.clearTimeout(timer?.exitTimeout);
395
395
  _class_private_field_get(this, _timers).delete(toastId);
396
396
  });
397
397
  /**
@@ -408,9 +408,9 @@ var _queue = /*#__PURE__*/ new WeakMap(), _timers = /*#__PURE__*/ new WeakMap(),
408
408
  * Mostly used for tests.
409
409
  */ _define_property(this, "clearToasts", (disableEmit = false)=>{
410
410
  _class_private_field_set(this, _queue, []);
411
- _class_private_field_get(this, _timers).forEach((meta)=>{
412
- window.clearTimeout(meta.exitTimeout);
413
- });
411
+ for (const [, meta] of _class_private_field_get(this, _timers)){
412
+ globalThis.clearTimeout(meta.exitTimeout);
413
+ }
414
414
  _class_private_field_get(this, _timers).clear();
415
415
  if (!disableEmit) {
416
416
  _class_private_field_get(this, _emit).call(this);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/snackbar/ToastManager.ts"],"sourcesContent":["import { nanoid } from \"nanoid\";\n\nimport { type ConfigurableToastProps } from \"./Toast.js\";\n\n/**\n * @since 6.0.0\n */\nexport const DEFAULT_TOAST_VISIBLE_TIME = 5000;\n\n/**\n * - `\"normal\"` - the toast will be added to the end of the queue\n * - `\"next\"` - the toast will be inserted next-in-line in the queue, waiting\n * for the current visible toast to exit before being shown. If the toast does\n * not support duplicates, the existing toast will be moved instead and merged\n * with the toast.\n * - `\"replace\"` - if there is a currently visible toast, it will start the\n * leave transition and display the newly added toast instead.\n * - `\"immediate\"` - the same behavior as `\"replace\"` except that if there was a\n * currently visible toast, the toast will be shown again once the `\"immediate\"`\n * toast is hidden.\n *\n * @since 6.0.0 Renamed from `MessagePriority` to `ToastPriority`\n */\nexport type ToastPriority = \"normal\" | \"next\" | \"replace\" | \"immediate\";\n\n/**\n * - `\"allow\"` - toasts with the same `toastId` can be added into the queue, but\n * the leave timeout behavior might not work if multiple toasts can be shown\n * at the same time.\n * - `\"restart\"` - (default) toasts that have the same `toastId` as a toast\n * being shown will restart the exit timeout and update the toast with any\n * differences in the toast. If the toast is not currently being shown, a new\n * toast will not be added.\n * - `\"update\"` - toasts that have the same `toastId` will just update the toast\n * with the latest content while maintaining any existing timeouts\n *\n * @since 6.0.0 Renamed from `DuplicateBehavior`\n */\nexport type ToastDuplicateBehavior = \"allow\" | \"restart\" | \"update\";\n\n/**\n * @since 6.0.0\n */\nexport interface ToastMeta {\n /**\n * This will be `true` if the exit timeout has been paused either by hovering\n * the toast or the page has become inactive through blur or minimizing.\n */\n paused: boolean;\n\n /**\n * This will be `true` when the toast should be visible and `false` during the\n * exit animation.\n */\n visible: boolean;\n\n /**\n * The current toast's id which can be used with the:\n * - {@link ToastManager.removeToast}\n * - {@link ToastManager.startRemoveTimeout}\n * - {@link ToastManager.pauseRemoveTimeout}\n * - {@link ToastManager.resumeRemoveTimeout}\n */\n toastId: string;\n priority: ToastPriority;\n duplicates: ToastDuplicateBehavior;\n visibleTime: number | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface CreateToastOptions extends ConfigurableToastProps {\n /**\n * @defaultValue `nanoid()`\n */\n toastId?: string;\n\n /**\n * @see {@link ToastDuplicateBehavior}\n * @defaultValue `\"restart\"`\n */\n duplicates?: ToastDuplicateBehavior;\n\n /**\n * @see {@link ToastPriority}\n * @defaultValue `\"normal\"`\n */\n priority?: ToastPriority;\n\n /**\n * Set this to `null` to prevent the toast from automatically hiding,\n * otherwise set this to the number of milliseconds to remain visible.\n *\n * @see {@link DEFAULT_TOAST_VISIBLE_TIME}\n * @defaultValue `DEFAULT_TOAST_VISIBLE_TIME`\n */\n visibleTime?: number | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface QueuedToast extends ConfigurableToastProps, ToastMeta {}\n\n/**\n * @since 6.0.0\n */\nexport type ToastQueue = readonly Readonly<QueuedToast>[];\n\n/**\n * @since 6.0.0\n */\nexport type ToastCallback = (queue: ToastQueue) => void;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface ToastVisibilityTimers {\n inactive: boolean;\n startTime: number;\n elapsedTime: number;\n exitTimeout?: number;\n}\n\n/**\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @see {@link ToastManagerProvider}\n * @since 6.0.0\n */\nexport class ToastManager {\n #queue: QueuedToast[];\n #timers: Map<string, ToastVisibilityTimers>;\n #listeners: ToastCallback[];\n\n constructor() {\n this.#queue = [];\n this.#timers = new Map();\n this.#listeners = [];\n\n // All of the class methods must be arrow functions to preserve the correct\n // `this` value. If they aren't arrow functions, I'd have to wrap each call\n // in an arrow function to work.\n //\n // i.e.\n // useSyncExternalStore(\n // (cb) => manager.subscribe(cb),\n // () => manager.getQueue(),\n // () => manager.getQueue(),\n // );\n }\n\n #emit = (): void => {\n // shallow clone to ensure react updates\n this.#queue = [...this.#queue];\n this.#listeners.forEach((callback) => {\n callback(this.#queue);\n });\n };\n\n #getToastIndex = (toastId: string | undefined): number => {\n if (!toastId) {\n return -1;\n }\n\n return this.#queue.findIndex((toast) => toast.toastId === toastId);\n };\n\n #getToast = (toastId: string | undefined): QueuedToast | undefined => {\n return this.#queue[this.#getToastIndex(toastId)];\n };\n\n /**\n * Starts the exit transition for the currently shown toast and adds the next\n * toast into the queue. This requires a manual call to `this.#emit()`\n * afterwards.\n */\n #addToastImmediately = (nextToast: QueuedToast): void => {\n const [current] = this.#queue;\n this.clearTimer(current.toastId);\n this.#queue[0] = {\n ...current,\n visible: false,\n };\n if (nextToast.priority === \"immediate\") {\n this.#queue.splice(1, 0, nextToast, current);\n } else {\n this.#queue.splice(1, 0, nextToast);\n }\n };\n\n /**\n * This calls `this.#emit()` if the toast was updated\n */\n #updateToast = (\n toastIdOrIndex: string | number,\n patch: Partial<QueuedToast>\n ): void => {\n const index =\n typeof toastIdOrIndex === \"number\"\n ? toastIdOrIndex\n : this.#getToastIndex(toastIdOrIndex);\n\n if (index === -1) {\n return;\n }\n\n this.#queue[index] = {\n ...this.#queue[index],\n ...patch,\n };\n this.#emit();\n };\n\n /**\n * This is just used to subscribe to changes in the {@link useToastQueue}.\n *\n * ```tsx\n * useSyncExternalStore(\n * toastManager.subscribe,\n * toastManager.getQueue,\n * toastManager.getQueue,\n * );\n * ```\n *\n * @internal\n */\n subscribe = (callback: ToastCallback): (() => void) => {\n this.#listeners.push(callback);\n\n return () => {\n this.#listeners = this.#listeners.filter((cb) => cb !== callback);\n };\n };\n\n /**\n * @see {@link subscribe}\n * @internal\n */\n getQueue = (): ToastQueue => {\n return this.#queue;\n };\n\n /**\n * Either adds the toast to the queue or updates an existing toast when using\n * an existing `toastId`.\n *\n * @example Adding toasts\n * ```tsx\n * // create a toast when the user is offline that will not disappear\n * addToast({ toastId: \"offline\", visibleTime: null });\n *\n * // add a new toast that displays `\"Toast\"` to the queue\n * addToast({ children: \"Toast!\" });\n *\n * // add an online toast notification. since these three use the same toast\n * // id, the hide timer will be reset each time\n * addToast({ toastId: \"online\" });\n * addToast({ toastId: \"online\" });\n * addToast({ toastId: \"online\" });\n *\n * // add a server error toast to the queue where the second one will be\n * // ignored\n * addToast({\n * toastId: \"ServerError\",\n * theme: \"error\",\n * duplicates: \"prevent\",\n * });\n * addToast({\n * toastId: \"ServerError\",\n * theme: \"error\",\n * duplicates: \"prevent\",\n * });\n *\n * // add a toast to the queue that has an action button that says \"Goodbye\"\n * addToast({\n * children: \"Hello, world!\",\n * action: \"Goodbye\",\n * });\n *\n * // add a toast to the queue that has an action button that says \"Goodbye\"\n * // and a custom click handler\n * addToast({\n * children: \"Hello, world!\",\n * action: {\n * onClick: () => {\n * logout();\n * },\n * children: \"Goodbye\",\n * },\n * });\n *\n * // add a toast to the queue that renders a react component in the content,\n * // a custom action button implementation (using `ToastActionButton`), and a\n * // close button\n * addToast({\n * children: <SomeCustomComponent />,\n * actionButton: <SomeCustomActionButton />,\n * closeButton: true,\n * });\n * ```\n */\n addToast = (toast: CreateToastOptions): void => {\n const {\n toastId = nanoid(),\n visibleTime = DEFAULT_TOAST_VISIBLE_TIME,\n role = visibleTime === null ? \"alert\" : \"status\",\n priority = \"normal\",\n duplicates = \"restart\",\n } = toast;\n\n const existingIndex = this.#getToastIndex(toast.toastId);\n if (existingIndex !== -1 && duplicates !== \"allow\") {\n const existingToast = this.#queue[existingIndex];\n const nextToast: QueuedToast = {\n ...existingToast,\n ...toast,\n };\n\n // reorder/move the existing toast to be the next item in the queue by:\n // - removing the toast from the queue\n // - inserting it into the next position with the updates\n if (priority === \"next\" && existingIndex > 1) {\n this.#queue.splice(existingIndex, 1);\n this.#queue.splice(1, 0, nextToast);\n this.#emit();\n return;\n }\n\n // only need to reorder the queue if it is not being shown\n if (\n (priority === \"replace\" || priority === \"immediate\") &&\n existingIndex !== 0\n ) {\n this.#queue.splice(existingIndex, 1);\n this.#addToastImmediately(nextToast);\n this.#emit();\n return;\n }\n\n const timers = this.#timers.get(toastId);\n if (existingToast.visible && duplicates === \"restart\" && timers) {\n this.#timers.set(toastId, { ...timers, elapsedTime: 0 });\n\n // wait for the next resume event instead. this _should_ only happen\n // when hovering a toast and another toast replaces it\n if (!nextToast.paused) {\n this.startRemoveTimeout(toastId);\n }\n }\n\n this.#updateToast(existingIndex, toast);\n return;\n }\n\n const nextToast: QueuedToast = {\n ...toast,\n role,\n paused: false,\n visible: true,\n toastId,\n priority,\n duplicates,\n visibleTime,\n };\n\n const queueSize = this.#queue.length;\n if (priority === \"next\" && queueSize > 1) {\n this.#queue.splice(1, 0, nextToast);\n } else if (\n (priority === \"replace\" || priority === \"immediate\") &&\n queueSize > 0\n ) {\n this.#addToastImmediately(nextToast);\n } else {\n this.#queue.push(nextToast);\n }\n\n this.#emit();\n };\n\n /**\n * Attempts to start the timeout for removing the toast when the `visibleTime`\n * is not null for a toast.\n *\n * @param toastId - The specific toastId to update\n */\n startRemoveTimeout = (toastId: string): void => {\n const toast = this.#getToast(toastId);\n if (!toast) {\n return;\n }\n\n const { visibleTime } = toast;\n if (visibleTime === null) {\n // Must manually be closed\n return;\n }\n\n const cached = this.#timers.get(toastId);\n const timers = (cached && { ...cached }) || {\n inactive: false,\n startTime: Date.now(),\n elapsedTime: 0,\n };\n window.clearTimeout(timers.exitTimeout);\n\n let duration = visibleTime;\n if (timers.elapsedTime) {\n duration -= timers.elapsedTime;\n }\n\n timers.inactive = false;\n timers.exitTimeout = window.setTimeout(() => {\n this.removeToast(toastId, true);\n }, duration);\n this.#timers.set(toastId, timers);\n };\n\n /**\n * Pauses the remove timeout for a specific toast normally with hover events\n * or the browser becoming inactive.\n *\n * @param toastId - The specific toastId to pause\n */\n pauseRemoveTimeout = (toastId: string): void => {\n const toast = this.#getToast(toastId);\n const cached = this.#timers.get(toastId);\n if (!toast || !cached || cached.inactive) {\n return;\n }\n\n window.clearTimeout(cached.exitTimeout);\n const timers = { ...cached };\n timers.inactive = true;\n timers.elapsedTime = Date.now() - timers.startTime + timers.elapsedTime;\n this.#timers.set(toastId, timers);\n this.#updateToast(toastId, { paused: true });\n };\n\n /**\n * Resumes the current remove timeout if it was paused by\n * {@link pauseRemoveTimeout}.\n *\n * @param toastId - The specific toastId to resume\n */\n resumeRemoveTimeout = (toastId: string): void => {\n const toastIndex = this.#getToastIndex(toastId);\n const timers = this.#timers.get(toastId);\n if (toastIndex === -1 || !timers?.startTime) {\n return;\n }\n\n timers.startTime = Date.now();\n this.#updateToast(toastIndex, { paused: false });\n this.startRemoveTimeout(toastId);\n };\n\n /**\n * Removes a toast by id from the queue without any exit animation.\n *\n * @param toastId - The specific {@link QueuedToast.toastId}\n * @param transition - Set this to `true` to remove the toast by the exit\n * transition instead of immediately.\n */\n removeToast = (toastId: string, transition: boolean): void => {\n const toastIndex = this.#getToastIndex(toastId);\n if (toastIndex === -1) {\n return;\n }\n\n if (transition) {\n this.clearTimer(toastId);\n this.#updateToast(toastIndex, { visible: false });\n return;\n }\n\n this.#queue.splice(toastIndex, 1);\n this.#emit();\n };\n\n /**\n * Clears any pending timers for the provided toast id. This should generally\n * be used in the `useEffect` cleanup effect for any custom toast renderer\n * implementations.\n *\n * @example\n * ```tsx\n * const { toastId } = toast;\n * const toastManager = useToastManager();\n *\n * useEffect(() => {\n * return () => {\n * toastManager.clearTimer(toastId):\n * }\n * }, [toastManager, toastId]);\n * ```\n */\n clearTimer = (toastId: string): void => {\n const timer = this.#timers.get(toastId);\n window.clearTimeout(timer?.exitTimeout);\n this.#timers.delete(toastId);\n };\n\n /**\n * Removes first toast from the queue without any exit animation. You most\n * likely want to use {@link removeToast} instead.\n */\n popToast = (): void => {\n this.#queue.pop();\n this.#emit();\n };\n\n /**\n * Removes all toasts from the queue. There will be no exit animation.\n *\n * @param disableEmit - Set this to `true` to disable emitting the empty queue.\n * Mostly used for tests.\n */\n clearToasts = (disableEmit = false): void => {\n this.#queue = [];\n this.#timers.forEach((meta) => {\n window.clearTimeout(meta.exitTimeout);\n });\n this.#timers.clear();\n if (!disableEmit) {\n this.#emit();\n }\n };\n}\n\n/**\n * The default toast manager for react-md apps that will allow toasts to be\n * added without setting up the {@link ToastManagerProvider}.\n *\n * @internal\n * @since 6.0.0\n */\nexport const toastManager = new ToastManager();\n\n/**\n * @see {@link ToastManager.addToast}\n * @since 6.0.0\n */\nexport const addToast: ToastManager[\"addToast\"] = (toast) => {\n toastManager.addToast(toast);\n};\n\n/**\n * @see {@link ToastManager.startRemoveTimeout}\n * @since 6.0.0\n */\nexport const startRemoveToastTimeout: ToastManager[\"startRemoveTimeout\"] = (\n toastId\n) => {\n toastManager.startRemoveTimeout(toastId);\n};\n\n/**\n * @see {@link ToastManager.popToast}\n * @since 6.0.0\n */\nexport const popToast: ToastManager[\"popToast\"] = () => {\n toastManager.popToast();\n};\n\n/**\n * @see {@link ToastManager.removeToast}\n * @since 6.0.0\n */\nexport const removeToast: ToastManager[\"removeToast\"] = (\n toastId,\n transition\n) => {\n toastManager.removeToast(toastId, transition);\n};\n\n/**\n * @see {@link ToastManager.clearToasts}\n * @since 6.0.0\n */\nexport const clearToasts = (): void => {\n toastManager.clearToasts();\n};\n"],"names":["nanoid","DEFAULT_TOAST_VISIBLE_TIME","ToastManager","forEach","callback","toastId","findIndex","toast","nextToast","current","clearTimer","visible","priority","splice","toastIdOrIndex","patch","index","subscribe","push","filter","cb","getQueue","addToast","visibleTime","role","duplicates","existingIndex","existingToast","timers","get","set","elapsedTime","paused","startRemoveTimeout","queueSize","length","cached","inactive","startTime","Date","now","window","clearTimeout","exitTimeout","duration","setTimeout","removeToast","pauseRemoveTimeout","resumeRemoveTimeout","toastIndex","transition","timer","delete","popToast","pop","clearToasts","disableEmit","meta","clear","Map","toastManager","startRemoveToastTimeout"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/snackbar/ToastManager.ts"],"sourcesContent":["import { nanoid } from \"nanoid\";\n\nimport { type ConfigurableToastProps } from \"./Toast.js\";\n\n/**\n * @since 6.0.0\n */\nexport const DEFAULT_TOAST_VISIBLE_TIME = 5000;\n\n/**\n * - `\"normal\"` - the toast will be added to the end of the queue\n * - `\"next\"` - the toast will be inserted next-in-line in the queue, waiting\n * for the current visible toast to exit before being shown. If the toast does\n * not support duplicates, the existing toast will be moved instead and merged\n * with the toast.\n * - `\"replace\"` - if there is a currently visible toast, it will start the\n * leave transition and display the newly added toast instead.\n * - `\"immediate\"` - the same behavior as `\"replace\"` except that if there was a\n * currently visible toast, the toast will be shown again once the `\"immediate\"`\n * toast is hidden.\n *\n * @since 6.0.0 Renamed from `MessagePriority` to `ToastPriority`\n */\nexport type ToastPriority = \"normal\" | \"next\" | \"replace\" | \"immediate\";\n\n/**\n * - `\"allow\"` - toasts with the same `toastId` can be added into the queue, but\n * the leave timeout behavior might not work if multiple toasts can be shown\n * at the same time.\n * - `\"restart\"` - (default) toasts that have the same `toastId` as a toast\n * being shown will restart the exit timeout and update the toast with any\n * differences in the toast. If the toast is not currently being shown, a new\n * toast will not be added.\n * - `\"update\"` - toasts that have the same `toastId` will just update the toast\n * with the latest content while maintaining any existing timeouts\n *\n * @since 6.0.0 Renamed from `DuplicateBehavior`\n */\nexport type ToastDuplicateBehavior = \"allow\" | \"restart\" | \"update\";\n\n/**\n * @since 6.0.0\n */\nexport interface ToastMeta {\n /**\n * This will be `true` if the exit timeout has been paused either by hovering\n * the toast or the page has become inactive through blur or minimizing.\n */\n paused: boolean;\n\n /**\n * This will be `true` when the toast should be visible and `false` during the\n * exit animation.\n */\n visible: boolean;\n\n /**\n * The current toast's id which can be used with the:\n * - {@link ToastManager.removeToast}\n * - {@link ToastManager.startRemoveTimeout}\n * - {@link ToastManager.pauseRemoveTimeout}\n * - {@link ToastManager.resumeRemoveTimeout}\n */\n toastId: string;\n priority: ToastPriority;\n duplicates: ToastDuplicateBehavior;\n visibleTime: number | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface CreateToastOptions extends ConfigurableToastProps {\n /**\n * @defaultValue `nanoid()`\n */\n toastId?: string;\n\n /**\n * @see {@link ToastDuplicateBehavior}\n * @defaultValue `\"restart\"`\n */\n duplicates?: ToastDuplicateBehavior;\n\n /**\n * @see {@link ToastPriority}\n * @defaultValue `\"normal\"`\n */\n priority?: ToastPriority;\n\n /**\n * Set this to `null` to prevent the toast from automatically hiding,\n * otherwise set this to the number of milliseconds to remain visible.\n *\n * @see {@link DEFAULT_TOAST_VISIBLE_TIME}\n * @defaultValue `DEFAULT_TOAST_VISIBLE_TIME`\n */\n visibleTime?: number | null;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface QueuedToast extends ConfigurableToastProps, ToastMeta {}\n\n/**\n * @since 6.0.0\n */\nexport type ToastQueue = readonly Readonly<QueuedToast>[];\n\n/**\n * @since 6.0.0\n */\nexport type ToastCallback = (queue: ToastQueue) => void;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface ToastVisibilityTimers {\n inactive: boolean;\n startTime: number;\n elapsedTime: number;\n exitTimeout?: NodeJS.Timeout;\n}\n\n/**\n * @see {@link https://react-md.dev/components/snackbar | Snackbar Demos}\n * @see {@link ToastManagerProvider}\n * @since 6.0.0\n */\nexport class ToastManager {\n #queue: QueuedToast[];\n #timers: Map<string, ToastVisibilityTimers>;\n #listeners: ToastCallback[];\n\n constructor() {\n this.#queue = [];\n this.#timers = new Map();\n this.#listeners = [];\n\n // All of the class methods must be arrow functions to preserve the correct\n // `this` value. If they aren't arrow functions, I'd have to wrap each call\n // in an arrow function to work.\n //\n // i.e.\n // useSyncExternalStore(\n // (cb) => manager.subscribe(cb),\n // () => manager.getQueue(),\n // () => manager.getQueue(),\n // );\n }\n\n #emit = (): void => {\n // shallow clone to ensure react updates\n this.#queue = [...this.#queue];\n for (const callback of this.#listeners) {\n callback(this.#queue);\n }\n };\n\n #getToastIndex = (toastId: string | undefined): number => {\n if (!toastId) {\n return -1;\n }\n\n return this.#queue.findIndex((toast) => toast.toastId === toastId);\n };\n\n #getToast = (toastId: string | undefined): QueuedToast | undefined => {\n return this.#queue[this.#getToastIndex(toastId)];\n };\n\n /**\n * Starts the exit transition for the currently shown toast and adds the next\n * toast into the queue. This requires a manual call to `this.#emit()`\n * afterwards.\n */\n #addToastImmediately = (nextToast: QueuedToast): void => {\n const [current] = this.#queue;\n this.clearTimer(current.toastId);\n this.#queue[0] = {\n ...current,\n visible: false,\n };\n if (nextToast.priority === \"immediate\") {\n this.#queue.splice(1, 0, nextToast, current);\n } else {\n this.#queue.splice(1, 0, nextToast);\n }\n };\n\n /**\n * This calls `this.#emit()` if the toast was updated\n */\n #updateToast = (\n toastIdOrIndex: string | number,\n patch: Partial<QueuedToast>\n ): void => {\n const index =\n typeof toastIdOrIndex === \"number\"\n ? toastIdOrIndex\n : this.#getToastIndex(toastIdOrIndex);\n\n if (index === -1) {\n return;\n }\n\n this.#queue[index] = {\n ...this.#queue[index],\n ...patch,\n };\n this.#emit();\n };\n\n /**\n * This is just used to subscribe to changes in the {@link useToastQueue}.\n *\n * ```tsx\n * useSyncExternalStore(\n * toastManager.subscribe,\n * toastManager.getQueue,\n * toastManager.getQueue,\n * );\n * ```\n *\n * @internal\n */\n subscribe = (callback: ToastCallback): (() => void) => {\n this.#listeners.push(callback);\n\n return () => {\n this.#listeners = this.#listeners.filter((cb) => cb !== callback);\n };\n };\n\n /**\n * @see {@link subscribe}\n * @internal\n */\n getQueue = (): ToastQueue => {\n return this.#queue;\n };\n\n /**\n * Either adds the toast to the queue or updates an existing toast when using\n * an existing `toastId`.\n *\n * @example Adding toasts\n * ```tsx\n * // create a toast when the user is offline that will not disappear\n * addToast({ toastId: \"offline\", visibleTime: null });\n *\n * // add a new toast that displays `\"Toast\"` to the queue\n * addToast({ children: \"Toast!\" });\n *\n * // add an online toast notification. since these three use the same toast\n * // id, the hide timer will be reset each time\n * addToast({ toastId: \"online\" });\n * addToast({ toastId: \"online\" });\n * addToast({ toastId: \"online\" });\n *\n * // add a server error toast to the queue where the second one will be\n * // ignored\n * addToast({\n * toastId: \"ServerError\",\n * theme: \"error\",\n * duplicates: \"prevent\",\n * });\n * addToast({\n * toastId: \"ServerError\",\n * theme: \"error\",\n * duplicates: \"prevent\",\n * });\n *\n * // add a toast to the queue that has an action button that says \"Goodbye\"\n * addToast({\n * children: \"Hello, world!\",\n * action: \"Goodbye\",\n * });\n *\n * // add a toast to the queue that has an action button that says \"Goodbye\"\n * // and a custom click handler\n * addToast({\n * children: \"Hello, world!\",\n * action: {\n * onClick: () => {\n * logout();\n * },\n * children: \"Goodbye\",\n * },\n * });\n *\n * // add a toast to the queue that renders a react component in the content,\n * // a custom action button implementation (using `ToastActionButton`), and a\n * // close button\n * addToast({\n * children: <SomeCustomComponent />,\n * actionButton: <SomeCustomActionButton />,\n * closeButton: true,\n * });\n * ```\n */\n addToast = (toast: CreateToastOptions): void => {\n const {\n toastId = nanoid(),\n visibleTime = DEFAULT_TOAST_VISIBLE_TIME,\n role = visibleTime === null ? \"alert\" : \"status\",\n priority = \"normal\",\n duplicates = \"restart\",\n } = toast;\n\n const existingIndex = this.#getToastIndex(toast.toastId);\n if (existingIndex !== -1 && duplicates !== \"allow\") {\n const existingToast = this.#queue[existingIndex];\n const nextToast: QueuedToast = {\n ...existingToast,\n ...toast,\n };\n\n // reorder/move the existing toast to be the next item in the queue by:\n // - removing the toast from the queue\n // - inserting it into the next position with the updates\n if (priority === \"next\" && existingIndex > 1) {\n this.#queue.splice(existingIndex, 1);\n this.#queue.splice(1, 0, nextToast);\n this.#emit();\n return;\n }\n\n // only need to reorder the queue if it is not being shown\n if (\n (priority === \"replace\" || priority === \"immediate\") &&\n existingIndex !== 0\n ) {\n this.#queue.splice(existingIndex, 1);\n this.#addToastImmediately(nextToast);\n this.#emit();\n return;\n }\n\n const timers = this.#timers.get(toastId);\n if (existingToast.visible && duplicates === \"restart\" && timers) {\n this.#timers.set(toastId, { ...timers, elapsedTime: 0 });\n\n // wait for the next resume event instead. this _should_ only happen\n // when hovering a toast and another toast replaces it\n if (!nextToast.paused) {\n this.startRemoveTimeout(toastId);\n }\n }\n\n this.#updateToast(existingIndex, toast);\n return;\n }\n\n const nextToast: QueuedToast = {\n ...toast,\n role,\n paused: false,\n visible: true,\n toastId,\n priority,\n duplicates,\n visibleTime,\n };\n\n const queueSize = this.#queue.length;\n if (priority === \"next\" && queueSize > 1) {\n this.#queue.splice(1, 0, nextToast);\n } else if (\n (priority === \"replace\" || priority === \"immediate\") &&\n queueSize > 0\n ) {\n this.#addToastImmediately(nextToast);\n } else {\n this.#queue.push(nextToast);\n }\n\n this.#emit();\n };\n\n /**\n * Attempts to start the timeout for removing the toast when the `visibleTime`\n * is not null for a toast.\n *\n * @param toastId - The specific toastId to update\n */\n startRemoveTimeout = (toastId: string): void => {\n const toast = this.#getToast(toastId);\n if (!toast) {\n return;\n }\n\n const { visibleTime } = toast;\n if (visibleTime === null) {\n // Must manually be closed\n return;\n }\n\n const cached = this.#timers.get(toastId);\n const timers = (cached && { ...cached }) || {\n inactive: false,\n startTime: Date.now(),\n elapsedTime: 0,\n };\n globalThis.clearTimeout(timers.exitTimeout);\n\n let duration = visibleTime;\n if (timers.elapsedTime) {\n duration -= timers.elapsedTime;\n }\n\n timers.inactive = false;\n timers.exitTimeout = globalThis.setTimeout(() => {\n this.removeToast(toastId, true);\n }, duration);\n this.#timers.set(toastId, timers);\n };\n\n /**\n * Pauses the remove timeout for a specific toast normally with hover events\n * or the browser becoming inactive.\n *\n * @param toastId - The specific toastId to pause\n */\n pauseRemoveTimeout = (toastId: string): void => {\n const toast = this.#getToast(toastId);\n const cached = this.#timers.get(toastId);\n if (!toast || !cached || cached.inactive) {\n return;\n }\n\n globalThis.clearTimeout(cached.exitTimeout);\n const timers = { ...cached, inactive: true };\n timers.elapsedTime = Date.now() - timers.startTime + timers.elapsedTime;\n this.#timers.set(toastId, timers);\n this.#updateToast(toastId, { paused: true });\n };\n\n /**\n * Resumes the current remove timeout if it was paused by\n * {@link pauseRemoveTimeout}.\n *\n * @param toastId - The specific toastId to resume\n */\n resumeRemoveTimeout = (toastId: string): void => {\n const toastIndex = this.#getToastIndex(toastId);\n const timers = this.#timers.get(toastId);\n if (toastIndex === -1 || !timers?.startTime) {\n return;\n }\n\n timers.startTime = Date.now();\n this.#updateToast(toastIndex, { paused: false });\n this.startRemoveTimeout(toastId);\n };\n\n /**\n * Removes a toast by id from the queue without any exit animation.\n *\n * @param toastId - The specific {@link QueuedToast.toastId}\n * @param transition - Set this to `true` to remove the toast by the exit\n * transition instead of immediately.\n */\n removeToast = (toastId: string, transition: boolean): void => {\n const toastIndex = this.#getToastIndex(toastId);\n if (toastIndex === -1) {\n return;\n }\n\n if (transition) {\n this.clearTimer(toastId);\n this.#updateToast(toastIndex, { visible: false });\n return;\n }\n\n this.#queue.splice(toastIndex, 1);\n this.#emit();\n };\n\n /**\n * Clears any pending timers for the provided toast id. This should generally\n * be used in the `useEffect` cleanup effect for any custom toast renderer\n * implementations.\n *\n * @example\n * ```tsx\n * const { toastId } = toast;\n * const toastManager = useToastManager();\n *\n * useEffect(() => {\n * return () => {\n * toastManager.clearTimer(toastId):\n * }\n * }, [toastManager, toastId]);\n * ```\n */\n clearTimer = (toastId: string): void => {\n const timer = this.#timers.get(toastId);\n globalThis.clearTimeout(timer?.exitTimeout);\n this.#timers.delete(toastId);\n };\n\n /**\n * Removes first toast from the queue without any exit animation. You most\n * likely want to use {@link removeToast} instead.\n */\n popToast = (): void => {\n this.#queue.pop();\n this.#emit();\n };\n\n /**\n * Removes all toasts from the queue. There will be no exit animation.\n *\n * @param disableEmit - Set this to `true` to disable emitting the empty queue.\n * Mostly used for tests.\n */\n clearToasts = (disableEmit = false): void => {\n this.#queue = [];\n for (const [, meta] of this.#timers) {\n globalThis.clearTimeout(meta.exitTimeout);\n }\n this.#timers.clear();\n if (!disableEmit) {\n this.#emit();\n }\n };\n}\n\n/**\n * The default toast manager for react-md apps that will allow toasts to be\n * added without setting up the {@link ToastManagerProvider}.\n *\n * @internal\n * @since 6.0.0\n */\nexport const toastManager = new ToastManager();\n\n/**\n * @see {@link ToastManager.addToast}\n * @since 6.0.0\n */\nexport const addToast: ToastManager[\"addToast\"] = (toast) => {\n toastManager.addToast(toast);\n};\n\n/**\n * @see {@link ToastManager.startRemoveTimeout}\n * @since 6.0.0\n */\nexport const startRemoveToastTimeout: ToastManager[\"startRemoveTimeout\"] = (\n toastId\n) => {\n toastManager.startRemoveTimeout(toastId);\n};\n\n/**\n * @see {@link ToastManager.popToast}\n * @since 6.0.0\n */\nexport const popToast: ToastManager[\"popToast\"] = () => {\n toastManager.popToast();\n};\n\n/**\n * @see {@link ToastManager.removeToast}\n * @since 6.0.0\n */\nexport const removeToast: ToastManager[\"removeToast\"] = (\n toastId,\n transition\n) => {\n toastManager.removeToast(toastId, transition);\n};\n\n/**\n * @see {@link ToastManager.clearToasts}\n * @since 6.0.0\n */\nexport const clearToasts = (): void => {\n toastManager.clearToasts();\n};\n"],"names":["nanoid","DEFAULT_TOAST_VISIBLE_TIME","ToastManager","callback","toastId","findIndex","toast","nextToast","current","clearTimer","visible","priority","splice","toastIdOrIndex","patch","index","subscribe","push","filter","cb","getQueue","addToast","visibleTime","role","duplicates","existingIndex","existingToast","timers","get","set","elapsedTime","paused","startRemoveTimeout","queueSize","length","cached","inactive","startTime","Date","now","globalThis","clearTimeout","exitTimeout","duration","setTimeout","removeToast","pauseRemoveTimeout","resumeRemoveTimeout","toastIndex","transition","timer","delete","popToast","pop","clearToasts","disableEmit","meta","clear","Map","toastManager","startRemoveToastTimeout"],"mappings":"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"}
@@ -24,7 +24,7 @@ import { selectNode } from "./utils/selectNode.js";
24
24
  // trigger a noop setValue when `value` and `onValueChange` are provided
25
25
  // since `onValueChange is always called with `setValue
26
26
  let propSetValue;
27
- if (typeof propValue !== "undefined" && options.onValueChange) {
27
+ if (propValue !== undefined && options.onValueChange) {
28
28
  propSetValue = noop;
29
29
  }
30
30
  const [value, setValue] = useEnsuredState({