@react-md/core 6.5.0 → 6.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/dist/_utils.scss +5 -1
  2. package/dist/autocomplete/AutocompleteChip.js +2 -2
  3. package/dist/autocomplete/AutocompleteChip.js.map +1 -1
  4. package/dist/autocomplete/AutocompleteListboxChildren.js +1 -1
  5. package/dist/autocomplete/AutocompleteListboxChildren.js.map +1 -1
  6. package/dist/autocomplete/useAutocomplete.js +4 -4
  7. package/dist/autocomplete/useAutocomplete.js.map +1 -1
  8. package/dist/autocomplete/utils.js +3 -3
  9. package/dist/autocomplete/utils.js.map +1 -1
  10. package/dist/box/styles.js +2 -2
  11. package/dist/box/styles.js.map +1 -1
  12. package/dist/button/AsyncButton.js +1 -1
  13. package/dist/button/AsyncButton.js.map +1 -1
  14. package/dist/chip/Chip.js +1 -1
  15. package/dist/chip/Chip.js.map +1 -1
  16. package/dist/cssUtils.d.ts +11 -6
  17. package/dist/cssUtils.js.map +1 -1
  18. package/dist/datetime/useTimeField.js +1 -1
  19. package/dist/datetime/useTimeField.js.map +1 -1
  20. package/dist/delegateEvent.js +9 -9
  21. package/dist/delegateEvent.js.map +1 -1
  22. package/dist/draggable/useDraggable.js +4 -4
  23. package/dist/draggable/useDraggable.js.map +1 -1
  24. package/dist/draggable/utils.js +1 -1
  25. package/dist/draggable/utils.js.map +1 -1
  26. package/dist/expansion-panel/ExpansionPanel.js +1 -1
  27. package/dist/expansion-panel/ExpansionPanel.js.map +1 -1
  28. package/dist/expansion-panel/useExpansionPanels.js +1 -1
  29. package/dist/expansion-panel/useExpansionPanels.js.map +1 -1
  30. package/dist/files/FileInput.js +1 -1
  31. package/dist/files/FileInput.js.map +1 -1
  32. package/dist/files/createAcceptFromExtensions.d.ts +5 -0
  33. package/dist/files/createAcceptFromExtensions.js +15 -0
  34. package/dist/files/createAcceptFromExtensions.js.map +1 -0
  35. package/dist/files/useFileUpload.js +45 -41
  36. package/dist/files/useFileUpload.js.map +1 -1
  37. package/dist/files/utils.js +14 -10
  38. package/dist/files/utils.js.map +1 -1
  39. package/dist/files/validation.js +7 -8
  40. package/dist/files/validation.js.map +1 -1
  41. package/dist/focus/useFocusContainer.js +1 -1
  42. package/dist/focus/useFocusContainer.js.map +1 -1
  43. package/dist/focus/utils.js +12 -7
  44. package/dist/focus/utils.js.map +1 -1
  45. package/dist/form/InputToggleIcon.js +5 -1
  46. package/dist/form/InputToggleIcon.js.map +1 -1
  47. package/dist/form/NativeSelect.js +1 -1
  48. package/dist/form/NativeSelect.js.map +1 -1
  49. package/dist/form/Select.js +5 -5
  50. package/dist/form/Select.js.map +1 -1
  51. package/dist/form/formConfig.js +1 -1
  52. package/dist/form/formConfig.js.map +1 -1
  53. package/dist/form/inputToggleStyles.js +7 -1
  54. package/dist/form/inputToggleStyles.js.map +1 -1
  55. package/dist/form/selectUtils.js +2 -2
  56. package/dist/form/selectUtils.js.map +1 -1
  57. package/dist/form/useCombobox.js +1 -0
  58. package/dist/form/useCombobox.js.map +1 -1
  59. package/dist/form/useFormReset.js +2 -2
  60. package/dist/form/useFormReset.js.map +1 -1
  61. package/dist/form/useNumberField.js +1 -1
  62. package/dist/form/useNumberField.js.map +1 -1
  63. package/dist/form/useResizingTextArea.js +4 -4
  64. package/dist/form/useResizingTextArea.js.map +1 -1
  65. package/dist/form/useSelectCombobox.js +1 -1
  66. package/dist/form/useSelectCombobox.js.map +1 -1
  67. package/dist/form/validation.js +1 -1
  68. package/dist/form/validation.js.map +1 -1
  69. package/dist/hoverMode/useHoverMode.js +8 -8
  70. package/dist/hoverMode/useHoverMode.js.map +1 -1
  71. package/dist/hoverMode/useHoverModeProvider.js +3 -3
  72. package/dist/hoverMode/useHoverModeProvider.js.map +1 -1
  73. package/dist/icon/config.js +3 -3
  74. package/dist/icon/config.js.map +1 -1
  75. package/dist/icon/materialConfig.js +1 -1
  76. package/dist/icon/materialConfig.js.map +1 -1
  77. package/dist/interaction/UserInteractionModeProvider.js +11 -10
  78. package/dist/interaction/UserInteractionModeProvider.js.map +1 -1
  79. package/dist/interaction/utils.js +7 -3
  80. package/dist/interaction/utils.js.map +1 -1
  81. package/dist/layout/useExpandableLayout.js +3 -4
  82. package/dist/layout/useExpandableLayout.js.map +1 -1
  83. package/dist/layout/useMainTabIndex.js +1 -1
  84. package/dist/layout/useMainTabIndex.js.map +1 -1
  85. package/dist/list/ListItem.js +1 -1
  86. package/dist/list/ListItem.js.map +1 -1
  87. package/dist/media-queries/AppSizeProvider.js +1 -1
  88. package/dist/media-queries/AppSizeProvider.js.map +1 -1
  89. package/dist/media-queries/config.js +2 -2
  90. package/dist/media-queries/config.js.map +1 -1
  91. package/dist/media-queries/useMediaQuery.js +3 -3
  92. package/dist/media-queries/useMediaQuery.js.map +1 -1
  93. package/dist/menu/Menu.js +4 -4
  94. package/dist/menu/Menu.js.map +1 -1
  95. package/dist/menu/MenuItemButton.js +1 -1
  96. package/dist/menu/MenuItemButton.js.map +1 -1
  97. package/dist/menu/MenuItemFileInput.js +1 -1
  98. package/dist/menu/MenuItemFileInput.js.map +1 -1
  99. package/dist/menu/MenuWidget.js +2 -2
  100. package/dist/menu/MenuWidget.js.map +1 -1
  101. package/dist/movement/findMatchIndex.js +2 -2
  102. package/dist/movement/findMatchIndex.js.map +1 -1
  103. package/dist/movement/useKeyboardMovementProvider.js +2 -2
  104. package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
  105. package/dist/movement/utils.js +12 -10
  106. package/dist/movement/utils.js.map +1 -1
  107. package/dist/navigation/getTableOfContentsHeadings.js +4 -3
  108. package/dist/navigation/getTableOfContentsHeadings.js.map +1 -1
  109. package/dist/navigation/useActiveHeadingId.js +9 -9
  110. package/dist/navigation/useActiveHeadingId.js.map +1 -1
  111. package/dist/navigation/useTableOfContentsHeadings.js +1 -1
  112. package/dist/navigation/useTableOfContentsHeadings.js.map +1 -1
  113. package/dist/navigation/utils.js +6 -5
  114. package/dist/navigation/utils.js.map +1 -1
  115. package/dist/portal/PortalContainerProvider.js +5 -3
  116. package/dist/portal/PortalContainerProvider.js.map +1 -1
  117. package/dist/positioning/getFixedPosition.js +2 -4
  118. package/dist/positioning/getFixedPosition.js.map +1 -1
  119. package/dist/positioning/useFixedPositioning.js +2 -2
  120. package/dist/positioning/useFixedPositioning.js.map +1 -1
  121. package/dist/positioning/utils.js +3 -3
  122. package/dist/positioning/utils.js.map +1 -1
  123. package/dist/scroll/getScrollbarWidth.js +4 -4
  124. package/dist/scroll/getScrollbarWidth.js.map +1 -1
  125. package/dist/searching/fuzzy.js +3 -2
  126. package/dist/searching/fuzzy.js.map +1 -1
  127. package/dist/searching/toSearchQuery.js +1 -1
  128. package/dist/searching/toSearchQuery.js.map +1 -1
  129. package/dist/searching/utils.js +1 -1
  130. package/dist/searching/utils.js.map +1 -1
  131. package/dist/snackbar/Toast.js +1 -1
  132. package/dist/snackbar/Toast.js.map +1 -1
  133. package/dist/snackbar/ToastContent.js +2 -2
  134. package/dist/snackbar/ToastContent.js.map +1 -1
  135. package/dist/snackbar/ToastManager.d.ts +1 -1
  136. package/dist/snackbar/ToastManager.js +11 -11
  137. package/dist/snackbar/ToastManager.js.map +1 -1
  138. package/dist/spinbutton/useSpinButton.js +1 -1
  139. package/dist/spinbutton/useSpinButton.js.map +1 -1
  140. package/dist/spinbutton/utils/deselectNode.js +1 -1
  141. package/dist/spinbutton/utils/deselectNode.js.map +1 -1
  142. package/dist/spinbutton/utils/resolveInputEvent.js +1 -1
  143. package/dist/spinbutton/utils/resolveInputEvent.js.map +1 -1
  144. package/dist/spinbutton/utils/selectNode.js +1 -1
  145. package/dist/spinbutton/utils/selectNode.js.map +1 -1
  146. package/dist/storage/useStorage.js +8 -3
  147. package/dist/storage/useStorage.js.map +1 -1
  148. package/dist/table/useStickyTableSection.js +1 -1
  149. package/dist/table/useStickyTableSection.js.map +1 -1
  150. package/dist/tabs/TabList.js +2 -2
  151. package/dist/tabs/TabList.js.map +1 -1
  152. package/dist/tabs/useMaxTabPanelHeight.js +4 -3
  153. package/dist/tabs/useMaxTabPanelHeight.js.map +1 -1
  154. package/dist/tabs/useTabList.js +1 -1
  155. package/dist/tabs/useTabList.js.map +1 -1
  156. package/dist/test-utils/jest-globals/match-media.d.ts +1 -1
  157. package/dist/test-utils/jest-globals/match-media.js +1 -1
  158. package/dist/test-utils/jest-globals/match-media.js.map +1 -1
  159. package/dist/test-utils/jest-globals/timers.js +1 -1
  160. package/dist/test-utils/jest-globals/timers.js.map +1 -1
  161. package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js +1 -1
  162. package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js.map +1 -1
  163. package/dist/test-utils/mocks/ResizeObserver.js +2 -2
  164. package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
  165. package/dist/test-utils/polyfills/IntersectionObserver.js +2 -2
  166. package/dist/test-utils/polyfills/IntersectionObserver.js.map +1 -1
  167. package/dist/test-utils/polyfills/ResizeObserver.js +2 -2
  168. package/dist/test-utils/polyfills/ResizeObserver.js.map +1 -1
  169. package/dist/test-utils/polyfills/TextDecoder.js +2 -2
  170. package/dist/test-utils/polyfills/TextDecoder.js.map +1 -1
  171. package/dist/test-utils/polyfills/TextEncoder.js +2 -2
  172. package/dist/test-utils/polyfills/TextEncoder.js.map +1 -1
  173. package/dist/test-utils/polyfills/matchMedia.js +2 -2
  174. package/dist/test-utils/polyfills/matchMedia.js.map +1 -1
  175. package/dist/test-utils/polyfills/offsetParent.js +2 -2
  176. package/dist/test-utils/polyfills/offsetParent.js.map +1 -1
  177. package/dist/test-utils/polyfills/scrollIntoView.js +1 -1
  178. package/dist/test-utils/polyfills/scrollIntoView.js.map +1 -1
  179. package/dist/test-utils/queries/select.js +2 -2
  180. package/dist/test-utils/queries/select.js.map +1 -1
  181. package/dist/test-utils/queries/slider.js +1 -1
  182. package/dist/test-utils/queries/slider.js.map +1 -1
  183. package/dist/test-utils/utils/createFileList.js +2 -0
  184. package/dist/test-utils/utils/createFileList.js.map +1 -1
  185. package/dist/test-utils/utils/createMatchMediaSpy.d.ts +1 -1
  186. package/dist/test-utils/utils/createMatchMediaSpy.js +3 -3
  187. package/dist/test-utils/utils/createMatchMediaSpy.js.map +1 -1
  188. package/dist/test-utils/vitest/match-media.d.ts +1 -1
  189. package/dist/test-utils/vitest/match-media.js +1 -1
  190. package/dist/test-utils/vitest/match-media.js.map +1 -1
  191. package/dist/test-utils/vitest/timers.js +1 -1
  192. package/dist/test-utils/vitest/timers.js.map +1 -1
  193. package/dist/test-utils/vitest/uploadMenuItemFileInput.js +1 -1
  194. package/dist/test-utils/vitest/uploadMenuItemFileInput.js.map +1 -1
  195. package/dist/theme/ThemeProvider.js +2 -2
  196. package/dist/theme/ThemeProvider.js.map +1 -1
  197. package/dist/theme/getDerivedTheme.js +1 -1
  198. package/dist/theme/getDerivedTheme.js.map +1 -1
  199. package/dist/theme/useCSSVariables.js +5 -5
  200. package/dist/theme/useCSSVariables.js.map +1 -1
  201. package/dist/theme/useColorSchemeMetaTag.js +2 -2
  202. package/dist/theme/useColorSchemeMetaTag.js.map +1 -1
  203. package/dist/theme/useInlineCSSVariables.js +4 -3
  204. package/dist/theme/useInlineCSSVariables.js.map +1 -1
  205. package/dist/theme/utils.js +8 -8
  206. package/dist/theme/utils.js.map +1 -1
  207. package/dist/tooltip/useTooltip.js +7 -7
  208. package/dist/tooltip/useTooltip.js.map +1 -1
  209. package/dist/tooltip/useTooltipPosition.js +1 -1
  210. package/dist/tooltip/useTooltipPosition.js.map +1 -1
  211. package/dist/transition/useCarousel.js +2 -2
  212. package/dist/transition/useCarousel.js.map +1 -1
  213. package/dist/transition/useCollapseTransition.js +1 -1
  214. package/dist/transition/useCollapseTransition.js.map +1 -1
  215. package/dist/transition/useSkeletonPlaceholder.js +4 -4
  216. package/dist/transition/useSkeletonPlaceholder.js.map +1 -1
  217. package/dist/transition/useTransition.js +2 -2
  218. package/dist/transition/useTransition.js.map +1 -1
  219. package/dist/transition/utils.js +5 -5
  220. package/dist/transition/utils.js.map +1 -1
  221. package/dist/tree/TreeItem.js +1 -1
  222. package/dist/tree/TreeItem.js.map +1 -1
  223. package/dist/tree/useTreeItems.js +7 -5
  224. package/dist/tree/useTreeItems.js.map +1 -1
  225. package/dist/tree/useTreeMovement.js +1 -1
  226. package/dist/tree/useTreeMovement.js.map +1 -1
  227. package/dist/tree/utils.js +6 -9
  228. package/dist/tree/utils.js.map +1 -1
  229. package/dist/typography/HighlightText.js +2 -1
  230. package/dist/typography/HighlightText.js.map +1 -1
  231. package/dist/typography/SrOnly.js +7 -1
  232. package/dist/typography/SrOnly.js.map +1 -1
  233. package/dist/useDebouncedFunction.js +4 -4
  234. package/dist/useDebouncedFunction.js.map +1 -1
  235. package/dist/useDropzone.js +9 -9
  236. package/dist/useDropzone.js.map +1 -1
  237. package/dist/useEnsuredState.js +5 -5
  238. package/dist/useEnsuredState.js.map +1 -1
  239. package/dist/useIntersectionObserver.js +3 -3
  240. package/dist/useIntersectionObserver.js.map +1 -1
  241. package/dist/useIsomorphicLayoutEffect.js +1 -1
  242. package/dist/useIsomorphicLayoutEffect.js.map +1 -1
  243. package/dist/useOrientation.js +1 -1
  244. package/dist/useOrientation.js.map +1 -1
  245. package/dist/useReadonlySet.js +1 -1
  246. package/dist/useReadonlySet.js.map +1 -1
  247. package/dist/useResizeListener.js +2 -2
  248. package/dist/useResizeListener.js.map +1 -1
  249. package/dist/useResizeObserver.js +3 -4
  250. package/dist/useResizeObserver.js.map +1 -1
  251. package/dist/useThrottledFunction.js +3 -3
  252. package/dist/useThrottledFunction.js.map +1 -1
  253. package/dist/useWindowSize.js +1 -1
  254. package/dist/useWindowSize.js.map +1 -1
  255. package/dist/utils/alphaNumericSort.js +3 -1
  256. package/dist/utils/alphaNumericSort.js.map +1 -1
  257. package/dist/utils/bem.js +9 -12
  258. package/dist/utils/bem.js.map +1 -1
  259. package/dist/utils/getNumberOfDigits.js +1 -0
  260. package/dist/utils/getNumberOfDigits.js.map +1 -1
  261. package/dist/utils/getRangeDefaultValue.js +1 -1
  262. package/dist/utils/getRangeDefaultValue.js.map +1 -1
  263. package/dist/utils/nearest.js +2 -2
  264. package/dist/utils/nearest.js.map +1 -1
  265. package/dist/utils/parseCssLengthUnit.js +3 -3
  266. package/dist/utils/parseCssLengthUnit.js.map +1 -1
  267. package/dist/utils/trigonometry.js +1 -1
  268. package/dist/utils/trigonometry.js.map +1 -1
  269. package/package.json +3 -1
  270. package/src/autocomplete/AutocompleteChip.tsx +2 -2
  271. package/src/autocomplete/AutocompleteListboxChildren.tsx +1 -1
  272. package/src/autocomplete/useAutocomplete.ts +4 -4
  273. package/src/autocomplete/utils.ts +3 -3
  274. package/src/box/styles.ts +2 -2
  275. package/src/button/AsyncButton.tsx +1 -3
  276. package/src/chip/Chip.tsx +1 -2
  277. package/src/cssUtils.ts +12 -6
  278. package/src/datetime/useTimeField.ts +1 -1
  279. package/src/delegateEvent.ts +9 -9
  280. package/src/draggable/useDraggable.ts +4 -4
  281. package/src/draggable/utils.ts +1 -1
  282. package/src/expansion-panel/ExpansionPanel.tsx +1 -1
  283. package/src/expansion-panel/useExpansionPanels.ts +1 -1
  284. package/src/files/FileInput.tsx +1 -1
  285. package/src/files/createAcceptFromExtensions.ts +18 -0
  286. package/src/files/useFileUpload.ts +36 -37
  287. package/src/files/utils.ts +15 -11
  288. package/src/files/validation.ts +7 -9
  289. package/src/focus/useFocusContainer.ts +1 -1
  290. package/src/focus/utils.ts +11 -6
  291. package/src/form/InputToggleIcon.tsx +5 -5
  292. package/src/form/NativeSelect.tsx +1 -1
  293. package/src/form/Select.tsx +5 -5
  294. package/src/form/formConfig.ts +1 -1
  295. package/src/form/inputToggleStyles.ts +9 -4
  296. package/src/form/selectUtils.ts +2 -2
  297. package/src/form/useCombobox.ts +1 -0
  298. package/src/form/useFormReset.ts +2 -2
  299. package/src/form/useNumberField.ts +1 -1
  300. package/src/form/useResizingTextArea.ts +5 -5
  301. package/src/form/useSelectCombobox.ts +1 -4
  302. package/src/form/validation.ts +1 -1
  303. package/src/hoverMode/useHoverMode.ts +9 -9
  304. package/src/hoverMode/useHoverModeProvider.ts +4 -4
  305. package/src/icon/config.tsx +3 -3
  306. package/src/icon/materialConfig.ts +1 -1
  307. package/src/interaction/UserInteractionModeProvider.tsx +11 -10
  308. package/src/interaction/utils.ts +3 -3
  309. package/src/layout/useExpandableLayout.ts +3 -4
  310. package/src/layout/useMainTabIndex.ts +1 -1
  311. package/src/list/ListItem.tsx +1 -1
  312. package/src/media-queries/AppSizeProvider.tsx +1 -1
  313. package/src/media-queries/config.ts +2 -2
  314. package/src/media-queries/useMediaQuery.ts +3 -3
  315. package/src/menu/Menu.tsx +4 -4
  316. package/src/menu/MenuItemButton.tsx +1 -1
  317. package/src/menu/MenuItemFileInput.tsx +1 -1
  318. package/src/menu/MenuWidget.tsx +6 -4
  319. package/src/movement/findMatchIndex.ts +2 -2
  320. package/src/movement/useKeyboardMovementProvider.ts +2 -2
  321. package/src/movement/utils.ts +15 -14
  322. package/src/navigation/getTableOfContentsHeadings.ts +4 -3
  323. package/src/navigation/useActiveHeadingId.ts +8 -8
  324. package/src/navigation/useTableOfContentsHeadings.ts +1 -1
  325. package/src/navigation/utils.ts +6 -5
  326. package/src/portal/PortalContainerProvider.tsx +5 -3
  327. package/src/positioning/getFixedPosition.ts +9 -6
  328. package/src/positioning/useFixedPositioning.ts +2 -2
  329. package/src/positioning/utils.ts +3 -3
  330. package/src/scroll/getScrollbarWidth.ts +4 -4
  331. package/src/searching/fuzzy.ts +7 -3
  332. package/src/searching/toSearchQuery.ts +1 -1
  333. package/src/searching/utils.ts +1 -1
  334. package/src/snackbar/Toast.tsx +1 -1
  335. package/src/snackbar/ToastContent.tsx +2 -2
  336. package/src/snackbar/ToastManager.ts +11 -12
  337. package/src/spinbutton/useSpinButton.ts +1 -1
  338. package/src/spinbutton/utils/deselectNode.ts +1 -1
  339. package/src/spinbutton/utils/resolveInputEvent.ts +1 -1
  340. package/src/spinbutton/utils/selectNode.ts +1 -1
  341. package/src/storage/useStorage.ts +7 -2
  342. package/src/table/useStickyTableSection.tsx +1 -1
  343. package/src/tabs/TabList.tsx +2 -2
  344. package/src/tabs/useMaxTabPanelHeight.ts +6 -3
  345. package/src/tabs/useTabList.ts +2 -2
  346. package/src/test-utils/jest-globals/match-media.ts +5 -2
  347. package/src/test-utils/jest-globals/timers.ts +1 -1
  348. package/src/test-utils/jest-globals/uploadMenuItemFileInput.ts +1 -1
  349. package/src/test-utils/mocks/ResizeObserver.ts +2 -2
  350. package/src/test-utils/polyfills/IntersectionObserver.ts +2 -2
  351. package/src/test-utils/polyfills/ResizeObserver.ts +2 -2
  352. package/src/test-utils/polyfills/TextDecoder.ts +2 -2
  353. package/src/test-utils/polyfills/TextEncoder.ts +2 -2
  354. package/src/test-utils/polyfills/matchMedia.ts +5 -2
  355. package/src/test-utils/polyfills/offsetParent.ts +2 -2
  356. package/src/test-utils/polyfills/scrollIntoView.ts +1 -1
  357. package/src/test-utils/queries/select.ts +2 -2
  358. package/src/test-utils/queries/slider.ts +1 -1
  359. package/src/test-utils/utils/createFileList.ts +2 -0
  360. package/src/test-utils/utils/createMatchMediaSpy.ts +4 -4
  361. package/src/test-utils/vitest/match-media.ts +2 -2
  362. package/src/test-utils/vitest/timers.ts +1 -1
  363. package/src/test-utils/vitest/uploadMenuItemFileInput.ts +1 -1
  364. package/src/theme/ThemeProvider.tsx +2 -2
  365. package/src/theme/getDerivedTheme.ts +1 -1
  366. package/src/theme/useCSSVariables.ts +5 -5
  367. package/src/theme/useColorSchemeMetaTag.ts +2 -2
  368. package/src/theme/useInlineCSSVariables.ts +6 -7
  369. package/src/theme/utils.ts +8 -8
  370. package/src/tooltip/useTooltip.ts +7 -7
  371. package/src/tooltip/useTooltipPosition.ts +1 -1
  372. package/src/transition/useCarousel.ts +2 -2
  373. package/src/transition/useCollapseTransition.ts +1 -1
  374. package/src/transition/useSkeletonPlaceholder.ts +4 -4
  375. package/src/transition/useTransition.ts +2 -2
  376. package/src/transition/utils.ts +5 -5
  377. package/src/tree/TreeItem.tsx +1 -1
  378. package/src/tree/useTreeItems.ts +5 -5
  379. package/src/tree/useTreeMovement.ts +1 -1
  380. package/src/tree/utils.ts +9 -9
  381. package/src/typography/HighlightText.tsx +4 -3
  382. package/src/typography/SrOnly.tsx +9 -2
  383. package/src/useDebouncedFunction.ts +5 -5
  384. package/src/useDropzone.ts +10 -10
  385. package/src/useEnsuredState.ts +5 -5
  386. package/src/useIntersectionObserver.ts +3 -3
  387. package/src/useIsomorphicLayoutEffect.ts +3 -3
  388. package/src/useOrientation.ts +1 -1
  389. package/src/useReadonlySet.ts +3 -1
  390. package/src/useResizeListener.ts +2 -2
  391. package/src/useResizeObserver.ts +3 -4
  392. package/src/useThrottledFunction.ts +4 -4
  393. package/src/useWindowSize.ts +1 -1
  394. package/src/utils/alphaNumericSort.ts +1 -1
  395. package/src/utils/bem.ts +15 -16
  396. package/src/utils/getNumberOfDigits.ts +1 -0
  397. package/src/utils/getRangeDefaultValue.ts +1 -1
  398. package/src/utils/nearest.ts +5 -2
  399. package/src/utils/parseCssLengthUnit.ts +5 -4
  400. package/src/utils/trigonometry.ts +1 -1
  401. package/dist/form/defaultGetSelectedOptionChildren.d.ts +0 -1
  402. package/dist/form/getSelectedOptionChildren.d.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cssUtils.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\n/**\n * - `primary -> $primary-color`\n * - `secondary -> $secondary-color`\n * - `warning -> $warning-color`\n * - `success -> $success-color`\n * - `error -> $error-color`\n *\n * @since 6.0.0\n */\nexport type ThemeColor =\n | \"primary\"\n | \"secondary\"\n | \"warning\"\n | \"success\"\n | \"error\";\n\n/**\n * - `text-primary -> $text-primary-color`\n * - `text-secondary -> $text-secondary-color`\n * - `text-hint -> $text-hint-color`\n * - `text-disabled -> $text-disabled-color`\n *\n * @since 6.0.0\n */\nexport type TextColor =\n | \"text-primary\"\n | \"text-secondary\"\n | \"text-hint\"\n | \"text-disabled\"\n | `on-${ThemeColor}`;\n\n/**\n * @since 6.0.0\n */\nexport type OutlineColor = ThemeColor | \"greyscale\" | \"current-color\";\n\n/**\n * @since 6.0.0\n */\nexport type BackgroundColor = ThemeColor | \"surface\" | \"current-color\";\n\nexport type TextAlign = \"left\" | \"center\" | \"right\";\nexport type TextDecoration = \"underline\" | \"overline\" | \"line-through\" | \"none\";\nexport type TextTransform = \"capitalize\" | \"uppercase\" | \"lowercase\";\nexport type FontStyle = \"italic\" | \"oblique\" | \"normal\";\n\n/**\n * The supported css `font-weight` values.\n *\n * Note: You will need to ensure that you are using a web safe font for all the\n * font weights to work, use variable fonts, or load all font weights for your\n * custom font.\n *\n * @see {@link https://www.google.com/search?q=web+safe+fonts | Web Safe Fonts}\n * @see {@link https://www.google.com/search?q=variable+fonts | Variable Fonts}\n * @since 6.0.0 This was `TextWeight` beforehand.\n */\nexport type FontWeight =\n | \"thin\"\n | \"light\"\n | \"regular\"\n | \"medium\"\n | \"bold\"\n | \"semi-bold\"\n | \"black\";\n\n/**\n * Since the typography within react-md tries to not modify base elements, the\n * default margin applied to heading tags (h1-h6) and paragraph (p) might have\n * large margin that you don't want applied when using this component. You can\n * disable:\n *\n * - only the top margin by setting this prop to `\"bottom\"`\n * - only the bottom margin by setting this prop to `\"top\"`\n * - top and bottom margin by setting this prop to `\"none\"`\n * - or keep the initial behavior: `\"initial\"`\n *\n * @since 6.0.0\n */\nexport type Margin = \"none\" | \"top\" | \"bottom\" | \"centered\";\n\n/** @since 6.0.0 */\nexport type TextOverflow = \"allow\" | \"nowrap\" | \"ellipsis\";\n\n/** @since 6.0.0 */\nexport interface TextCssUtilsOptions {\n textColor?: ThemeColor | TextColor | null;\n\n textAlign?: TextAlign;\n\n textDecoration?: TextDecoration;\n\n textTransform?: TextTransform;\n\n fontWeight?: FontWeight;\n\n fontStyle?: FontStyle;\n\n /**\n * This can be used to remove margin from an element (usually typography\n * elements since the browser applies default margin for those elements).\n *\n * @see {@link Margin}\n */\n margin?: Margin;\n\n /**\n * Set this to `\"nowrap\"` to only prevent line wrap behavior or `\"ellipsis\"`\n * to also hide additional text with ellipsis.\n *\n * @defaultValue `\"allow\"`\n */\n textOverflow?: TextOverflow;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface CssUtilsOptions extends TextCssUtilsOptions {\n className?: string;\n\n /**\n * Set this to `true` to allow the content to only be visible for screen\n * readers. Set this to `\"focusable\"` to allow the content to be visible to\n * screen readers and once focused. Set this to `\"phone\"` to only render the\n * the content as screen reader only text on phones.\n *\n * @defaultValue `false`\n */\n srOnly?: boolean | \"focusable\" | \"phone\";\n\n /**\n * Set this to `\"current-color\"` to inherit the current text color or a\n * specific theme color as the outline `box-shadow`.\n */\n outlineColor?: OutlineColor;\n\n /**\n * When this is defined, a specific theme background-color will be applied\n * along with updating the text color be either `#000` or `#fff` depending on\n * which has the highest contrast ratio.\n */\n backgroundColor?: BackgroundColor;\n\n /**\n * Set this to `true` if the element should act as an interaction surface\n * which will:\n * - display a pointer while hovered\n * - increase the z-index of children to enable higher contrast when\n * `core.$interaction-disable-higher-contrast` is not `true`\n * - add a `::before` pseudo element that will:\n * - gain the focus shadow while `:focus`-ed\n * - add a background-color while `:hover`-ed\n * - show no hover/focus styles while `:disabled` or `[aria-disabled=\"true\"]`\n *\n * @defaultValue `false`\n */\n surface?: boolean;\n\n /**\n * Set this to `\"light\"` or `\"dark\"` to update the hover, focus, press,\n * selected, and ripple colors for the surface type. `\"light\"` surfaces will\n * use `#000` while `\"dark\"` will use `#fff`.\n */\n surfaceColor?: \"light\" | \"dark\";\n}\n\n/**\n * This is used to apply css utility functions to any element within your\n * application such as:\n * - specific theme colors as background, text, or outline color\n * - removing margin\n * - screen reader visible only text\n * - text-align, text-decoration, text-transform, font-style, font-weight\n * - disable line wrap\n *\n * @since 6.0.0\n */\nexport function cssUtils(options: CssUtilsOptions): string {\n const {\n className,\n srOnly,\n textColor,\n outlineColor,\n backgroundColor,\n surface,\n surfaceColor,\n margin,\n fontStyle,\n fontWeight,\n textAlign,\n textDecoration,\n textTransform,\n textOverflow,\n } = options;\n\n const isMarginTop = margin === \"top\";\n const isTextColor =\n textColor === \"text-primary\" ||\n textColor === \"text-secondary\" ||\n textColor === \"text-hint\" ||\n textColor === \"text-disabled\";\n\n return cnb(\n !backgroundColor && !isTextColor && textColor && `rmd-${textColor}-color`,\n !backgroundColor && isTextColor && `rmd-${textColor}-color`,\n backgroundColor && \"rmd-background-container\",\n backgroundColor &&\n backgroundColor !== \"current-color\" &&\n backgroundColor !== \"surface\" &&\n `rmd-${backgroundColor}-container`,\n outlineColor && \"rmd-outline\",\n outlineColor && `rmd-${outlineColor}-outline`,\n (isMarginTop || margin === \"bottom\") &&\n `rmd-no-margin-${isMarginTop ? \"bottom\" : \"top\"}`,\n margin === \"none\" && \"rmd-no-margin\",\n margin === \"centered\" && \"rmd-centered\",\n textAlign && `rmd-align-${textAlign}`,\n textDecoration && `rmd-${textDecoration}`,\n textTransform && `rmd-${textTransform}`,\n fontStyle && `rmd-${fontStyle}`,\n fontWeight && `rmd-${fontWeight}`,\n srOnly && srOnly !== \"phone\" && \"rmd-sr-only\",\n srOnly === \"phone\" && \"rmd-phone-sr-only\",\n srOnly === \"focusable\" && \"rmd-sr-only--focusable\",\n surfaceColor === \"light\" && \"rmd-light-surface\",\n surfaceColor === \"dark\" && \"rmd-dark-surface\",\n textOverflow && textOverflow !== \"allow\" && \"rmd-nowrap\",\n textOverflow === \"ellipsis\" && \"rmd-ellipsis\",\n surface && \"rmd-interaction-surface\",\n className\n );\n}\n"],"names":["cnb","cssUtils","options","className","srOnly","textColor","outlineColor","backgroundColor","surface","surfaceColor","margin","fontStyle","fontWeight","textAlign","textDecoration","textTransform","textOverflow","isMarginTop","isTextColor"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAyKhC;;;;;;;;;;CAUC,GACD,OAAO,SAASC,SAASC,OAAwB;IAC/C,MAAM,EACJC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,YAAY,EACZC,eAAe,EACfC,OAAO,EACPC,YAAY,EACZC,MAAM,EACNC,SAAS,EACTC,UAAU,EACVC,SAAS,EACTC,cAAc,EACdC,aAAa,EACbC,YAAY,EACb,GAAGd;IAEJ,MAAMe,cAAcP,WAAW;IAC/B,MAAMQ,cACJb,cAAc,kBACdA,cAAc,oBACdA,cAAc,eACdA,cAAc;IAEhB,OAAOL,IACL,CAACO,mBAAmB,CAACW,eAAeb,aAAa,CAAC,IAAI,EAAEA,UAAU,MAAM,CAAC,EACzE,CAACE,mBAAmBW,eAAe,CAAC,IAAI,EAAEb,UAAU,MAAM,CAAC,EAC3DE,mBAAmB,4BACnBA,mBACEA,oBAAoB,mBACpBA,oBAAoB,aACpB,CAAC,IAAI,EAAEA,gBAAgB,UAAU,CAAC,EACpCD,gBAAgB,eAChBA,gBAAgB,CAAC,IAAI,EAAEA,aAAa,QAAQ,CAAC,EAC7C,AAACW,CAAAA,eAAeP,WAAW,QAAO,KAChC,CAAC,cAAc,EAAEO,cAAc,WAAW,OAAO,EACnDP,WAAW,UAAU,iBACrBA,WAAW,cAAc,gBACzBG,aAAa,CAAC,UAAU,EAAEA,WAAW,EACrCC,kBAAkB,CAAC,IAAI,EAAEA,gBAAgB,EACzCC,iBAAiB,CAAC,IAAI,EAAEA,eAAe,EACvCJ,aAAa,CAAC,IAAI,EAAEA,WAAW,EAC/BC,cAAc,CAAC,IAAI,EAAEA,YAAY,EACjCR,UAAUA,WAAW,WAAW,eAChCA,WAAW,WAAW,qBACtBA,WAAW,eAAe,0BAC1BK,iBAAiB,WAAW,qBAC5BA,iBAAiB,UAAU,oBAC3BO,gBAAgBA,iBAAiB,WAAW,cAC5CA,iBAAiB,cAAc,gBAC/BR,WAAW,2BACXL;AAEJ"}
1
+ {"version":3,"sources":["../src/cssUtils.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\n/**\n * - `primary -> $primary-color`\n * - `secondary -> $secondary-color`\n * - `warning -> $warning-color`\n * - `success -> $success-color`\n * - `error -> $error-color`\n *\n * @since 6.0.0\n */\nexport type ThemeColor =\n | \"primary\"\n | \"secondary\"\n | \"warning\"\n | \"success\"\n | \"error\";\n\n/**\n * - `text-primary -> $text-primary-color`\n * - `text-secondary -> $text-secondary-color`\n * - `text-hint -> $text-hint-color`\n * - `text-disabled -> $text-disabled-color`\n *\n * @since 6.0.0\n */\nexport type TextColor =\n | \"text-primary\"\n | \"text-secondary\"\n | \"text-hint\"\n | \"text-disabled\"\n | `on-${ThemeColor}`;\n\n/**\n * @since 6.0.0\n */\nexport type OutlineColor = ThemeColor | \"greyscale\" | \"current-color\";\n\n/**\n * @since 6.0.0\n */\nexport type BackgroundColor = ThemeColor | \"surface\" | \"current-color\";\n\nexport type TextAlign = \"left\" | \"center\" | \"right\";\nexport type TextDecoration = \"underline\" | \"overline\" | \"line-through\" | \"none\";\nexport type TextTransform = \"capitalize\" | \"uppercase\" | \"lowercase\";\nexport type FontStyle = \"italic\" | \"oblique\" | \"normal\";\n\n/**\n * The supported css `font-weight` values.\n *\n * Note: You will need to ensure that you are using a web safe font for all the\n * font weights to work, use variable fonts, or load all font weights for your\n * custom font.\n *\n * @see {@link https://www.google.com/search?q=web+safe+fonts | Web Safe Fonts}\n * @see {@link https://www.google.com/search?q=variable+fonts | Variable Fonts}\n * @since 6.0.0 This was `TextWeight` beforehand.\n */\nexport type FontWeight =\n | \"thin\"\n | \"light\"\n | \"regular\"\n | \"medium\"\n | \"bold\"\n | \"semi-bold\"\n | \"black\";\n\n/**\n * Since the typography within react-md tries to not modify base elements, the\n * default margin applied to heading tags (h1-h6) and paragraph (p) might have\n * large margin that you don't want applied when using this component. You can\n * disable:\n *\n * - only the top margin by setting this prop to `\"bottom\"`\n * - only the bottom margin by setting this prop to `\"top\"`\n * - top and bottom margin by setting this prop to `\"none\"`\n * - or keep the initial behavior: `\"initial\"`\n *\n * @since 6.0.0\n */\nexport type Margin = \"none\" | \"top\" | \"bottom\" | \"centered\";\n\n/** @since 6.0.0 */\nexport type TextOverflow = \"allow\" | \"nowrap\" | \"ellipsis\";\n\n/** @since 6.0.0 */\nexport interface TextCssUtilsOptions {\n textColor?: ThemeColor | TextColor | null;\n\n textAlign?: TextAlign;\n\n textDecoration?: TextDecoration;\n\n textTransform?: TextTransform;\n\n fontWeight?: FontWeight;\n\n fontStyle?: FontStyle;\n\n /**\n * This can be used to remove margin from an element (usually typography\n * elements since the browser applies default margin for those elements).\n *\n * @see {@link Margin}\n */\n margin?: Margin;\n\n /**\n * Set this to `\"nowrap\"` to only prevent line wrap behavior or `\"ellipsis\"`\n * to also hide additional text with ellipsis.\n *\n * @defaultValue `\"allow\"`\n */\n textOverflow?: TextOverflow;\n}\n\n/**\n * Set this to `true` to allow the content to only be visible for screen\n * readers. Set this to `\"focusable\"` to allow the content to be visible to\n * screen readers and once focused. Set this to `\"phone\"` to only render the\n * content as screen reader only text on phones.\n *\n * @since 6.5.1\n */\nexport type SrOnlyBehavior = boolean | \"focusable\" | \"phone\";\n\n/**\n * @since 6.0.0\n */\nexport interface CssUtilsOptions extends TextCssUtilsOptions {\n className?: string;\n\n /**\n * @see {@link SrOnlyBehavior}\n * @defaultValue `false`\n */\n srOnly?: SrOnlyBehavior;\n\n /**\n * Set this to `\"current-color\"` to inherit the current text color or a\n * specific theme color as the outline `box-shadow`.\n */\n outlineColor?: OutlineColor;\n\n /**\n * When this is defined, a specific theme background-color will be applied\n * along with updating the text color be either `#000` or `#fff` depending on\n * which has the highest contrast ratio.\n */\n backgroundColor?: BackgroundColor;\n\n /**\n * Set this to `true` if the element should act as an interaction surface\n * which will:\n * - display a pointer while hovered\n * - increase the z-index of children to enable higher contrast when\n * `core.$interaction-disable-higher-contrast` is not `true`\n * - add a `::before` pseudo element that will:\n * - gain the focus shadow while `:focus`-ed\n * - add a background-color while `:hover`-ed\n * - show no hover/focus styles while `:disabled` or `[aria-disabled=\"true\"]`\n *\n * @defaultValue `false`\n */\n surface?: boolean;\n\n /**\n * Set this to `\"light\"` or `\"dark\"` to update the hover, focus, press,\n * selected, and ripple colors for the surface type. `\"light\"` surfaces will\n * use `#000` while `\"dark\"` will use `#fff`.\n */\n surfaceColor?: \"light\" | \"dark\";\n}\n\n/**\n * This is used to apply css utility functions to any element within your\n * application such as:\n * - specific theme colors as background, text, or outline color\n * - removing margin\n * - screen reader visible only text\n * - text-align, text-decoration, text-transform, font-style, font-weight\n * - disable line wrap\n *\n * @since 6.0.0\n */\nexport function cssUtils(options: CssUtilsOptions): string {\n const {\n className,\n srOnly,\n textColor,\n outlineColor,\n backgroundColor,\n surface,\n surfaceColor,\n margin,\n fontStyle,\n fontWeight,\n textAlign,\n textDecoration,\n textTransform,\n textOverflow,\n } = options;\n\n const isMarginTop = margin === \"top\";\n const isTextColor =\n textColor === \"text-primary\" ||\n textColor === \"text-secondary\" ||\n textColor === \"text-hint\" ||\n textColor === \"text-disabled\";\n\n return cnb(\n !backgroundColor && !isTextColor && textColor && `rmd-${textColor}-color`,\n !backgroundColor && isTextColor && `rmd-${textColor}-color`,\n backgroundColor && \"rmd-background-container\",\n backgroundColor &&\n backgroundColor !== \"current-color\" &&\n backgroundColor !== \"surface\" &&\n `rmd-${backgroundColor}-container`,\n outlineColor && \"rmd-outline\",\n outlineColor && `rmd-${outlineColor}-outline`,\n (isMarginTop || margin === \"bottom\") &&\n `rmd-no-margin-${isMarginTop ? \"bottom\" : \"top\"}`,\n margin === \"none\" && \"rmd-no-margin\",\n margin === \"centered\" && \"rmd-centered\",\n textAlign && `rmd-align-${textAlign}`,\n textDecoration && `rmd-${textDecoration}`,\n textTransform && `rmd-${textTransform}`,\n fontStyle && `rmd-${fontStyle}`,\n fontWeight && `rmd-${fontWeight}`,\n srOnly && srOnly !== \"phone\" && \"rmd-sr-only\",\n srOnly === \"phone\" && \"rmd-phone-sr-only\",\n srOnly === \"focusable\" && \"rmd-sr-only--focusable\",\n surfaceColor === \"light\" && \"rmd-light-surface\",\n surfaceColor === \"dark\" && \"rmd-dark-surface\",\n textOverflow && textOverflow !== \"allow\" && \"rmd-nowrap\",\n textOverflow === \"ellipsis\" && \"rmd-ellipsis\",\n surface && \"rmd-interaction-surface\",\n className\n );\n}\n"],"names":["cnb","cssUtils","options","className","srOnly","textColor","outlineColor","backgroundColor","surface","surfaceColor","margin","fontStyle","fontWeight","textAlign","textDecoration","textTransform","textOverflow","isMarginTop","isTextColor"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AA+KhC;;;;;;;;;;CAUC,GACD,OAAO,SAASC,SAASC,OAAwB;IAC/C,MAAM,EACJC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,YAAY,EACZC,eAAe,EACfC,OAAO,EACPC,YAAY,EACZC,MAAM,EACNC,SAAS,EACTC,UAAU,EACVC,SAAS,EACTC,cAAc,EACdC,aAAa,EACbC,YAAY,EACb,GAAGd;IAEJ,MAAMe,cAAcP,WAAW;IAC/B,MAAMQ,cACJb,cAAc,kBACdA,cAAc,oBACdA,cAAc,eACdA,cAAc;IAEhB,OAAOL,IACL,CAACO,mBAAmB,CAACW,eAAeb,aAAa,CAAC,IAAI,EAAEA,UAAU,MAAM,CAAC,EACzE,CAACE,mBAAmBW,eAAe,CAAC,IAAI,EAAEb,UAAU,MAAM,CAAC,EAC3DE,mBAAmB,4BACnBA,mBACEA,oBAAoB,mBACpBA,oBAAoB,aACpB,CAAC,IAAI,EAAEA,gBAAgB,UAAU,CAAC,EACpCD,gBAAgB,eAChBA,gBAAgB,CAAC,IAAI,EAAEA,aAAa,QAAQ,CAAC,EAC7C,AAACW,CAAAA,eAAeP,WAAW,QAAO,KAChC,CAAC,cAAc,EAAEO,cAAc,WAAW,OAAO,EACnDP,WAAW,UAAU,iBACrBA,WAAW,cAAc,gBACzBG,aAAa,CAAC,UAAU,EAAEA,WAAW,EACrCC,kBAAkB,CAAC,IAAI,EAAEA,gBAAgB,EACzCC,iBAAiB,CAAC,IAAI,EAAEA,eAAe,EACvCJ,aAAa,CAAC,IAAI,EAAEA,WAAW,EAC/BC,cAAc,CAAC,IAAI,EAAEA,YAAY,EACjCR,UAAUA,WAAW,WAAW,eAChCA,WAAW,WAAW,qBACtBA,WAAW,eAAe,0BAC1BK,iBAAiB,WAAW,qBAC5BA,iBAAiB,UAAU,oBAC3BO,gBAAgBA,iBAAiB,WAAW,cAC5CA,iBAAiB,cAAc,gBAC/BR,WAAW,2BACXL;AAEJ"}
@@ -33,7 +33,7 @@ import { getTimeStep } from "./utils.js";
33
33
  * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}
34
34
  */ export function useTimeField(options) {
35
35
  const { min, max, step, ...fieldOptions } = options;
36
- if (process.env.NODE_ENV !== "production" && typeof step !== "undefined" && (!min || !max)) {
36
+ if (process.env.NODE_ENV !== "production" && step !== undefined && (!min || !max)) {
37
37
  throw new Error("A `step` was provided to a time field without the `min` or `max` props.");
38
38
  }
39
39
  const { errorMessage, fieldProps, ...impl } = useTextField(fieldOptions);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/datetime/useTimeField.ts"],"sourcesContent":["\"use client\";\n\nimport { type InputHTMLAttributes, useRef } from \"react\";\n\nimport {\n type ProvidedFormMessageProps,\n type ProvidedTextFieldProps,\n type TextFieldHookOptions,\n type TextFieldImplementation,\n type TextFieldWithMessageImplementation,\n useTextField,\n} from \"../form/useTextField.js\";\nimport { type TimeFieldStepOptions, getTimeStep } from \"./utils.js\";\n\n/** @since 6.3.0 */\nexport interface TimeFieldConstraints {\n /**\n * This **must** be in the format `HH:mm`:\n * - `00:30` (12:30 AM)\n * - `15:15` (03:15 PM)\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}\n */\n min?: string;\n\n /**\n * This **must** be in the format `HH:mm`:\n * - `00:30` (12:30 AM)\n * - `15:15` (03:15 PM)\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}\n */\n max?: string;\n\n /**\n * For time inputs, the value of step is given in seconds, with a scaling\n * factor of 1000 (since the underlying numeric value is in milliseconds).\n * The default value of step is 60, indicating 60 seconds (or 1 minute, or\n * 60,000 milliseconds).\n *\n * When any is set as the value for step, the default 60 seconds is used, and\n * the seconds value is not displayed in the UI.\n *\n * Here are a few examples:\n *\n * - `15` -&gt; 15 seconds\n * - `60` -&gt; 1 minute\n * - `900` -&gt; 15 minutes\n * - `3600` -&gt; 1 hour\n *\n * Since this might be a bit confusing, the values can be provided in an\n * object instead:\n *\n * ```ts\n * { seconds: 30 }\n * { minutes: 1 }\n * { minutes: 15 }\n * { hours: 1 }\n * { seconds: 15, minutes: 30, hours: 1 }\n * ```\n *\n * NOTE: The `min` and `max` props **must** be provided as well for the\n * `step` to work.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#step | step attribute}\n */\n step?: number | \"any\" | TimeFieldStepOptions;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldOptions\n extends\n Omit<\n TextFieldHookOptions,\n | \"isNumber\"\n | \"counter\"\n | \"pattern\"\n | \"maxLength\"\n | \"minLength\"\n | \"disableMaxLength\"\n >,\n TimeFieldConstraints {}\n\n/** @since 6.3.0 */\nexport interface ProvidedTimeFieldProps\n extends\n Omit<ProvidedTextFieldProps, \"value\">,\n Omit<TimeFieldConstraints, \"step\"> {\n type: \"time\";\n step?: number | \"any\";\n defaultValue: Required<InputHTMLAttributes<HTMLInputElement>>[\"defaultValue\"];\n}\n\n/** @since 6.3.0 */\nexport interface ProvidedTimeFieldMessageProps extends ProvidedTimeFieldProps {\n /**\n * These props will be defined as long as the `disableMessage` prop is not\n * `true` from the `useTextField` hook.\n */\n messageProps: ProvidedFormMessageProps;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldImplementation extends Omit<\n TextFieldImplementation,\n \"fieldProps\"\n> {\n fieldProps: ProvidedTimeFieldProps;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldWithMessageImplementation extends Omit<\n TextFieldWithMessageImplementation,\n \"fieldProps\"\n> {\n fieldProps: ProvidedTimeFieldMessageProps;\n}\n\n/** @since 6.3.0 */\nexport interface ValidatedTimeFieldImplementation extends TimeFieldImplementation {\n fieldProps: ProvidedTimeFieldProps | ProvidedTimeFieldMessageProps;\n}\n\n/**\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions & { disableMessage: true }\n): TimeFieldImplementation;\n\n/**\n * The `useTimeField` is a small wrapper around the {@link useTextField} to be used\n * with `<input type=\"time\" />`. It is used in the `NativeTimeField` if an example\n * implementation would like to be seen.\n *\n * @example Simple Example\n * ```tsx\n * import { useTimeField } from \"@react-md/core/datetime/useTimeField\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { value, fieldProps, error, errorMessage } = useTimeField({\n * name: \"appt\",\n * required: true,\n * min: \"08:00\",\n * max: \"17:00\",\n * step: { minute: 15 },\n * disableMessage: true,\n * });\n *\n * // value: `\"\"` or `\"HH:mm\"`\n *\n * return <TextField label=\"Appointment\" {...fieldProps} />\n * }\n * ```\n *\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions\n): TimeFieldWithMessageImplementation;\n\n/**\n * The `useTimeField` is a small wrapper around the {@link useTextField} to be used\n * with `<input type=\"time\" />`. It is used in the `NativeTimeField` if an example\n * implementation would like to be seen.\n *\n * @example Simple Example\n * ```tsx\n * import { useTimeField } from \"@react-md/core/datetime/useTimeField\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { value, fieldProps } = useTimeField({\n * name: \"appt\",\n * required: true,\n * min: \"08:00\",\n * max: \"17:00\",\n * step: { minute: 15 },\n * });\n *\n * // value: `\"\"` or `\"HH:mm\"`\n *\n * return <TextField label=\"Appointment\" {...fieldProps} />\n * }\n * ```\n *\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions\n): ValidatedTimeFieldImplementation {\n const { min, max, step, ...fieldOptions } = options;\n if (\n process.env.NODE_ENV !== \"production\" &&\n typeof step !== \"undefined\" &&\n (!min || !max)\n ) {\n throw new Error(\n \"A `step` was provided to a time field without the `min` or `max` props.\"\n );\n }\n\n const { errorMessage, fieldProps, ...impl } = useTextField(fieldOptions);\n\n // NOTE: Unlike the other text field components, the `value` should **not**\n // be provided since the time input behaves a bit weirdly with the `onChange`\n // event and it is better to rely on default browser behavior instead of\n // controlling the value. The flow is:\n // - user types `12:30`\n // - `onChange` is fired with `12:30`\n // - user selects `30` and hits backspace\n // - `onChange` is fired with `\"\"`\n // If the `value` is set, the other time values would be lost\n const { value, ...allowedFieldProps } = fieldProps;\n const initial = useRef(value);\n\n return {\n ...impl,\n errorMessage,\n fieldProps: {\n ...allowedFieldProps,\n defaultValue: initial.current,\n min,\n max,\n step: getTimeStep(step),\n type: \"time\",\n },\n };\n}\n"],"names":["useRef","useTextField","getTimeStep","useTimeField","options","min","max","step","fieldOptions","process","env","NODE_ENV","Error","errorMessage","fieldProps","impl","value","allowedFieldProps","initial","defaultValue","current","type"],"mappings":"AAAA;AAEA,SAAmCA,MAAM,QAAQ,QAAQ;AAEzD,SAMEC,YAAY,QACP,0BAA0B;AACjC,SAAoCC,WAAW,QAAQ,aAAa;AA2JpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BC,GACD,OAAO,SAASC,aACdC,OAAyB;IAEzB,MAAM,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GAAGC,cAAc,GAAGJ;IAC5C,IACEK,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBACzB,OAAOJ,SAAS,eACf,CAAA,CAACF,OAAO,CAACC,GAAE,GACZ;QACA,MAAM,IAAIM,MACR;IAEJ;IAEA,MAAM,EAAEC,YAAY,EAAEC,UAAU,EAAE,GAAGC,MAAM,GAAGd,aAAaO;IAE3D,2EAA2E;IAC3E,6EAA6E;IAC7E,wEAAwE;IACxE,sCAAsC;IACtC,uBAAuB;IACvB,uCAAuC;IACvC,yCAAyC;IACzC,oCAAoC;IACpC,6DAA6D;IAC7D,MAAM,EAAEQ,KAAK,EAAE,GAAGC,mBAAmB,GAAGH;IACxC,MAAMI,UAAUlB,OAAOgB;IAEvB,OAAO;QACL,GAAGD,IAAI;QACPF;QACAC,YAAY;YACV,GAAGG,iBAAiB;YACpBE,cAAcD,QAAQE,OAAO;YAC7Bf;YACAC;YACAC,MAAML,YAAYK;YAClBc,MAAM;QACR;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/datetime/useTimeField.ts"],"sourcesContent":["\"use client\";\n\nimport { type InputHTMLAttributes, useRef } from \"react\";\n\nimport {\n type ProvidedFormMessageProps,\n type ProvidedTextFieldProps,\n type TextFieldHookOptions,\n type TextFieldImplementation,\n type TextFieldWithMessageImplementation,\n useTextField,\n} from \"../form/useTextField.js\";\nimport { type TimeFieldStepOptions, getTimeStep } from \"./utils.js\";\n\n/** @since 6.3.0 */\nexport interface TimeFieldConstraints {\n /**\n * This **must** be in the format `HH:mm`:\n * - `00:30` (12:30 AM)\n * - `15:15` (03:15 PM)\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}\n */\n min?: string;\n\n /**\n * This **must** be in the format `HH:mm`:\n * - `00:30` (12:30 AM)\n * - `15:15` (03:15 PM)\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}\n */\n max?: string;\n\n /**\n * For time inputs, the value of step is given in seconds, with a scaling\n * factor of 1000 (since the underlying numeric value is in milliseconds).\n * The default value of step is 60, indicating 60 seconds (or 1 minute, or\n * 60,000 milliseconds).\n *\n * When any is set as the value for step, the default 60 seconds is used, and\n * the seconds value is not displayed in the UI.\n *\n * Here are a few examples:\n *\n * - `15` -&gt; 15 seconds\n * - `60` -&gt; 1 minute\n * - `900` -&gt; 15 minutes\n * - `3600` -&gt; 1 hour\n *\n * Since this might be a bit confusing, the values can be provided in an\n * object instead:\n *\n * ```ts\n * { seconds: 30 }\n * { minutes: 1 }\n * { minutes: 15 }\n * { hours: 1 }\n * { seconds: 15, minutes: 30, hours: 1 }\n * ```\n *\n * NOTE: The `min` and `max` props **must** be provided as well for the\n * `step` to work.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#step | step attribute}\n */\n step?: number | \"any\" | TimeFieldStepOptions;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldOptions\n extends\n Omit<\n TextFieldHookOptions,\n | \"isNumber\"\n | \"counter\"\n | \"pattern\"\n | \"maxLength\"\n | \"minLength\"\n | \"disableMaxLength\"\n >,\n TimeFieldConstraints {}\n\n/** @since 6.3.0 */\nexport interface ProvidedTimeFieldProps\n extends\n Omit<ProvidedTextFieldProps, \"value\">,\n Omit<TimeFieldConstraints, \"step\"> {\n type: \"time\";\n step?: number | \"any\";\n defaultValue: Required<InputHTMLAttributes<HTMLInputElement>>[\"defaultValue\"];\n}\n\n/** @since 6.3.0 */\nexport interface ProvidedTimeFieldMessageProps extends ProvidedTimeFieldProps {\n /**\n * These props will be defined as long as the `disableMessage` prop is not\n * `true` from the `useTextField` hook.\n */\n messageProps: ProvidedFormMessageProps;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldImplementation extends Omit<\n TextFieldImplementation,\n \"fieldProps\"\n> {\n fieldProps: ProvidedTimeFieldProps;\n}\n\n/** @since 6.3.0 */\nexport interface TimeFieldWithMessageImplementation extends Omit<\n TextFieldWithMessageImplementation,\n \"fieldProps\"\n> {\n fieldProps: ProvidedTimeFieldMessageProps;\n}\n\n/** @since 6.3.0 */\nexport interface ValidatedTimeFieldImplementation extends TimeFieldImplementation {\n fieldProps: ProvidedTimeFieldProps | ProvidedTimeFieldMessageProps;\n}\n\n/**\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions & { disableMessage: true }\n): TimeFieldImplementation;\n\n/**\n * The `useTimeField` is a small wrapper around the {@link useTextField} to be used\n * with `<input type=\"time\" />`. It is used in the `NativeTimeField` if an example\n * implementation would like to be seen.\n *\n * @example Simple Example\n * ```tsx\n * import { useTimeField } from \"@react-md/core/datetime/useTimeField\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { value, fieldProps, error, errorMessage } = useTimeField({\n * name: \"appt\",\n * required: true,\n * min: \"08:00\",\n * max: \"17:00\",\n * step: { minute: 15 },\n * disableMessage: true,\n * });\n *\n * // value: `\"\"` or `\"HH:mm\"`\n *\n * return <TextField label=\"Appointment\" {...fieldProps} />\n * }\n * ```\n *\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions\n): TimeFieldWithMessageImplementation;\n\n/**\n * The `useTimeField` is a small wrapper around the {@link useTextField} to be used\n * with `<input type=\"time\" />`. It is used in the `NativeTimeField` if an example\n * implementation would like to be seen.\n *\n * @example Simple Example\n * ```tsx\n * import { useTimeField } from \"@react-md/core/datetime/useTimeField\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { value, fieldProps } = useTimeField({\n * name: \"appt\",\n * required: true,\n * min: \"08:00\",\n * max: \"17:00\",\n * step: { minute: 15 },\n * });\n *\n * // value: `\"\"` or `\"HH:mm\"`\n *\n * return <TextField label=\"Appointment\" {...fieldProps} />\n * }\n * ```\n *\n * @since 6.3.0\n * @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}\n * @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}\n */\nexport function useTimeField(\n options: TimeFieldOptions\n): ValidatedTimeFieldImplementation {\n const { min, max, step, ...fieldOptions } = options;\n if (\n process.env.NODE_ENV !== \"production\" &&\n step !== undefined &&\n (!min || !max)\n ) {\n throw new Error(\n \"A `step` was provided to a time field without the `min` or `max` props.\"\n );\n }\n\n const { errorMessage, fieldProps, ...impl } = useTextField(fieldOptions);\n\n // NOTE: Unlike the other text field components, the `value` should **not**\n // be provided since the time input behaves a bit weirdly with the `onChange`\n // event and it is better to rely on default browser behavior instead of\n // controlling the value. The flow is:\n // - user types `12:30`\n // - `onChange` is fired with `12:30`\n // - user selects `30` and hits backspace\n // - `onChange` is fired with `\"\"`\n // If the `value` is set, the other time values would be lost\n const { value, ...allowedFieldProps } = fieldProps;\n const initial = useRef(value);\n\n return {\n ...impl,\n errorMessage,\n fieldProps: {\n ...allowedFieldProps,\n defaultValue: initial.current,\n min,\n max,\n step: getTimeStep(step),\n type: \"time\",\n },\n };\n}\n"],"names":["useRef","useTextField","getTimeStep","useTimeField","options","min","max","step","fieldOptions","process","env","NODE_ENV","undefined","Error","errorMessage","fieldProps","impl","value","allowedFieldProps","initial","defaultValue","current","type"],"mappings":"AAAA;AAEA,SAAmCA,MAAM,QAAQ,QAAQ;AAEzD,SAMEC,YAAY,QACP,0BAA0B;AACjC,SAAoCC,WAAW,QAAQ,aAAa;AA2JpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BC,GACD,OAAO,SAASC,aACdC,OAAyB;IAEzB,MAAM,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GAAGC,cAAc,GAAGJ;IAC5C,IACEK,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBACzBJ,SAASK,aACR,CAAA,CAACP,OAAO,CAACC,GAAE,GACZ;QACA,MAAM,IAAIO,MACR;IAEJ;IAEA,MAAM,EAAEC,YAAY,EAAEC,UAAU,EAAE,GAAGC,MAAM,GAAGf,aAAaO;IAE3D,2EAA2E;IAC3E,6EAA6E;IAC7E,wEAAwE;IACxE,sCAAsC;IACtC,uBAAuB;IACvB,uCAAuC;IACvC,yCAAyC;IACzC,oCAAoC;IACpC,6DAA6D;IAC7D,MAAM,EAAES,KAAK,EAAE,GAAGC,mBAAmB,GAAGH;IACxC,MAAMI,UAAUnB,OAAOiB;IAEvB,OAAO;QACL,GAAGD,IAAI;QACPF;QACAC,YAAY;YACV,GAAGG,iBAAiB;YACpBE,cAAcD,QAAQE,OAAO;YAC7BhB;YACAC;YACAC,MAAML,YAAYK;YAClBe,MAAM;QACR;IACF;AACF"}
@@ -12,8 +12,8 @@
12
12
  */ function createEventHandler(throttle, callbacks) {
13
13
  let running = false;
14
14
  const runCallbacks = (event)=>()=>{
15
- for(let i = 0; i < callbacks.length; i += 1){
16
- callbacks[i](event);
15
+ for (const callback of callbacks){
16
+ callback(event);
17
17
  }
18
18
  running = false;
19
19
  };
@@ -26,13 +26,13 @@
26
26
  return;
27
27
  }
28
28
  running = true;
29
- window.requestAnimationFrame(runCallbacks(event));
29
+ globalThis.requestAnimationFrame(runCallbacks(event));
30
30
  };
31
31
  }
32
32
  /**
33
33
  * Creates a throttled event handler for the provided event type and event
34
34
  * target.
35
- */ function createDelegatedEventHandler(eventType, eventTarget = window, throttle = false, options) {
35
+ */ function createDelegatedEventHandler(eventType, eventTarget = globalThis.window, throttle = false, options) {
36
36
  const callbacks = [];
37
37
  const handler = createEventHandler(throttle, callbacks);
38
38
  return {
@@ -41,10 +41,10 @@
41
41
  * throttled event. If this is the first callback to be added, the throttled
42
42
  * event will also be started.
43
43
  */ add: (callback)=>{
44
- if (!callbacks.length) {
44
+ if (callbacks.length === 0) {
45
45
  eventTarget.addEventListener(eventType, handler, options);
46
46
  }
47
- if (callbacks.indexOf(callback) === -1) {
47
+ if (!callbacks.includes(callback)) {
48
48
  callbacks.push(callback);
49
49
  }
50
50
  },
@@ -54,9 +54,9 @@
54
54
  * throttled event will also be stopped.
55
55
  */ remove: (callback)=>{
56
56
  const i = callbacks.indexOf(callback);
57
- if (i >= 0) {
57
+ if (i !== -1) {
58
58
  callbacks.splice(i, 1);
59
- if (!callbacks.length) {
59
+ if (callbacks.length === 0) {
60
60
  eventTarget.removeEventListener(eventType, handler, options);
61
61
  }
62
62
  }
@@ -87,7 +87,7 @@
87
87
  * @returns The delegated event handler that allows you to add or remove
88
88
  * `EventListener`s to that event.
89
89
  * @internal
90
- */ export function delegateEvent(eventType, eventTarget = window, throttle = eventType === "resize" || eventType === "scroll", options) {
90
+ */ export function delegateEvent(eventType, eventTarget = globalThis.window, throttle = eventType === "resize" || eventType === "scroll", options) {
91
91
  let index = delegatedEvents.findIndex((event)=>event.type === eventType && event.target === eventTarget && event.options === options && event.throttle === throttle);
92
92
  if (index === -1) {
93
93
  delegatedEvents.push({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/delegateEvent.ts"],"sourcesContent":["/** @internal */\nexport type DelegatedEventTarget = Window | Document | HTMLElement;\n\n/**\n * This is a \"shared\" event handler for the provided `eventType`. The event\n * listener will only be created once, but every single callback will be called\n * when the throttled event is triggered. This means that you will need to make\n * sure to remove the provided callback when it is no longer in use.\n *\n * @internal\n */\nexport interface DelegatedEventHandler {\n /**\n * Adds the provided callback to the throttled event listener.\n */\n add: (callback: EventListener) => void;\n\n /**\n * Attempts to remove the provided callback from the throttled event listener.\n */\n remove: (callback: EventListener) => void;\n}\n\n/** @internal */\nexport interface DelegableEvent {\n type: string;\n target: DelegatedEventTarget;\n throttle: boolean;\n handler: DelegatedEventHandler;\n options?: boolean | AddEventListenerOptions;\n}\n\nconst delegatedEvents: DelegableEvent[] = [];\n\n/**\n * Creates the delegated event handler that will run all the callbacks once an\n * event happens. The callbacks' invocation can also be throttled for event\n * types that trigger rapidly for additional performance.\n *\n * The `<K extends keyof WindowEventMap` is a nice thing I found while looking\n * through the `lib.d.ts` implementation of `addEventListener` that will allow\n * you to get the \"correct\" event type when using the `add` and `remove`\n * functions once you have created this event handler. Otherwise there'd be ts\n * errors trying to do `MouseEvent` or `KeyboardEvent` in your listeners.\n */\nfunction createEventHandler(\n throttle: boolean,\n callbacks: readonly EventListener[]\n): (event: WindowEventMap[keyof WindowEventMap]) => void {\n let running = false;\n const runCallbacks = (event: WindowEventMap[keyof WindowEventMap]) => () => {\n for (let i = 0; i < callbacks.length; i += 1) {\n callbacks[i](event);\n }\n\n running = false;\n };\n\n return function eventHandler(event) {\n if (!throttle) {\n runCallbacks(event)();\n return;\n }\n\n if (running) {\n return;\n }\n\n running = true;\n window.requestAnimationFrame(runCallbacks(event));\n };\n}\n\n/**\n * Creates a throttled event handler for the provided event type and event\n * target.\n */\nfunction createDelegatedEventHandler(\n eventType: string,\n eventTarget: DelegatedEventTarget = window,\n throttle = false,\n options?: boolean | AddEventListenerOptions\n): DelegatedEventHandler {\n const callbacks: EventListener[] = [];\n const handler = createEventHandler(throttle, callbacks);\n\n return {\n /**\n * Attempts to add the provided callback to the list of callbacks for the\n * throttled event. If this is the first callback to be added, the throttled\n * event will also be started.\n */\n add: (callback: EventListener) => {\n if (!callbacks.length) {\n eventTarget.addEventListener(eventType, handler, options);\n }\n\n if (callbacks.indexOf(callback) === -1) {\n callbacks.push(callback);\n }\n },\n\n /**\n * Attempts to remove the provided callback from the list of callbacks for\n * the throttled event. If this is the last callback that was removed, the\n * throttled event will also be stopped.\n */\n remove: (callback: EventListener) => {\n const i = callbacks.indexOf(callback);\n if (i >= 0) {\n callbacks.splice(i, 1);\n\n if (!callbacks.length) {\n eventTarget.removeEventListener(eventType, handler, options);\n }\n }\n },\n };\n}\n\n/**\n * Creates a delegated event listener using custom events. Most of this code\n * comes from the MDN about resize listeners.\n *\n * This will return an object for adding or removing event handlers for the\n * provided `eventType` since only one base throttled event listener will be\n * created. Each callback that is added will be called with the event each time\n * the event is triggered. This does mean that you will manually need to remove\n * your callback like normal or else it can be called when no longer in use.\n * This also means that it doesn't \"hurt\" to call this function without\n * immediately calling the `add` function since the event won't start until\n * there is at least 1 callback.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/Events/resize#Examples\n * @param eventType - One of the event types that should be used to create a\n * delegated event for. This should be things like resize, click, scroll, etc.\n * @param eventTarget - The target that should have the delegated event handler\n * attached to. This is normally the window, but can be any element as needed.\n * @param throttle - Boolean if the event should be throttled or not. Normally\n * only event types like resize or scroll should be throttled for performance\n * boosts, but anything can be.\n * @returns The delegated event handler that allows you to add or remove\n * `EventListener`s to that event.\n * @internal\n */\nexport function delegateEvent(\n eventType: string,\n eventTarget: DelegatedEventTarget = window,\n throttle: boolean = eventType === \"resize\" || eventType === \"scroll\",\n options?: boolean | AddEventListenerOptions\n): DelegatedEventHandler {\n let index = delegatedEvents.findIndex(\n (event) =>\n event.type === eventType &&\n event.target === eventTarget &&\n event.options === options &&\n event.throttle === throttle\n );\n\n if (index === -1) {\n delegatedEvents.push({\n type: eventType,\n target: eventTarget,\n options,\n throttle,\n handler: createDelegatedEventHandler(\n eventType,\n eventTarget,\n throttle,\n options\n ),\n });\n\n index = delegatedEvents.length - 1;\n }\n\n return delegatedEvents[index].handler;\n}\n"],"names":["delegatedEvents","createEventHandler","throttle","callbacks","running","runCallbacks","event","i","length","eventHandler","window","requestAnimationFrame","createDelegatedEventHandler","eventType","eventTarget","options","handler","add","callback","addEventListener","indexOf","push","remove","splice","removeEventListener","delegateEvent","index","findIndex","type","target"],"mappings":"AAAA,cAAc,GAgCd,MAAMA,kBAAoC,EAAE;AAE5C;;;;;;;;;;CAUC,GACD,SAASC,mBACPC,QAAiB,EACjBC,SAAmC;IAEnC,IAAIC,UAAU;IACd,MAAMC,eAAe,CAACC,QAAgD;YACpE,IAAK,IAAIC,IAAI,GAAGA,IAAIJ,UAAUK,MAAM,EAAED,KAAK,EAAG;gBAC5CJ,SAAS,CAACI,EAAE,CAACD;YACf;YAEAF,UAAU;QACZ;IAEA,OAAO,SAASK,aAAaH,KAAK;QAChC,IAAI,CAACJ,UAAU;YACbG,aAAaC;YACb;QACF;QAEA,IAAIF,SAAS;YACX;QACF;QAEAA,UAAU;QACVM,OAAOC,qBAAqB,CAACN,aAAaC;IAC5C;AACF;AAEA;;;CAGC,GACD,SAASM,4BACPC,SAAiB,EACjBC,cAAoCJ,MAAM,EAC1CR,WAAW,KAAK,EAChBa,OAA2C;IAE3C,MAAMZ,YAA6B,EAAE;IACrC,MAAMa,UAAUf,mBAAmBC,UAAUC;IAE7C,OAAO;QACL;;;;KAIC,GACDc,KAAK,CAACC;YACJ,IAAI,CAACf,UAAUK,MAAM,EAAE;gBACrBM,YAAYK,gBAAgB,CAACN,WAAWG,SAASD;YACnD;YAEA,IAAIZ,UAAUiB,OAAO,CAACF,cAAc,CAAC,GAAG;gBACtCf,UAAUkB,IAAI,CAACH;YACjB;QACF;QAEA;;;;KAIC,GACDI,QAAQ,CAACJ;YACP,MAAMX,IAAIJ,UAAUiB,OAAO,CAACF;YAC5B,IAAIX,KAAK,GAAG;gBACVJ,UAAUoB,MAAM,CAAChB,GAAG;gBAEpB,IAAI,CAACJ,UAAUK,MAAM,EAAE;oBACrBM,YAAYU,mBAAmB,CAACX,WAAWG,SAASD;gBACtD;YACF;QACF;IACF;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GACD,OAAO,SAASU,cACdZ,SAAiB,EACjBC,cAAoCJ,MAAM,EAC1CR,WAAoBW,cAAc,YAAYA,cAAc,QAAQ,EACpEE,OAA2C;IAE3C,IAAIW,QAAQ1B,gBAAgB2B,SAAS,CACnC,CAACrB,QACCA,MAAMsB,IAAI,KAAKf,aACfP,MAAMuB,MAAM,KAAKf,eACjBR,MAAMS,OAAO,KAAKA,WAClBT,MAAMJ,QAAQ,KAAKA;IAGvB,IAAIwB,UAAU,CAAC,GAAG;QAChB1B,gBAAgBqB,IAAI,CAAC;YACnBO,MAAMf;YACNgB,QAAQf;YACRC;YACAb;YACAc,SAASJ,4BACPC,WACAC,aACAZ,UACAa;QAEJ;QAEAW,QAAQ1B,gBAAgBQ,MAAM,GAAG;IACnC;IAEA,OAAOR,eAAe,CAAC0B,MAAM,CAACV,OAAO;AACvC"}
1
+ {"version":3,"sources":["../src/delegateEvent.ts"],"sourcesContent":["/** @internal */\nexport type DelegatedEventTarget = Window | Document | HTMLElement;\n\n/**\n * This is a \"shared\" event handler for the provided `eventType`. The event\n * listener will only be created once, but every single callback will be called\n * when the throttled event is triggered. This means that you will need to make\n * sure to remove the provided callback when it is no longer in use.\n *\n * @internal\n */\nexport interface DelegatedEventHandler {\n /**\n * Adds the provided callback to the throttled event listener.\n */\n add: (callback: EventListener) => void;\n\n /**\n * Attempts to remove the provided callback from the throttled event listener.\n */\n remove: (callback: EventListener) => void;\n}\n\n/** @internal */\nexport interface DelegableEvent {\n type: string;\n target: DelegatedEventTarget;\n throttle: boolean;\n handler: DelegatedEventHandler;\n options?: boolean | AddEventListenerOptions;\n}\n\nconst delegatedEvents: DelegableEvent[] = [];\n\n/**\n * Creates the delegated event handler that will run all the callbacks once an\n * event happens. The callbacks' invocation can also be throttled for event\n * types that trigger rapidly for additional performance.\n *\n * The `<K extends keyof WindowEventMap` is a nice thing I found while looking\n * through the `lib.d.ts` implementation of `addEventListener` that will allow\n * you to get the \"correct\" event type when using the `add` and `remove`\n * functions once you have created this event handler. Otherwise there'd be ts\n * errors trying to do `MouseEvent` or `KeyboardEvent` in your listeners.\n */\nfunction createEventHandler(\n throttle: boolean,\n callbacks: readonly EventListener[]\n): (event: WindowEventMap[keyof WindowEventMap]) => void {\n let running = false;\n const runCallbacks = (event: WindowEventMap[keyof WindowEventMap]) => () => {\n for (const callback of callbacks) {\n callback(event);\n }\n\n running = false;\n };\n\n return function eventHandler(event) {\n if (!throttle) {\n runCallbacks(event)();\n return;\n }\n\n if (running) {\n return;\n }\n\n running = true;\n globalThis.requestAnimationFrame(runCallbacks(event));\n };\n}\n\n/**\n * Creates a throttled event handler for the provided event type and event\n * target.\n */\nfunction createDelegatedEventHandler(\n eventType: string,\n eventTarget: DelegatedEventTarget = globalThis.window,\n throttle = false,\n options?: boolean | AddEventListenerOptions\n): DelegatedEventHandler {\n const callbacks: EventListener[] = [];\n const handler = createEventHandler(throttle, callbacks);\n\n return {\n /**\n * Attempts to add the provided callback to the list of callbacks for the\n * throttled event. If this is the first callback to be added, the throttled\n * event will also be started.\n */\n add: (callback: EventListener) => {\n if (callbacks.length === 0) {\n eventTarget.addEventListener(eventType, handler, options);\n }\n\n if (!callbacks.includes(callback)) {\n callbacks.push(callback);\n }\n },\n\n /**\n * Attempts to remove the provided callback from the list of callbacks for\n * the throttled event. If this is the last callback that was removed, the\n * throttled event will also be stopped.\n */\n remove: (callback: EventListener) => {\n const i = callbacks.indexOf(callback);\n if (i !== -1) {\n callbacks.splice(i, 1);\n\n if (callbacks.length === 0) {\n eventTarget.removeEventListener(eventType, handler, options);\n }\n }\n },\n };\n}\n\n/**\n * Creates a delegated event listener using custom events. Most of this code\n * comes from the MDN about resize listeners.\n *\n * This will return an object for adding or removing event handlers for the\n * provided `eventType` since only one base throttled event listener will be\n * created. Each callback that is added will be called with the event each time\n * the event is triggered. This does mean that you will manually need to remove\n * your callback like normal or else it can be called when no longer in use.\n * This also means that it doesn't \"hurt\" to call this function without\n * immediately calling the `add` function since the event won't start until\n * there is at least 1 callback.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/Events/resize#Examples\n * @param eventType - One of the event types that should be used to create a\n * delegated event for. This should be things like resize, click, scroll, etc.\n * @param eventTarget - The target that should have the delegated event handler\n * attached to. This is normally the window, but can be any element as needed.\n * @param throttle - Boolean if the event should be throttled or not. Normally\n * only event types like resize or scroll should be throttled for performance\n * boosts, but anything can be.\n * @returns The delegated event handler that allows you to add or remove\n * `EventListener`s to that event.\n * @internal\n */\nexport function delegateEvent(\n eventType: string,\n eventTarget: DelegatedEventTarget = globalThis.window,\n throttle: boolean = eventType === \"resize\" || eventType === \"scroll\",\n options?: boolean | AddEventListenerOptions\n): DelegatedEventHandler {\n let index = delegatedEvents.findIndex(\n (event) =>\n event.type === eventType &&\n event.target === eventTarget &&\n event.options === options &&\n event.throttle === throttle\n );\n\n if (index === -1) {\n delegatedEvents.push({\n type: eventType,\n target: eventTarget,\n options,\n throttle,\n handler: createDelegatedEventHandler(\n eventType,\n eventTarget,\n throttle,\n options\n ),\n });\n\n index = delegatedEvents.length - 1;\n }\n\n return delegatedEvents[index].handler;\n}\n"],"names":["delegatedEvents","createEventHandler","throttle","callbacks","running","runCallbacks","event","callback","eventHandler","globalThis","requestAnimationFrame","createDelegatedEventHandler","eventType","eventTarget","window","options","handler","add","length","addEventListener","includes","push","remove","i","indexOf","splice","removeEventListener","delegateEvent","index","findIndex","type","target"],"mappings":"AAAA,cAAc,GAgCd,MAAMA,kBAAoC,EAAE;AAE5C;;;;;;;;;;CAUC,GACD,SAASC,mBACPC,QAAiB,EACjBC,SAAmC;IAEnC,IAAIC,UAAU;IACd,MAAMC,eAAe,CAACC,QAAgD;YACpE,KAAK,MAAMC,YAAYJ,UAAW;gBAChCI,SAASD;YACX;YAEAF,UAAU;QACZ;IAEA,OAAO,SAASI,aAAaF,KAAK;QAChC,IAAI,CAACJ,UAAU;YACbG,aAAaC;YACb;QACF;QAEA,IAAIF,SAAS;YACX;QACF;QAEAA,UAAU;QACVK,WAAWC,qBAAqB,CAACL,aAAaC;IAChD;AACF;AAEA;;;CAGC,GACD,SAASK,4BACPC,SAAiB,EACjBC,cAAoCJ,WAAWK,MAAM,EACrDZ,WAAW,KAAK,EAChBa,OAA2C;IAE3C,MAAMZ,YAA6B,EAAE;IACrC,MAAMa,UAAUf,mBAAmBC,UAAUC;IAE7C,OAAO;QACL;;;;KAIC,GACDc,KAAK,CAACV;YACJ,IAAIJ,UAAUe,MAAM,KAAK,GAAG;gBAC1BL,YAAYM,gBAAgB,CAACP,WAAWI,SAASD;YACnD;YAEA,IAAI,CAACZ,UAAUiB,QAAQ,CAACb,WAAW;gBACjCJ,UAAUkB,IAAI,CAACd;YACjB;QACF;QAEA;;;;KAIC,GACDe,QAAQ,CAACf;YACP,MAAMgB,IAAIpB,UAAUqB,OAAO,CAACjB;YAC5B,IAAIgB,MAAM,CAAC,GAAG;gBACZpB,UAAUsB,MAAM,CAACF,GAAG;gBAEpB,IAAIpB,UAAUe,MAAM,KAAK,GAAG;oBAC1BL,YAAYa,mBAAmB,CAACd,WAAWI,SAASD;gBACtD;YACF;QACF;IACF;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GACD,OAAO,SAASY,cACdf,SAAiB,EACjBC,cAAoCJ,WAAWK,MAAM,EACrDZ,WAAoBU,cAAc,YAAYA,cAAc,QAAQ,EACpEG,OAA2C;IAE3C,IAAIa,QAAQ5B,gBAAgB6B,SAAS,CACnC,CAACvB,QACCA,MAAMwB,IAAI,KAAKlB,aACfN,MAAMyB,MAAM,KAAKlB,eACjBP,MAAMS,OAAO,KAAKA,WAClBT,MAAMJ,QAAQ,KAAKA;IAGvB,IAAI0B,UAAU,CAAC,GAAG;QAChB5B,gBAAgBqB,IAAI,CAAC;YACnBS,MAAMlB;YACNmB,QAAQlB;YACRE;YACAb;YACAc,SAASL,4BACPC,WACAC,aACAX,UACAa;QAEJ;QAEAa,QAAQ5B,gBAAgBkB,MAAM,GAAG;IACnC;IAEA,OAAOlB,eAAe,CAAC4B,MAAM,CAACZ,OAAO;AACvC"}
@@ -138,11 +138,11 @@ const noop = ()=>{
138
138
  const passive = isTouch ? {
139
139
  passive: false
140
140
  } : undefined;
141
- window.addEventListener(updateKey, updatePosition, passive);
142
- window.addEventListener(stopKey, stopDragging);
141
+ globalThis.addEventListener(updateKey, updatePosition, passive);
142
+ globalThis.addEventListener(stopKey, stopDragging);
143
143
  return ()=>{
144
- window.removeEventListener(updateKey, updatePosition);
145
- window.removeEventListener(stopKey, stopDragging);
144
+ globalThis.removeEventListener(updateKey, updatePosition);
145
+ globalThis.removeEventListener(stopKey, stopDragging);
146
146
  };
147
147
  }, [
148
148
  dragging,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/draggable/useDraggable.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type HTMLAttributes,\n type Ref,\n type RefCallback,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useScrollLock } from \"../scroll/useScrollLock.js\";\nimport {\n type NonNullRef,\n type UseStateInitializer,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useDir } from \"../typography/WritingDirectionProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useEnsuredState } from \"../useEnsuredState.js\";\nimport { useHtmlClassName } from \"../useHtmlClassName.js\";\nimport { getPercentage } from \"../utils/getPercentage.js\";\nimport { getRangeDefaultValue } from \"../utils/getRangeDefaultValue.js\";\nimport { getRangeSteps } from \"../utils/getRangeSteps.js\";\nimport { nearest } from \"../utils/nearest.js\";\nimport { withinRange } from \"../utils/withinRange.js\";\nimport {\n isMouseDragStartEvent,\n isTouchDragStartEvent,\n updateDragPosition,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport type DraggableTouchEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onTouchStart\" | \"onTouchMove\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableMouseEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onMouseDown\" | \"onMouseUp\" | \"onMouseMove\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableKeyboardEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onKeyDown\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableEventHandlers<E extends HTMLElement> =\n DraggableTouchEventHandlers<E> &\n DraggableMouseEventHandlers<E> &\n DraggableKeyboardEventHandlers<E>;\n\n/**\n * @since 6.0.0\n */\nexport interface ControllableDraggableStateOptions {\n value?: number;\n setValue?: UseStateSetter<number>;\n defaultValue?: UseStateInitializer<number>;\n dragging?: boolean;\n setDragging?: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface BaseDraggableOptions<E extends HTMLElement>\n extends DraggableEventHandlers<E>, ControllableDraggableStateOptions {\n /**\n * An optional ref to merge with the returned\n * {@link DraggableImplementation.draggableRef}.\n */\n ref?: Ref<E>;\n\n /**\n * The minimum number of pixels allowed for the draggable element. This must\n * be a number greater than or equal to 0.\n *\n * When {@link withinOffsetParent} is set to `true`, this is the minimum value\n * allowed instead of pixels.\n */\n min: number;\n\n /**\n * The maximum number of pixels allowed for the draggable element. This must\n * be a number greater than the {@link min} and usually a number less than the\n * viewport size.\n *\n * When {@link withinOffsetParent} is set to `true`, this is the maximum value\n * allowed instead of pixels.\n */\n max: number;\n\n /**\n * The amount to increment or decrement the value with arrow keys.\n *\n * @defaultValue `1`\n */\n step?: number;\n\n /**\n * This was added to support range sliders where there are two (or more)\n * draggable elements within the same container element and their values\n * cannot pass each other. Without these overrides, the range would keep\n * changing as the other values change, so the drag percentage would be\n * incorrect.\n *\n * @example Range Slider\n * ```ts\n * const min = 0;\n * const max = 100;\n * const minValue = 3;\n * const maxValue = 80;\n *\n * const minValueDraggable = useDraggable({\n * min,\n * max,\n * rangeMax: maxValue,\n * });\n * const maxValueDraggable = useDraggable({\n * min,\n * max,\n * rangeMin: minValue,\n * });\n * ```\n *\n * @defaultValue `min`\n */\n rangeMin?: number;\n\n /**\n * @see {@link rangeMin} for an explanation of this option.\n * @defaultValue `max`\n */\n rangeMax?: number;\n\n /**\n * Set this to `true` to enable dragging vertically instead of horizontally.\n *\n * @defaultValue `false`\n */\n vertical?: boolean;\n\n /**\n * The default drag behavior is to increase the value when:\n *\n * - dragging `\"right\"` and the writing direction is `\"ltr\"`\n * - dragging `\"left\"` and the writing direction is `\"rtl\"`\n * - dragging `\"upwards\"`\n *\n * When this is set to `true`, the value when increase when:\n *\n * - dragging `\"left\"` and the writing direction is `\"ltr\"`\n * - dragging `\"right\"` and the writing direction is `\"rtl\"`\n * - dragging `\"downwards\"`\n *\n * @defaultValue `false`\n */\n reversed?: boolean;\n\n /**\n * Set this to `true` to disable all drag behavior. This will still call any\n * of the provided {@link DraggableEventHandlers}.\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n\n /**\n * Set this to `true` if the dragging calculations should be to the\n * `draggableRef.current.offsetParent` instead of the entire window. The main\n * use case for this is sliders.\n *\n * @defaultValue `false`\n */\n withinOffsetParent?: boolean;\n\n /**\n * Set this to `true` to prevent the `document.documentElement` from gaining\n * the `.rmd-dragging` class names while dragging.\n *\n * This should normally remain as `false` to improve performance and prevent\n * other mouse events from firing while dragging.\n *\n * @defaultValue `false`\n */\n disableDraggingClassName?: boolean;\n\n /**\n * Set this to `true` to prevent the vertical or horizontal cursor from\n * appearing while dragging.\n *\n * @defaultValue `false`\n */\n disableDraggingCursorClassName?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface UncontrolledDraggableOptions {\n value?: never;\n setValue?: never;\n dragging?: never;\n setDragging?: never;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ControlledValueDraggableOptions {\n value: number;\n setValue: UseStateSetter<number>;\n defaultValue?: never;\n dragging?: never;\n setDragging?: never;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ControlledDraggingDraggableOptions {\n value?: never;\n setValue?: never;\n defaultValue?: never;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface FullyControlledDraggableOptions {\n value: number;\n setValue: UseStateSetter<number>;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type DraggableStateOptions =\n | UncontrolledDraggableOptions\n | ControlledValueDraggableOptions\n | ControlledDraggingDraggableOptions\n | FullyControlledDraggableOptions;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableOptions<E extends HTMLElement = HTMLElement> =\n BaseDraggableOptions<E> & DraggableStateOptions;\n\n/**\n * @since 6.0.0\n */\nexport interface DraggableImplementation<\n E extends HTMLElement = HTMLElement,\n> extends Required<DraggableEventHandlers<E>> {\n mouseEventHandlers: Required<DraggableMouseEventHandlers<E>>;\n touchEventHandlers: Required<DraggableTouchEventHandlers<E>>;\n keyboardEventHandlers: Required<DraggableKeyboardEventHandlers<E>>;\n\n /**\n * Set the {@link value} to {@link DraggableOptions.min}.\n */\n minimum: () => void;\n\n /**\n * Set the {@link value} to {@link DraggableOptions.max}.\n */\n maximum: () => void;\n\n /**\n * Increment the {@link value} by {@link DraggableOptions.step}.\n */\n increment: () => void;\n\n /**\n * Decrement the {@link value} by {@link DraggableOptions.step}.\n */\n decrement: () => void;\n\n /**\n * The current percentage the `value` is within the range.\n *\n * ```ts\n * const percentage =\n * dragging && withinOffsetParent\n * ? : dragPercentage\n * : getPercentage({ min, max, value });\n * ```\n */\n percentage: number;\n\n /**\n * A ref that **Must** be passed to the element that should be draggable.\n */\n draggableRef: RefCallback<E>;\n\n /**\n * This value will only update while dragging with a mouse or touch and should\n * be used for the positioning styles while dragging.\n *\n * Note: The {@link percentage} will use this value while dragging.\n */\n dragPercentage: number;\n\n /**\n * Flag to determine if the user has dragged at least once. Used internally\n * for manually persisting the value into local storage once the user has\n * stopped dragging.\n */\n draggedOnce: NonNullRef<boolean>;\n\n value: number;\n setValue: UseStateSetter<number>;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * This is most likely an internal only hook that provides the functionality for\n * dragging an element through mouse, touch, and keyboard events. The main use\n * cases so far for this hook are:\n * - window splitters\n * - sliders\n *\n * NOTE: This requires `touch-action: none` to be applied to the draggable\n * element to help prevent page scrolling on mobile devices.\n *\n * @see {@link https://react-md.dev/components/use-draggable | useDraggable Demos}\n * @since 6.0.0\n */\nexport function useDraggable<E extends HTMLElement>(\n options: DraggableOptions<E>\n): DraggableImplementation<E> {\n const {\n ref: propRef,\n min,\n max,\n rangeMin = min,\n rangeMax = max,\n step = 1,\n reversed = false,\n vertical = false,\n onKeyDown = noop,\n onMouseUp = noop,\n onMouseDown = noop,\n onMouseMove = noop,\n onTouchStart = noop,\n onTouchMove = noop,\n dragging: propDragging,\n setDragging: propSetDragging,\n value: propValue,\n setValue: propSetValue,\n defaultValue,\n withinOffsetParent = false,\n disabled = false,\n disableDraggingClassName = false,\n disableDraggingCursorClassName = disableDraggingClassName,\n } = options;\n\n const [nodeRef, ref] = useEnsuredRef(propRef);\n const isTouch = useUserInteractionMode() === \"touch\";\n const draggingRef = useRef(false);\n const [dragPercentage, setDragPercentage] = useState(min);\n const [value, setValue] = useEnsuredState({\n value: propValue,\n setValue: propSetValue,\n defaultValue: getRangeDefaultValue({\n min,\n max,\n step: 1,\n defaultValue,\n }),\n });\n const [dragging, setDragging] = useEnsuredState({\n value: propDragging,\n setValue: propSetDragging,\n defaultValue: false,\n });\n\n const isRTL = useDir().dir === \"rtl\";\n const percentage =\n dragging && withinOffsetParent\n ? dragPercentage\n : getPercentage({ min, max, value });\n const maximum = useCallback(() => {\n setValue(max);\n }, [max, setValue]);\n const minimum = useCallback(() => {\n setValue(min);\n }, [min, setValue]);\n const increment = useCallback(() => {\n setValue((prevValue) => withinRange({ min, max, value: prevValue + step }));\n }, [max, min, setValue, step]);\n const decrement = useCallback(() => {\n setValue((prevValue) => withinRange({ min, max, value: prevValue - step }));\n }, [max, min, setValue, step]);\n\n const draggingClassName = dragging && !disableDraggingClassName;\n useHtmlClassName(cnb(draggingClassName && \"rmd-dragging\"));\n useHtmlClassName(\n cnb(\n !disableDraggingCursorClassName &&\n draggingClassName &&\n `rmd-dragging--${vertical ? \"v\" : \"h\"}`\n )\n );\n\n const draggedOnce = useRef(false);\n useEffect(() => {\n if (!dragging) {\n return;\n }\n\n draggedOnce.current = true;\n const updatePosition = (event: MouseEvent | TouchEvent): void => {\n if (!event.cancelable) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n updateDragPosition({\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n isDragStart: false,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n };\n\n const stopDragging = (event: MouseEvent | TouchEvent): void => {\n updatePosition(event);\n setDragging(false);\n draggingRef.current = false;\n // blur the element so that it no longer maintains the `:focus-visible`\n // styles if they were applied. pressing tab would re-focus this element\n // so the tab order is preserved\n nodeRef.current?.blur();\n };\n\n const updateKey = isTouch ? \"touchmove\" : \"mousemove\";\n const stopKey = isTouch ? \"touchend\" : \"mouseup\";\n const passive = isTouch ? { passive: false } : undefined;\n\n window.addEventListener(updateKey, updatePosition, passive);\n window.addEventListener(stopKey, stopDragging);\n return () => {\n window.removeEventListener(updateKey, updatePosition);\n window.removeEventListener(stopKey, stopDragging);\n };\n }, [\n dragging,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]);\n\n const prevRange = useRef({ min, max, step });\n useEffect(() => {\n if (\n prevRange.current.min === min &&\n prevRange.current.max === max &&\n prevRange.current.step === step\n ) {\n return;\n }\n\n prevRange.current = { min, max, step };\n setValue((prevValue) =>\n nearest({\n min,\n max,\n steps: getRangeSteps({ min, max, step }),\n value: prevValue,\n })\n );\n }, [max, min, setValue, step]);\n\n const mouseEventHandlers: Required<DraggableMouseEventHandlers<E>> = {\n onMouseDown: useCallback(\n (event) => {\n onMouseDown(event);\n if (disabled || isTouch || !isMouseDragStartEvent(event)) {\n return;\n }\n\n // don't allow text to be selected\n event.preventDefault();\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n\n // don't set dragging immediately so that click events can still happen\n draggingRef.current = true;\n },\n [\n disabled,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n onMouseDown,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onMouseMove: useCallback(\n (event) => {\n onMouseMove(event);\n if (disabled || isTouch || !draggingRef.current || dragging) {\n return;\n }\n\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n setDragging(true);\n },\n [\n disabled,\n dragging,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n onMouseMove,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onMouseUp: useCallback(\n (event) => {\n onMouseUp(event);\n if (disabled || isTouch) {\n return;\n }\n\n draggingRef.current = false;\n },\n [disabled, isTouch, onMouseUp]\n ),\n };\n const keyboardEventHandlers: Required<DraggableKeyboardEventHandlers<E>> = {\n onKeyDown: useCallback(\n (event) => {\n onKeyDown(event);\n if (disabled) {\n return;\n }\n\n const decrementKey = vertical ? \"ArrowDown\" : \"ArrowLeft\";\n const incrementKey = vertical ? \"ArrowUp\" : \"ArrowRight\";\n\n switch (event.key) {\n case decrementKey:\n event.preventDefault();\n decrement();\n break;\n case incrementKey:\n event.preventDefault();\n increment();\n break;\n case \"Home\":\n event.preventDefault();\n minimum();\n break;\n case \"End\":\n event.preventDefault();\n maximum();\n break;\n }\n },\n [decrement, disabled, increment, maximum, minimum, onKeyDown, vertical]\n ),\n };\n\n // touch devices are a bit weird and cause issues since the \"start\" event is\n // also used for scrolling. If the user quickly grabs the draggable element\n // and drags vertically, most of the time it will try to scroll instead of\n // dragging the element. The workaround is to being the drag events\n // immediately on touchstart and disable scroll behavior for the page.\n //\n // There are also some issues with calling `event.preventDefault()` within\n // touch events even while `{ passive: false } is manually set, so need to\n // also attach a touchmove event.\n useScrollLock(isTouch && dragging);\n const touchEventHandlers: Required<DraggableTouchEventHandlers<E>> = {\n onTouchStart: useCallback(\n (event) => {\n onTouchStart(event);\n if (disabled || !isTouchDragStartEvent(event)) {\n return;\n }\n\n draggingRef.current = true;\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n },\n [\n disabled,\n isRTL,\n max,\n min,\n nodeRef,\n onTouchStart,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onTouchMove: useCallback(\n (event) => {\n onTouchMove(event);\n if (disabled || !draggingRef.current || !event.cancelable) {\n return;\n }\n\n // prevent the document's touchmove event from also firing\n event.stopPropagation();\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n },\n [\n disabled,\n isRTL,\n max,\n min,\n nodeRef,\n onTouchMove,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n };\n\n return {\n ...touchEventHandlers,\n ...mouseEventHandlers,\n ...keyboardEventHandlers,\n value,\n setValue,\n dragging,\n setDragging,\n maximum,\n minimum,\n increment,\n decrement,\n draggedOnce,\n draggableRef: ref,\n percentage,\n dragPercentage,\n touchEventHandlers,\n mouseEventHandlers,\n keyboardEventHandlers,\n };\n}\n"],"names":["cnb","useCallback","useEffect","useRef","useState","useUserInteractionMode","useScrollLock","useDir","useEnsuredRef","useEnsuredState","useHtmlClassName","getPercentage","getRangeDefaultValue","getRangeSteps","nearest","withinRange","isMouseDragStartEvent","isTouchDragStartEvent","updateDragPosition","noop","useDraggable","options","ref","propRef","min","max","rangeMin","rangeMax","step","reversed","vertical","onKeyDown","onMouseUp","onMouseDown","onMouseMove","onTouchStart","onTouchMove","dragging","propDragging","setDragging","propSetDragging","value","propValue","setValue","propSetValue","defaultValue","withinOffsetParent","disabled","disableDraggingClassName","disableDraggingCursorClassName","nodeRef","isTouch","draggingRef","dragPercentage","setDragPercentage","isRTL","dir","percentage","maximum","minimum","increment","prevValue","decrement","draggingClassName","draggedOnce","current","updatePosition","event","cancelable","preventDefault","stopPropagation","isDragStart","stopDragging","blur","updateKey","stopKey","passive","undefined","window","addEventListener","removeEventListener","prevRange","steps","mouseEventHandlers","keyboardEventHandlers","decrementKey","incrementKey","key","touchEventHandlers","draggableRef"],"mappings":"AAAA;AAEA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAIEC,WAAW,EACXC,SAAS,EACTC,MAAM,EACNC,QAAQ,QACH,QAAQ;AAEf,SAASC,sBAAsB,QAAQ,gDAAgD;AACvF,SAASC,aAAa,QAAQ,6BAA6B;AAM3D,SAASC,MAAM,QAAQ,4CAA4C;AACnE,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAASC,eAAe,QAAQ,wBAAwB;AACxD,SAASC,gBAAgB,QAAQ,yBAAyB;AAC1D,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,oBAAoB,QAAQ,mCAAmC;AACxE,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SACEC,qBAAqB,EACrBC,qBAAqB,EACrBC,kBAAkB,QACb,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AAgTA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,aACdC,OAA4B;IAE5B,MAAM,EACJC,KAAKC,OAAO,EACZC,GAAG,EACHC,GAAG,EACHC,WAAWF,GAAG,EACdG,WAAWF,GAAG,EACdG,OAAO,CAAC,EACRC,WAAW,KAAK,EAChBC,WAAW,KAAK,EAChBC,YAAYZ,IAAI,EAChBa,YAAYb,IAAI,EAChBc,cAAcd,IAAI,EAClBe,cAAcf,IAAI,EAClBgB,eAAehB,IAAI,EACnBiB,cAAcjB,IAAI,EAClBkB,UAAUC,YAAY,EACtBC,aAAaC,eAAe,EAC5BC,OAAOC,SAAS,EAChBC,UAAUC,YAAY,EACtBC,YAAY,EACZC,qBAAqB,KAAK,EAC1BC,WAAW,KAAK,EAChBC,2BAA2B,KAAK,EAChCC,iCAAiCD,wBAAwB,EAC1D,GAAG3B;IAEJ,MAAM,CAAC6B,SAAS5B,IAAI,GAAGd,cAAce;IACrC,MAAM4B,UAAU9C,6BAA6B;IAC7C,MAAM+C,cAAcjD,OAAO;IAC3B,MAAM,CAACkD,gBAAgBC,kBAAkB,GAAGlD,SAASoB;IACrD,MAAM,CAACiB,OAAOE,SAAS,GAAGlC,gBAAgB;QACxCgC,OAAOC;QACPC,UAAUC;QACVC,cAAcjC,qBAAqB;YACjCY;YACAC;YACAG,MAAM;YACNiB;QACF;IACF;IACA,MAAM,CAACR,UAAUE,YAAY,GAAG9B,gBAAgB;QAC9CgC,OAAOH;QACPK,UAAUH;QACVK,cAAc;IAChB;IAEA,MAAMU,QAAQhD,SAASiD,GAAG,KAAK;IAC/B,MAAMC,aACJpB,YAAYS,qBACRO,iBACA1C,cAAc;QAAEa;QAAKC;QAAKgB;IAAM;IACtC,MAAMiB,UAAUzD,YAAY;QAC1B0C,SAASlB;IACX,GAAG;QAACA;QAAKkB;KAAS;IAClB,MAAMgB,UAAU1D,YAAY;QAC1B0C,SAASnB;IACX,GAAG;QAACA;QAAKmB;KAAS;IAClB,MAAMiB,YAAY3D,YAAY;QAC5B0C,SAAS,CAACkB,YAAc9C,YAAY;gBAAES;gBAAKC;gBAAKgB,OAAOoB,YAAYjC;YAAK;IAC1E,GAAG;QAACH;QAAKD;QAAKmB;QAAUf;KAAK;IAC7B,MAAMkC,YAAY7D,YAAY;QAC5B0C,SAAS,CAACkB,YAAc9C,YAAY;gBAAES;gBAAKC;gBAAKgB,OAAOoB,YAAYjC;YAAK;IAC1E,GAAG;QAACH;QAAKD;QAAKmB;QAAUf;KAAK;IAE7B,MAAMmC,oBAAoB1B,YAAY,CAACW;IACvCtC,iBAAiBV,IAAI+D,qBAAqB;IAC1CrD,iBACEV,IACE,CAACiD,kCACCc,qBACA,CAAC,cAAc,EAAEjC,WAAW,MAAM,KAAK;IAI7C,MAAMkC,cAAc7D,OAAO;IAC3BD,UAAU;QACR,IAAI,CAACmC,UAAU;YACb;QACF;QAEA2B,YAAYC,OAAO,GAAG;QACtB,MAAMC,iBAAiB,CAACC;YACtB,IAAI,CAACA,MAAMC,UAAU,EAAE;gBACrB;YACF;YAEAD,MAAME,cAAc;YACpBF,MAAMG,eAAe;YAErBpD,mBAAmB;gBACjBiD;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACAgB,aAAa;gBACb1C;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;QACF;QAEA,MAAM0B,eAAe,CAACL;YACpBD,eAAeC;YACf5B,YAAY;YACZa,YAAYa,OAAO,GAAG;YACtB,uEAAuE;YACvE,wEAAwE;YACxE,gCAAgC;YAChCf,QAAQe,OAAO,EAAEQ;QACnB;QAEA,MAAMC,YAAYvB,UAAU,cAAc;QAC1C,MAAMwB,UAAUxB,UAAU,aAAa;QACvC,MAAMyB,UAAUzB,UAAU;YAAEyB,SAAS;QAAM,IAAIC;QAE/CC,OAAOC,gBAAgB,CAACL,WAAWR,gBAAgBU;QACnDE,OAAOC,gBAAgB,CAACJ,SAASH;QACjC,OAAO;YACLM,OAAOE,mBAAmB,CAACN,WAAWR;YACtCY,OAAOE,mBAAmB,CAACL,SAASH;QACtC;IACF,GAAG;QACDnC;QACAkB;QACAJ;QACA1B;QACAD;QACA0B;QACAvB;QACAD;QACAG;QACAU;QACAI;QACAf;QACAE;QACAgB;KACD;IAED,MAAMmC,YAAY9E,OAAO;QAAEqB;QAAKC;QAAKG;IAAK;IAC1C1B,UAAU;QACR,IACE+E,UAAUhB,OAAO,CAACzC,GAAG,KAAKA,OAC1ByD,UAAUhB,OAAO,CAACxC,GAAG,KAAKA,OAC1BwD,UAAUhB,OAAO,CAACrC,IAAI,KAAKA,MAC3B;YACA;QACF;QAEAqD,UAAUhB,OAAO,GAAG;YAAEzC;YAAKC;YAAKG;QAAK;QACrCe,SAAS,CAACkB,YACR/C,QAAQ;gBACNU;gBACAC;gBACAyD,OAAOrE,cAAc;oBAAEW;oBAAKC;oBAAKG;gBAAK;gBACtCa,OAAOoB;YACT;IAEJ,GAAG;QAACpC;QAAKD;QAAKmB;QAAUf;KAAK;IAE7B,MAAMuD,qBAA+D;QACnElD,aAAahC,YACX,CAACkE;YACClC,YAAYkC;YACZ,IAAIpB,YAAYI,WAAW,CAACnC,sBAAsBmD,QAAQ;gBACxD;YACF;YAEA,kCAAkC;YAClCA,MAAME,cAAc;YACpBnD,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;YAEA,uEAAuE;YACvEM,YAAYa,OAAO,GAAG;QACxB,GACA;YACElB;YACAQ;YACAJ;YACA1B;YACAD;YACA0B;YACAjB;YACAN;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;QAEHZ,aAAajC,YACX,CAACkE;YACCjC,YAAYiC;YACZ,IAAIpB,YAAYI,WAAW,CAACC,YAAYa,OAAO,IAAI5B,UAAU;gBAC3D;YACF;YAEAnB,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;YACAP,YAAY;QACd,GACA;YACEQ;YACAV;YACAkB;YACAJ;YACA1B;YACAD;YACA0B;YACAhB;YACAP;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;QAEHd,WAAW/B,YACT,CAACkE;YACCnC,UAAUmC;YACV,IAAIpB,YAAYI,SAAS;gBACvB;YACF;YAEAC,YAAYa,OAAO,GAAG;QACxB,GACA;YAAClB;YAAUI;YAASnB;SAAU;IAElC;IACA,MAAMoD,wBAAqE;QACzErD,WAAW9B,YACT,CAACkE;YACCpC,UAAUoC;YACV,IAAIpB,UAAU;gBACZ;YACF;YAEA,MAAMsC,eAAevD,WAAW,cAAc;YAC9C,MAAMwD,eAAexD,WAAW,YAAY;YAE5C,OAAQqC,MAAMoB,GAAG;gBACf,KAAKF;oBACHlB,MAAME,cAAc;oBACpBP;oBACA;gBACF,KAAKwB;oBACHnB,MAAME,cAAc;oBACpBT;oBACA;gBACF,KAAK;oBACHO,MAAME,cAAc;oBACpBV;oBACA;gBACF,KAAK;oBACHQ,MAAME,cAAc;oBACpBX;oBACA;YACJ;QACF,GACA;YAACI;YAAWf;YAAUa;YAAWF;YAASC;YAAS5B;YAAWD;SAAS;IAE3E;IAEA,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,mEAAmE;IACnE,sEAAsE;IACtE,EAAE;IACF,0EAA0E;IAC1E,0EAA0E;IAC1E,iCAAiC;IACjCxB,cAAc6C,WAAWd;IACzB,MAAMmD,qBAA+D;QACnErD,cAAclC,YACZ,CAACkE;YACChC,aAAagC;YACb,IAAIpB,YAAY,CAAC9B,sBAAsBkD,QAAQ;gBAC7C;YACF;YAEAf,YAAYa,OAAO,GAAG;YACtB/C,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;QACF,GACA;YACEC;YACAQ;YACA9B;YACAD;YACA0B;YACAf;YACAR;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;QAEHV,aAAanC,YACX,CAACkE;YACC/B,YAAY+B;YACZ,IAAIpB,YAAY,CAACK,YAAYa,OAAO,IAAI,CAACE,MAAMC,UAAU,EAAE;gBACzD;YACF;YAEA,0DAA0D;YAC1DD,MAAMG,eAAe;YACrBpD,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;QACF,GACA;YACEC;YACAQ;YACA9B;YACAD;YACA0B;YACAd;YACAT;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;IAEL;IAEA,OAAO;QACL,GAAG0C,kBAAkB;QACrB,GAAGL,kBAAkB;QACrB,GAAGC,qBAAqB;QACxB3C;QACAE;QACAN;QACAE;QACAmB;QACAC;QACAC;QACAE;QACAE;QACAyB,cAAcnE;QACdmC;QACAJ;QACAmC;QACAL;QACAC;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/draggable/useDraggable.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type HTMLAttributes,\n type Ref,\n type RefCallback,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useScrollLock } from \"../scroll/useScrollLock.js\";\nimport {\n type NonNullRef,\n type UseStateInitializer,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useDir } from \"../typography/WritingDirectionProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useEnsuredState } from \"../useEnsuredState.js\";\nimport { useHtmlClassName } from \"../useHtmlClassName.js\";\nimport { getPercentage } from \"../utils/getPercentage.js\";\nimport { getRangeDefaultValue } from \"../utils/getRangeDefaultValue.js\";\nimport { getRangeSteps } from \"../utils/getRangeSteps.js\";\nimport { nearest } from \"../utils/nearest.js\";\nimport { withinRange } from \"../utils/withinRange.js\";\nimport {\n isMouseDragStartEvent,\n isTouchDragStartEvent,\n updateDragPosition,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport type DraggableTouchEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onTouchStart\" | \"onTouchMove\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableMouseEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onMouseDown\" | \"onMouseUp\" | \"onMouseMove\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableKeyboardEventHandlers<E extends HTMLElement> = Pick<\n HTMLAttributes<E>,\n \"onKeyDown\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableEventHandlers<E extends HTMLElement> =\n DraggableTouchEventHandlers<E> &\n DraggableMouseEventHandlers<E> &\n DraggableKeyboardEventHandlers<E>;\n\n/**\n * @since 6.0.0\n */\nexport interface ControllableDraggableStateOptions {\n value?: number;\n setValue?: UseStateSetter<number>;\n defaultValue?: UseStateInitializer<number>;\n dragging?: boolean;\n setDragging?: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface BaseDraggableOptions<E extends HTMLElement>\n extends DraggableEventHandlers<E>, ControllableDraggableStateOptions {\n /**\n * An optional ref to merge with the returned\n * {@link DraggableImplementation.draggableRef}.\n */\n ref?: Ref<E>;\n\n /**\n * The minimum number of pixels allowed for the draggable element. This must\n * be a number greater than or equal to 0.\n *\n * When {@link withinOffsetParent} is set to `true`, this is the minimum value\n * allowed instead of pixels.\n */\n min: number;\n\n /**\n * The maximum number of pixels allowed for the draggable element. This must\n * be a number greater than the {@link min} and usually a number less than the\n * viewport size.\n *\n * When {@link withinOffsetParent} is set to `true`, this is the maximum value\n * allowed instead of pixels.\n */\n max: number;\n\n /**\n * The amount to increment or decrement the value with arrow keys.\n *\n * @defaultValue `1`\n */\n step?: number;\n\n /**\n * This was added to support range sliders where there are two (or more)\n * draggable elements within the same container element and their values\n * cannot pass each other. Without these overrides, the range would keep\n * changing as the other values change, so the drag percentage would be\n * incorrect.\n *\n * @example Range Slider\n * ```ts\n * const min = 0;\n * const max = 100;\n * const minValue = 3;\n * const maxValue = 80;\n *\n * const minValueDraggable = useDraggable({\n * min,\n * max,\n * rangeMax: maxValue,\n * });\n * const maxValueDraggable = useDraggable({\n * min,\n * max,\n * rangeMin: minValue,\n * });\n * ```\n *\n * @defaultValue `min`\n */\n rangeMin?: number;\n\n /**\n * @see {@link rangeMin} for an explanation of this option.\n * @defaultValue `max`\n */\n rangeMax?: number;\n\n /**\n * Set this to `true` to enable dragging vertically instead of horizontally.\n *\n * @defaultValue `false`\n */\n vertical?: boolean;\n\n /**\n * The default drag behavior is to increase the value when:\n *\n * - dragging `\"right\"` and the writing direction is `\"ltr\"`\n * - dragging `\"left\"` and the writing direction is `\"rtl\"`\n * - dragging `\"upwards\"`\n *\n * When this is set to `true`, the value when increase when:\n *\n * - dragging `\"left\"` and the writing direction is `\"ltr\"`\n * - dragging `\"right\"` and the writing direction is `\"rtl\"`\n * - dragging `\"downwards\"`\n *\n * @defaultValue `false`\n */\n reversed?: boolean;\n\n /**\n * Set this to `true` to disable all drag behavior. This will still call any\n * of the provided {@link DraggableEventHandlers}.\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n\n /**\n * Set this to `true` if the dragging calculations should be to the\n * `draggableRef.current.offsetParent` instead of the entire window. The main\n * use case for this is sliders.\n *\n * @defaultValue `false`\n */\n withinOffsetParent?: boolean;\n\n /**\n * Set this to `true` to prevent the `document.documentElement` from gaining\n * the `.rmd-dragging` class names while dragging.\n *\n * This should normally remain as `false` to improve performance and prevent\n * other mouse events from firing while dragging.\n *\n * @defaultValue `false`\n */\n disableDraggingClassName?: boolean;\n\n /**\n * Set this to `true` to prevent the vertical or horizontal cursor from\n * appearing while dragging.\n *\n * @defaultValue `false`\n */\n disableDraggingCursorClassName?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface UncontrolledDraggableOptions {\n value?: never;\n setValue?: never;\n dragging?: never;\n setDragging?: never;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ControlledValueDraggableOptions {\n value: number;\n setValue: UseStateSetter<number>;\n defaultValue?: never;\n dragging?: never;\n setDragging?: never;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ControlledDraggingDraggableOptions {\n value?: never;\n setValue?: never;\n defaultValue?: never;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface FullyControlledDraggableOptions {\n value: number;\n setValue: UseStateSetter<number>;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type DraggableStateOptions =\n | UncontrolledDraggableOptions\n | ControlledValueDraggableOptions\n | ControlledDraggingDraggableOptions\n | FullyControlledDraggableOptions;\n\n/**\n * @since 6.0.0\n */\nexport type DraggableOptions<E extends HTMLElement = HTMLElement> =\n BaseDraggableOptions<E> & DraggableStateOptions;\n\n/**\n * @since 6.0.0\n */\nexport interface DraggableImplementation<\n E extends HTMLElement = HTMLElement,\n> extends Required<DraggableEventHandlers<E>> {\n mouseEventHandlers: Required<DraggableMouseEventHandlers<E>>;\n touchEventHandlers: Required<DraggableTouchEventHandlers<E>>;\n keyboardEventHandlers: Required<DraggableKeyboardEventHandlers<E>>;\n\n /**\n * Set the {@link value} to {@link DraggableOptions.min}.\n */\n minimum: () => void;\n\n /**\n * Set the {@link value} to {@link DraggableOptions.max}.\n */\n maximum: () => void;\n\n /**\n * Increment the {@link value} by {@link DraggableOptions.step}.\n */\n increment: () => void;\n\n /**\n * Decrement the {@link value} by {@link DraggableOptions.step}.\n */\n decrement: () => void;\n\n /**\n * The current percentage the `value` is within the range.\n *\n * ```ts\n * const percentage =\n * dragging && withinOffsetParent\n * ? : dragPercentage\n * : getPercentage({ min, max, value });\n * ```\n */\n percentage: number;\n\n /**\n * A ref that **Must** be passed to the element that should be draggable.\n */\n draggableRef: RefCallback<E>;\n\n /**\n * This value will only update while dragging with a mouse or touch and should\n * be used for the positioning styles while dragging.\n *\n * Note: The {@link percentage} will use this value while dragging.\n */\n dragPercentage: number;\n\n /**\n * Flag to determine if the user has dragged at least once. Used internally\n * for manually persisting the value into local storage once the user has\n * stopped dragging.\n */\n draggedOnce: NonNullRef<boolean>;\n\n value: number;\n setValue: UseStateSetter<number>;\n dragging: boolean;\n setDragging: UseStateSetter<boolean>;\n}\n\n/**\n * This is most likely an internal only hook that provides the functionality for\n * dragging an element through mouse, touch, and keyboard events. The main use\n * cases so far for this hook are:\n * - window splitters\n * - sliders\n *\n * NOTE: This requires `touch-action: none` to be applied to the draggable\n * element to help prevent page scrolling on mobile devices.\n *\n * @see {@link https://react-md.dev/components/use-draggable | useDraggable Demos}\n * @since 6.0.0\n */\nexport function useDraggable<E extends HTMLElement>(\n options: DraggableOptions<E>\n): DraggableImplementation<E> {\n const {\n ref: propRef,\n min,\n max,\n rangeMin = min,\n rangeMax = max,\n step = 1,\n reversed = false,\n vertical = false,\n onKeyDown = noop,\n onMouseUp = noop,\n onMouseDown = noop,\n onMouseMove = noop,\n onTouchStart = noop,\n onTouchMove = noop,\n dragging: propDragging,\n setDragging: propSetDragging,\n value: propValue,\n setValue: propSetValue,\n defaultValue,\n withinOffsetParent = false,\n disabled = false,\n disableDraggingClassName = false,\n disableDraggingCursorClassName = disableDraggingClassName,\n } = options;\n\n const [nodeRef, ref] = useEnsuredRef(propRef);\n const isTouch = useUserInteractionMode() === \"touch\";\n const draggingRef = useRef(false);\n const [dragPercentage, setDragPercentage] = useState(min);\n const [value, setValue] = useEnsuredState({\n value: propValue,\n setValue: propSetValue,\n defaultValue: getRangeDefaultValue({\n min,\n max,\n step: 1,\n defaultValue,\n }),\n });\n const [dragging, setDragging] = useEnsuredState({\n value: propDragging,\n setValue: propSetDragging,\n defaultValue: false,\n });\n\n const isRTL = useDir().dir === \"rtl\";\n const percentage =\n dragging && withinOffsetParent\n ? dragPercentage\n : getPercentage({ min, max, value });\n const maximum = useCallback(() => {\n setValue(max);\n }, [max, setValue]);\n const minimum = useCallback(() => {\n setValue(min);\n }, [min, setValue]);\n const increment = useCallback(() => {\n setValue((prevValue) => withinRange({ min, max, value: prevValue + step }));\n }, [max, min, setValue, step]);\n const decrement = useCallback(() => {\n setValue((prevValue) => withinRange({ min, max, value: prevValue - step }));\n }, [max, min, setValue, step]);\n\n const draggingClassName = dragging && !disableDraggingClassName;\n useHtmlClassName(cnb(draggingClassName && \"rmd-dragging\"));\n useHtmlClassName(\n cnb(\n !disableDraggingCursorClassName &&\n draggingClassName &&\n `rmd-dragging--${vertical ? \"v\" : \"h\"}`\n )\n );\n\n const draggedOnce = useRef(false);\n useEffect(() => {\n if (!dragging) {\n return;\n }\n\n draggedOnce.current = true;\n const updatePosition = (event: MouseEvent | TouchEvent): void => {\n if (!event.cancelable) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n updateDragPosition({\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n isDragStart: false,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n };\n\n const stopDragging = (event: MouseEvent | TouchEvent): void => {\n updatePosition(event);\n setDragging(false);\n draggingRef.current = false;\n // blur the element so that it no longer maintains the `:focus-visible`\n // styles if they were applied. pressing tab would re-focus this element\n // so the tab order is preserved\n nodeRef.current?.blur();\n };\n\n const updateKey = isTouch ? \"touchmove\" : \"mousemove\";\n const stopKey = isTouch ? \"touchend\" : \"mouseup\";\n const passive = isTouch ? { passive: false } : undefined;\n\n globalThis.addEventListener(updateKey, updatePosition, passive);\n globalThis.addEventListener(stopKey, stopDragging);\n return () => {\n globalThis.removeEventListener(updateKey, updatePosition);\n globalThis.removeEventListener(stopKey, stopDragging);\n };\n }, [\n dragging,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]);\n\n const prevRange = useRef({ min, max, step });\n useEffect(() => {\n if (\n prevRange.current.min === min &&\n prevRange.current.max === max &&\n prevRange.current.step === step\n ) {\n return;\n }\n\n prevRange.current = { min, max, step };\n setValue((prevValue) =>\n nearest({\n min,\n max,\n steps: getRangeSteps({ min, max, step }),\n value: prevValue,\n })\n );\n }, [max, min, setValue, step]);\n\n const mouseEventHandlers: Required<DraggableMouseEventHandlers<E>> = {\n onMouseDown: useCallback(\n (event) => {\n onMouseDown(event);\n if (disabled || isTouch || !isMouseDragStartEvent(event)) {\n return;\n }\n\n // don't allow text to be selected\n event.preventDefault();\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n\n // don't set dragging immediately so that click events can still happen\n draggingRef.current = true;\n },\n [\n disabled,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n onMouseDown,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onMouseMove: useCallback(\n (event) => {\n onMouseMove(event);\n if (disabled || isTouch || !draggingRef.current || dragging) {\n return;\n }\n\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n setDragging(true);\n },\n [\n disabled,\n dragging,\n isRTL,\n isTouch,\n max,\n min,\n nodeRef,\n onMouseMove,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onMouseUp: useCallback(\n (event) => {\n onMouseUp(event);\n if (disabled || isTouch) {\n return;\n }\n\n draggingRef.current = false;\n },\n [disabled, isTouch, onMouseUp]\n ),\n };\n const keyboardEventHandlers: Required<DraggableKeyboardEventHandlers<E>> = {\n onKeyDown: useCallback(\n (event) => {\n onKeyDown(event);\n if (disabled) {\n return;\n }\n\n const decrementKey = vertical ? \"ArrowDown\" : \"ArrowLeft\";\n const incrementKey = vertical ? \"ArrowUp\" : \"ArrowRight\";\n\n switch (event.key) {\n case decrementKey:\n event.preventDefault();\n decrement();\n break;\n case incrementKey:\n event.preventDefault();\n increment();\n break;\n case \"Home\":\n event.preventDefault();\n minimum();\n break;\n case \"End\":\n event.preventDefault();\n maximum();\n break;\n }\n },\n [decrement, disabled, increment, maximum, minimum, onKeyDown, vertical]\n ),\n };\n\n // touch devices are a bit weird and cause issues since the \"start\" event is\n // also used for scrolling. If the user quickly grabs the draggable element\n // and drags vertically, most of the time it will try to scroll instead of\n // dragging the element. The workaround is to being the drag events\n // immediately on touchstart and disable scroll behavior for the page.\n //\n // There are also some issues with calling `event.preventDefault()` within\n // touch events even while `{ passive: false } is manually set, so need to\n // also attach a touchmove event.\n useScrollLock(isTouch && dragging);\n const touchEventHandlers: Required<DraggableTouchEventHandlers<E>> = {\n onTouchStart: useCallback(\n (event) => {\n onTouchStart(event);\n if (disabled || !isTouchDragStartEvent(event)) {\n return;\n }\n\n draggingRef.current = true;\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n },\n [\n disabled,\n isRTL,\n max,\n min,\n nodeRef,\n onTouchStart,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n onTouchMove: useCallback(\n (event) => {\n onTouchMove(event);\n if (disabled || !draggingRef.current || !event.cancelable) {\n return;\n }\n\n // prevent the document's touchmove event from also firing\n event.stopPropagation();\n updateDragPosition({\n isDragStart: true,\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n });\n },\n [\n disabled,\n isRTL,\n max,\n min,\n nodeRef,\n onTouchMove,\n rangeMax,\n rangeMin,\n reversed,\n setDragging,\n setValue,\n step,\n vertical,\n withinOffsetParent,\n ]\n ),\n };\n\n return {\n ...touchEventHandlers,\n ...mouseEventHandlers,\n ...keyboardEventHandlers,\n value,\n setValue,\n dragging,\n setDragging,\n maximum,\n minimum,\n increment,\n decrement,\n draggedOnce,\n draggableRef: ref,\n percentage,\n dragPercentage,\n touchEventHandlers,\n mouseEventHandlers,\n keyboardEventHandlers,\n };\n}\n"],"names":["cnb","useCallback","useEffect","useRef","useState","useUserInteractionMode","useScrollLock","useDir","useEnsuredRef","useEnsuredState","useHtmlClassName","getPercentage","getRangeDefaultValue","getRangeSteps","nearest","withinRange","isMouseDragStartEvent","isTouchDragStartEvent","updateDragPosition","noop","useDraggable","options","ref","propRef","min","max","rangeMin","rangeMax","step","reversed","vertical","onKeyDown","onMouseUp","onMouseDown","onMouseMove","onTouchStart","onTouchMove","dragging","propDragging","setDragging","propSetDragging","value","propValue","setValue","propSetValue","defaultValue","withinOffsetParent","disabled","disableDraggingClassName","disableDraggingCursorClassName","nodeRef","isTouch","draggingRef","dragPercentage","setDragPercentage","isRTL","dir","percentage","maximum","minimum","increment","prevValue","decrement","draggingClassName","draggedOnce","current","updatePosition","event","cancelable","preventDefault","stopPropagation","isDragStart","stopDragging","blur","updateKey","stopKey","passive","undefined","globalThis","addEventListener","removeEventListener","prevRange","steps","mouseEventHandlers","keyboardEventHandlers","decrementKey","incrementKey","key","touchEventHandlers","draggableRef"],"mappings":"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gBAC7C;YACF;YAEAf,YAAYa,OAAO,GAAG;YACtB/C,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;QACF,GACA;YACEC;YACAQ;YACA9B;YACAD;YACA0B;YACAf;YACAR;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;QAEHV,aAAanC,YACX,CAACkE;YACC/B,YAAY+B;YACZ,IAAIpB,YAAY,CAACK,YAAYa,OAAO,IAAI,CAACE,MAAMC,UAAU,EAAE;gBACzD;YACF;YAEA,0DAA0D;YAC1DD,MAAMG,eAAe;YACrBpD,mBAAmB;gBACjBqD,aAAa;gBACbJ;gBACAjB;gBACA1B;gBACAC;gBACAG;gBACAF;gBACAC;gBACA4B;gBACA1B;gBACAC;gBACAa;gBACAJ;gBACAe;gBACAR;YACF;QACF,GACA;YACEC;YACAQ;YACA9B;YACAD;YACA0B;YACAd;YACAT;YACAD;YACAG;YACAU;YACAI;YACAf;YACAE;YACAgB;SACD;IAEL;IAEA,OAAO;QACL,GAAG0C,kBAAkB;QACrB,GAAGL,kBAAkB;QACrB,GAAGC,qBAAqB;QACxB3C;QACAE;QACAN;QACAE;QACAmB;QACAC;QACAC;QACAE;QACAE;QACAyB,cAAcnE;QACdmC;QACAJ;QACAmC;QACAL;QACAC;IACF;AACF"}
@@ -120,7 +120,7 @@ import { withinRange } from "../utils/withinRange.js";
120
120
  * @since 6.0.0
121
121
  */ export function deserializeDraggableValue(options) {
122
122
  const { item, min, max } = options;
123
- const value = parseFloat(item);
123
+ const value = Number.parseFloat(item);
124
124
  if (Number.isNaN(item)) {
125
125
  return min;
126
126
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/draggable/utils.ts"],"sourcesContent":["import { type MouseEvent, type RefObject, type TouchEvent } from \"react\";\n\nimport { type MinMaxRange } from \"../types.js\";\nimport {\n type ClientPositionEvent,\n type ClientPositionOptions,\n getClientPosition,\n} from \"../utils/getClientPosition.js\";\nimport { getRangeSteps } from \"../utils/getRangeSteps.js\";\nimport { nearest } from \"../utils/nearest.js\";\nimport { withinRange } from \"../utils/withinRange.js\";\n\n/**\n * @internal\n */\nexport const isMouseDragStartEvent = (event: MouseEvent): boolean =>\n event.button === 0 &&\n !event.altKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey;\n\n/**\n * @internal\n */\nexport const isTouchDragStartEvent = (event: TouchEvent): boolean =>\n event.changedTouches.length === 1;\n\n/**\n * @internal\n */\ninterface DragPositionOptions extends ClientPositionOptions {\n isRTL: boolean;\n reversed: boolean;\n container: Element;\n}\n\n/**\n * @internal\n */\nexport const getDragPosition = (options: DragPositionOptions): number => {\n const { isRTL, reversed, vertical, container } = options;\n\n const clientPosition = getClientPosition(options);\n const { left, right, top } = container.getBoundingClientRect();\n if (vertical) {\n if (reversed) {\n return window.innerHeight - clientPosition;\n }\n\n // added `Math.max` since the `top` will be a negative number if rendered\n // within a portal element like a dialog/sheet\n return clientPosition - Math.max(0, top);\n }\n\n if (reversed ? !isRTL : isRTL) {\n return right - clientPosition;\n }\n\n return clientPosition - left;\n};\n\n/**\n * @internal\n */\ninterface RelativeDragPositionOptions extends DragPositionOptions, MinMaxRange {\n step: number;\n rangeMin: number;\n rangeMax: number;\n}\n\n/**\n * @internal\n */\ninterface RelativeDragPosition {\n value: number;\n dragPercentage: number;\n}\n\n/**\n * @internal\n */\nexport const getRelativeDragPosition = (\n options: RelativeDragPositionOptions\n): RelativeDragPosition => {\n const { min, max, rangeMin, rangeMax, step, isRTL, vertical, container } =\n options;\n\n const { height, width, left, top } = container.getBoundingClientRect();\n const containerSize = vertical ? height : width;\n const containerPosition = vertical ? top + height : left;\n const clientPosition = getClientPosition(options);\n\n const position = vertical\n ? containerPosition - clientPosition\n : clientPosition - containerPosition;\n const distanceDragged = Math.min(Math.max(0, position), containerSize);\n let dragPercentage = distanceDragged / containerSize;\n if (isRTL && !vertical) {\n dragPercentage = 1 - dragPercentage;\n }\n\n const range = rangeMax - rangeMin;\n const steps = getRangeSteps({ min: rangeMin, max: rangeMax, step });\n const value = dragPercentage * range + rangeMin;\n const nextValue = nearest({\n min,\n max,\n steps,\n range,\n value,\n });\n\n return {\n value: nextValue,\n dragPercentage,\n };\n};\n\n/**\n * @internal\n */\ninterface UpdateDragPositionOptions extends Omit<\n RelativeDragPositionOptions,\n \"container\"\n> {\n event: ClientPositionEvent;\n nodeRef: RefObject<HTMLElement>;\n focus?: boolean;\n isDragStart: boolean;\n setValue: (value: number) => void;\n setDragging: (dragging: boolean) => void;\n setDragPercentage: (value: number) => void;\n withinOffsetParent: boolean;\n}\n\n/**\n * @internal\n */\nexport const updateDragPosition = (\n options: UpdateDragPositionOptions\n): void => {\n const {\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n isDragStart,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n } = options;\n\n const element = nodeRef.current;\n if (!element) {\n return;\n }\n\n if (isDragStart) {\n // need to focus so that Chromium based browsers allow drag events. this\n // really appeared while trying to create a DnD tree\n element.focus({ preventScroll: true });\n\n if (!withinOffsetParent && !(\"changedTouches\" in event)) {\n return;\n }\n\n // unlike the other flow, start dragging immediately so that you can trigger\n // a mousedown or touchstart event on the container element and drag until\n // the user lets go\n setDragging(true);\n }\n\n // firefox defaults to `document.body` while chrome will return `null`\n const container = element.offsetParent || document.body;\n if (!withinOffsetParent) {\n const dragPosition = getDragPosition({\n event,\n isRTL,\n reversed,\n vertical,\n container,\n });\n const nextValue = withinRange({\n min,\n max,\n value: dragPosition,\n });\n setValue(nextValue);\n\n return;\n }\n\n const { value, dragPercentage } = getRelativeDragPosition({\n min,\n max,\n rangeMin,\n rangeMax,\n step,\n event,\n isRTL,\n reversed,\n vertical,\n container,\n });\n\n setValue(value);\n setDragPercentage(dragPercentage);\n};\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface DeserializeDraggableValueOptions extends MinMaxRange {\n item: string;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function deserializeDraggableValue(\n options: DeserializeDraggableValueOptions\n): number {\n const { item, min, max } = options;\n\n const value = parseFloat(item);\n if (Number.isNaN(item)) {\n return min;\n }\n\n return Math.max(min, Math.min(max, value));\n}\n"],"names":["getClientPosition","getRangeSteps","nearest","withinRange","isMouseDragStartEvent","event","button","altKey","metaKey","ctrlKey","shiftKey","isTouchDragStartEvent","changedTouches","length","getDragPosition","options","isRTL","reversed","vertical","container","clientPosition","left","right","top","getBoundingClientRect","window","innerHeight","Math","max","getRelativeDragPosition","min","rangeMin","rangeMax","step","height","width","containerSize","containerPosition","position","distanceDragged","dragPercentage","range","steps","value","nextValue","updateDragPosition","nodeRef","isDragStart","setValue","setDragging","setDragPercentage","withinOffsetParent","element","current","focus","preventScroll","offsetParent","document","body","dragPosition","deserializeDraggableValue","item","parseFloat","Number","isNaN"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/draggable/utils.ts"],"sourcesContent":["import { type MouseEvent, type RefObject, type TouchEvent } from \"react\";\n\nimport { type MinMaxRange } from \"../types.js\";\nimport {\n type ClientPositionEvent,\n type ClientPositionOptions,\n getClientPosition,\n} from \"../utils/getClientPosition.js\";\nimport { getRangeSteps } from \"../utils/getRangeSteps.js\";\nimport { nearest } from \"../utils/nearest.js\";\nimport { withinRange } from \"../utils/withinRange.js\";\n\n/**\n * @internal\n */\nexport const isMouseDragStartEvent = (event: MouseEvent): boolean =>\n event.button === 0 &&\n !event.altKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey;\n\n/**\n * @internal\n */\nexport const isTouchDragStartEvent = (event: TouchEvent): boolean =>\n event.changedTouches.length === 1;\n\n/**\n * @internal\n */\ninterface DragPositionOptions extends ClientPositionOptions {\n isRTL: boolean;\n reversed: boolean;\n container: Element;\n}\n\n/**\n * @internal\n */\nexport const getDragPosition = (options: DragPositionOptions): number => {\n const { isRTL, reversed, vertical, container } = options;\n\n const clientPosition = getClientPosition(options);\n const { left, right, top } = container.getBoundingClientRect();\n if (vertical) {\n if (reversed) {\n return window.innerHeight - clientPosition;\n }\n\n // added `Math.max` since the `top` will be a negative number if rendered\n // within a portal element like a dialog/sheet\n return clientPosition - Math.max(0, top);\n }\n\n if (reversed ? !isRTL : isRTL) {\n return right - clientPosition;\n }\n\n return clientPosition - left;\n};\n\n/**\n * @internal\n */\ninterface RelativeDragPositionOptions extends DragPositionOptions, MinMaxRange {\n step: number;\n rangeMin: number;\n rangeMax: number;\n}\n\n/**\n * @internal\n */\ninterface RelativeDragPosition {\n value: number;\n dragPercentage: number;\n}\n\n/**\n * @internal\n */\nexport const getRelativeDragPosition = (\n options: RelativeDragPositionOptions\n): RelativeDragPosition => {\n const { min, max, rangeMin, rangeMax, step, isRTL, vertical, container } =\n options;\n\n const { height, width, left, top } = container.getBoundingClientRect();\n const containerSize = vertical ? height : width;\n const containerPosition = vertical ? top + height : left;\n const clientPosition = getClientPosition(options);\n\n const position = vertical\n ? containerPosition - clientPosition\n : clientPosition - containerPosition;\n const distanceDragged = Math.min(Math.max(0, position), containerSize);\n let dragPercentage = distanceDragged / containerSize;\n if (isRTL && !vertical) {\n dragPercentage = 1 - dragPercentage;\n }\n\n const range = rangeMax - rangeMin;\n const steps = getRangeSteps({ min: rangeMin, max: rangeMax, step });\n const value = dragPercentage * range + rangeMin;\n const nextValue = nearest({\n min,\n max,\n steps,\n range,\n value,\n });\n\n return {\n value: nextValue,\n dragPercentage,\n };\n};\n\n/**\n * @internal\n */\ninterface UpdateDragPositionOptions extends Omit<\n RelativeDragPositionOptions,\n \"container\"\n> {\n event: ClientPositionEvent;\n nodeRef: RefObject<HTMLElement>;\n focus?: boolean;\n isDragStart: boolean;\n setValue: (value: number) => void;\n setDragging: (dragging: boolean) => void;\n setDragPercentage: (value: number) => void;\n withinOffsetParent: boolean;\n}\n\n/**\n * @internal\n */\nexport const updateDragPosition = (\n options: UpdateDragPositionOptions\n): void => {\n const {\n event,\n nodeRef,\n min,\n max,\n step,\n rangeMin,\n rangeMax,\n isRTL,\n reversed,\n vertical,\n isDragStart,\n setValue,\n setDragging,\n setDragPercentage,\n withinOffsetParent,\n } = options;\n\n const element = nodeRef.current;\n if (!element) {\n return;\n }\n\n if (isDragStart) {\n // need to focus so that Chromium based browsers allow drag events. this\n // really appeared while trying to create a DnD tree\n element.focus({ preventScroll: true });\n\n if (!withinOffsetParent && !(\"changedTouches\" in event)) {\n return;\n }\n\n // unlike the other flow, start dragging immediately so that you can trigger\n // a mousedown or touchstart event on the container element and drag until\n // the user lets go\n setDragging(true);\n }\n\n // firefox defaults to `document.body` while chrome will return `null`\n const container = element.offsetParent || document.body;\n if (!withinOffsetParent) {\n const dragPosition = getDragPosition({\n event,\n isRTL,\n reversed,\n vertical,\n container,\n });\n const nextValue = withinRange({\n min,\n max,\n value: dragPosition,\n });\n setValue(nextValue);\n\n return;\n }\n\n const { value, dragPercentage } = getRelativeDragPosition({\n min,\n max,\n rangeMin,\n rangeMax,\n step,\n event,\n isRTL,\n reversed,\n vertical,\n container,\n });\n\n setValue(value);\n setDragPercentage(dragPercentage);\n};\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface DeserializeDraggableValueOptions extends MinMaxRange {\n item: string;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function deserializeDraggableValue(\n options: DeserializeDraggableValueOptions\n): number {\n const { item, min, max } = options;\n\n const value = Number.parseFloat(item);\n if (Number.isNaN(item)) {\n return min;\n }\n\n return Math.max(min, Math.min(max, value));\n}\n"],"names":["getClientPosition","getRangeSteps","nearest","withinRange","isMouseDragStartEvent","event","button","altKey","metaKey","ctrlKey","shiftKey","isTouchDragStartEvent","changedTouches","length","getDragPosition","options","isRTL","reversed","vertical","container","clientPosition","left","right","top","getBoundingClientRect","window","innerHeight","Math","max","getRelativeDragPosition","min","rangeMin","rangeMax","step","height","width","containerSize","containerPosition","position","distanceDragged","dragPercentage","range","steps","value","nextValue","updateDragPosition","nodeRef","isDragStart","setValue","setDragging","setDragPercentage","withinOffsetParent","element","current","focus","preventScroll","offsetParent","document","body","dragPosition","deserializeDraggableValue","item","Number","parseFloat","isNaN"],"mappings":"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"}
@@ -57,7 +57,7 @@ import { expansionPanel } from "./styles.js";
57
57
  transitionIn: expanded
58
58
  });
59
59
  let header = propHeader;
60
- if (typeof header === "undefined") {
60
+ if (header === undefined) {
61
61
  header = /*#__PURE__*/ _jsx(ExpansionPanelHeader, {
62
62
  style: headerStyle,
63
63
  className: headerClassName,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/expansion-panel/ExpansionPanel.tsx"],"sourcesContent":["\"use client\";\n\nimport { type CSSProperties, type ReactNode, forwardRef } from \"react\";\n\nimport { Card, type CardProps } from \"../card/Card.js\";\nimport { CardContent, type CardContentProps } from \"../card/CardContent.js\";\nimport { useCollapseTransition } from \"../transition/useCollapseTransition.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport {\n ExpansionPanelHeader,\n type ExpansionPanelHeaderProps,\n} from \"./ExpansionPanelHeader.js\";\nimport { expansionPanel } from \"./styles.js\";\n\n/**\n * @since 6.0.0 The `disableSecondaryColor` convenience prop was removed in\n * favor of the new `contentProps` object.\n * @since 6.0.0 The `disableParagraphMargin` prop was removed since it no longer\n * exists on the `CardContent` component.\n * @since 6.0.0 Removed the `marginTop` prop since it is no longer needed.\n */\nexport interface ExpansionPanelProps extends CardProps {\n /**\n * Set this to `true` if the {@link children} should be visible. This should\n * generally be provided by the `useExpansionPanels` hook.\n */\n expanded: boolean;\n\n /**\n * A function that should toggle the {@link expanded} state. This should\n * generally be provided by the `useExpansionPanels` hook.\n */\n onExpandClick: () => void;\n\n /**\n * Set this to `true` to prevent the panel from toggling the {@link expanded}\n * state. This should generally be provided by the `useExpansionPanels` hook.\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n\n /**\n * @defaultValue `true`\n * @see {@link CardProps.fullWidth}\n */\n fullWidth?: boolean;\n\n /**\n * This can be used to implement a custom header implementation, but it\n * probably shouldn't be needed.\n *\n * @since 6.0.0 This was renamed from `customHeader`\n * @see {@link headerProps}\n */\n header?: ReactNode;\n\n /**\n * This can be used to apply additional props to the header element.\n *\n * Note: You can override the `style` and `className` using\n * {@link headerStyle} and {@link headerClassName} instead for convenience.\n *\n * @example\n * ```tsx\n * <ExpansionPanel\n * {...props}\n * headerProps={{\n * style: {\n * // custom inline style\n * },\n * className: \"come-class-name\",\n * icon: <MyCustomIcon />,\n * iconRotatorProps: {\n * className: \"another-custom-class-name\",\n * },\n * }}\n * />\n * ```\n */\n headerProps?: Omit<\n ExpansionPanelHeaderProps,\n \"id\" | \"aria-disabled\" | \"onClick\" | \"expanded\"\n >;\n\n /**\n * Convenience prop to apply custom style to the `ExpansionPanelHeader`\n * component.\n */\n headerStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `ExpansionPanelHeader`\n * component.\n */\n headerClassName?: string;\n\n /**\n * Content to display within the header of the expansion panel that toggles\n * the expanded state. This should generally contain some accessible text\n * describing the expansion panel's content.\n *\n * @since 6.0.0 This was renamed from `header`\n */\n headerChildren?: ReactNode;\n\n /**\n * This can be used to apply additional props to the `CardContent` component\n * if needed.\n *\n * Note: `disableSecondaryColor` and `disableLastChildPadding` default to\n * `true` in this implementation.\n *\n * @example\n * ```tsx\n * contentProps={{\n * style: {},\n * className: \"some-class-name\",\n * disablePadding: true,\n * disableSecondaryColor: false,\n * disableLastChildPadding: false,\n * // whatever else\n * }}\n * ```\n *\n * @see {@link contentStyle}\n * @see {@link contentClassName}\n * @see {@link disableContentPadding}\n */\n contentProps?: PropsWithRef<Omit<CardContentProps, \"role\">>;\n\n /**\n * Convenience prop to apply custom style to the `CardContent` component.\n */\n contentStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `CardContent` component.\n */\n contentClassName?: string;\n\n /**\n * Set to `true` to disable the collapse transition for the card content\n * whenever the {@link expanded} state changes.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `false`\n * @see {@link CardContentProps.disablePadding}\n */\n disableContentPadding?: boolean;\n\n /**\n * Set this to `true` to unmount the {@link children} when the\n * {@link expanded} state is `false`.\n *\n * @defaultValue `false`\n * @since 6.0.0 Renamed from `persistent` to match the\n * `useCollapseTransition` naming convention.\n */\n temporary?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * An expansion panel enables content to be either collapsed (hidden) or\n * expanded (visible) following the disclosure pattern.\n *\n * @example Simple Example\n * ```tsx\n * \"use client\";\n *\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * export default function ExpansionPanelGroupExample(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList style={{ width: \"100%\" }}>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/expansion-panel | ExpansionPanel Demos}\n * @see `useExpansionPanels` for examples.\n * @since 6.0.0 The content will be persistent and invisible using `display: none`\n * instead of unmounting and also animate the `margin-top` style.\n */\nexport const ExpansionPanel = forwardRef<\n HTMLHeadingElement,\n ExpansionPanelProps\n>(function ExpansionPanel(props, ref) {\n const {\n id: propId,\n className,\n contentProps,\n contentStyle,\n contentClassName,\n header: propHeader,\n headerProps,\n headerStyle,\n headerClassName,\n headerChildren,\n children,\n expanded,\n onExpandClick,\n disabled = false,\n fullWidth = true,\n temporary = false,\n disableTransition = false,\n disableContentPadding = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"expansion-panel\");\n const { elementProps, rendered } = useCollapseTransition({\n nodeRef: contentProps?.ref,\n style: contentStyle,\n className: contentClassName,\n timeout: disableTransition ? 0 : undefined,\n temporary,\n transitionIn: expanded,\n });\n\n let header = propHeader;\n if (typeof header === \"undefined\") {\n header = (\n <ExpansionPanelHeader\n style={headerStyle}\n className={headerClassName}\n disableTransition={disableTransition}\n {...headerProps}\n aria-disabled={disabled || undefined}\n id={id}\n onClick={onExpandClick}\n expanded={expanded}\n >\n {headerChildren}\n </ExpansionPanelHeader>\n );\n }\n\n return (\n <Card\n {...remaining}\n id={`${id}-container`}\n ref={ref}\n fullWidth={fullWidth}\n className={expansionPanel({\n expanded,\n disableTransition,\n className,\n })}\n >\n {header}\n {rendered && (\n <CardContent\n id={`${id}-content`}\n aria-labelledby={id}\n disablePadding={disableContentPadding}\n disableSecondaryColor\n disableLastChildPadding\n {...contentProps}\n {...elementProps}\n role=\"region\"\n >\n {children}\n </CardContent>\n )}\n </Card>\n );\n});\n"],"names":["forwardRef","Card","CardContent","useCollapseTransition","useEnsuredId","ExpansionPanelHeader","expansionPanel","ExpansionPanel","props","ref","id","propId","className","contentProps","contentStyle","contentClassName","header","propHeader","headerProps","headerStyle","headerClassName","headerChildren","children","expanded","onExpandClick","disabled","fullWidth","temporary","disableTransition","disableContentPadding","remaining","elementProps","rendered","nodeRef","style","timeout","undefined","transitionIn","aria-disabled","onClick","aria-labelledby","disablePadding","disableSecondaryColor","disableLastChildPadding","role"],"mappings":"AAAA;;AAEA,SAA6CA,UAAU,QAAQ,QAAQ;AAEvE,SAASC,IAAI,QAAwB,kBAAkB;AACvD,SAASC,WAAW,QAA+B,yBAAyB;AAC5E,SAASC,qBAAqB,QAAQ,yCAAyC;AAE/E,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SACEC,oBAAoB,QAEf,4BAA4B;AACnC,SAASC,cAAc,QAAQ,cAAc;AA0J7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCC,GACD,OAAO,MAAMC,+BAAiBP,WAG5B,SAASO,eAAeC,KAAK,EAAEC,GAAG;IAClC,MAAM,EACJC,IAAIC,MAAM,EACVC,SAAS,EACTC,YAAY,EACZC,YAAY,EACZC,gBAAgB,EAChBC,QAAQC,UAAU,EAClBC,WAAW,EACXC,WAAW,EACXC,eAAe,EACfC,cAAc,EACdC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,WAAW,KAAK,EAChBC,YAAY,IAAI,EAChBC,YAAY,KAAK,EACjBC,oBAAoB,KAAK,EACzBC,wBAAwB,KAAK,EAC7B,GAAGC,WACJ,GAAGtB;IAEJ,MAAME,KAAKN,aAAaO,QAAQ;IAChC,MAAM,EAAEoB,YAAY,EAAEC,QAAQ,EAAE,GAAG7B,sBAAsB;QACvD8B,SAASpB,cAAcJ;QACvByB,OAAOpB;QACPF,WAAWG;QACXoB,SAASP,oBAAoB,IAAIQ;QACjCT;QACAU,cAAcd;IAChB;IAEA,IAAIP,SAASC;IACb,IAAI,OAAOD,WAAW,aAAa;QACjCA,uBACE,KAACX;YACC6B,OAAOf;YACPP,WAAWQ;YACXQ,mBAAmBA;YAClB,GAAGV,WAAW;YACfoB,iBAAeb,YAAYW;YAC3B1B,IAAIA;YACJ6B,SAASf;YACTD,UAAUA;sBAETF;;IAGP;IAEA,qBACE,MAACpB;QACE,GAAG6B,SAAS;QACbpB,IAAI,GAAGA,GAAG,UAAU,CAAC;QACrBD,KAAKA;QACLiB,WAAWA;QACXd,WAAWN,eAAe;YACxBiB;YACAK;YACAhB;QACF;;YAECI;YACAgB,0BACC,KAAC9B;gBACCQ,IAAI,GAAGA,GAAG,QAAQ,CAAC;gBACnB8B,mBAAiB9B;gBACjB+B,gBAAgBZ;gBAChBa,qBAAqB;gBACrBC,uBAAuB;gBACtB,GAAG9B,YAAY;gBACf,GAAGkB,YAAY;gBAChBa,MAAK;0BAEJtB;;;;AAKX,GAAG"}
1
+ {"version":3,"sources":["../../src/expansion-panel/ExpansionPanel.tsx"],"sourcesContent":["\"use client\";\n\nimport { type CSSProperties, type ReactNode, forwardRef } from \"react\";\n\nimport { Card, type CardProps } from \"../card/Card.js\";\nimport { CardContent, type CardContentProps } from \"../card/CardContent.js\";\nimport { useCollapseTransition } from \"../transition/useCollapseTransition.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport {\n ExpansionPanelHeader,\n type ExpansionPanelHeaderProps,\n} from \"./ExpansionPanelHeader.js\";\nimport { expansionPanel } from \"./styles.js\";\n\n/**\n * @since 6.0.0 The `disableSecondaryColor` convenience prop was removed in\n * favor of the new `contentProps` object.\n * @since 6.0.0 The `disableParagraphMargin` prop was removed since it no longer\n * exists on the `CardContent` component.\n * @since 6.0.0 Removed the `marginTop` prop since it is no longer needed.\n */\nexport interface ExpansionPanelProps extends CardProps {\n /**\n * Set this to `true` if the {@link children} should be visible. This should\n * generally be provided by the `useExpansionPanels` hook.\n */\n expanded: boolean;\n\n /**\n * A function that should toggle the {@link expanded} state. This should\n * generally be provided by the `useExpansionPanels` hook.\n */\n onExpandClick: () => void;\n\n /**\n * Set this to `true` to prevent the panel from toggling the {@link expanded}\n * state. This should generally be provided by the `useExpansionPanels` hook.\n *\n * @defaultValue `false`\n */\n disabled?: boolean;\n\n /**\n * @defaultValue `true`\n * @see {@link CardProps.fullWidth}\n */\n fullWidth?: boolean;\n\n /**\n * This can be used to implement a custom header implementation, but it\n * probably shouldn't be needed.\n *\n * @since 6.0.0 This was renamed from `customHeader`\n * @see {@link headerProps}\n */\n header?: ReactNode;\n\n /**\n * This can be used to apply additional props to the header element.\n *\n * Note: You can override the `style` and `className` using\n * {@link headerStyle} and {@link headerClassName} instead for convenience.\n *\n * @example\n * ```tsx\n * <ExpansionPanel\n * {...props}\n * headerProps={{\n * style: {\n * // custom inline style\n * },\n * className: \"come-class-name\",\n * icon: <MyCustomIcon />,\n * iconRotatorProps: {\n * className: \"another-custom-class-name\",\n * },\n * }}\n * />\n * ```\n */\n headerProps?: Omit<\n ExpansionPanelHeaderProps,\n \"id\" | \"aria-disabled\" | \"onClick\" | \"expanded\"\n >;\n\n /**\n * Convenience prop to apply custom style to the `ExpansionPanelHeader`\n * component.\n */\n headerStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `ExpansionPanelHeader`\n * component.\n */\n headerClassName?: string;\n\n /**\n * Content to display within the header of the expansion panel that toggles\n * the expanded state. This should generally contain some accessible text\n * describing the expansion panel's content.\n *\n * @since 6.0.0 This was renamed from `header`\n */\n headerChildren?: ReactNode;\n\n /**\n * This can be used to apply additional props to the `CardContent` component\n * if needed.\n *\n * Note: `disableSecondaryColor` and `disableLastChildPadding` default to\n * `true` in this implementation.\n *\n * @example\n * ```tsx\n * contentProps={{\n * style: {},\n * className: \"some-class-name\",\n * disablePadding: true,\n * disableSecondaryColor: false,\n * disableLastChildPadding: false,\n * // whatever else\n * }}\n * ```\n *\n * @see {@link contentStyle}\n * @see {@link contentClassName}\n * @see {@link disableContentPadding}\n */\n contentProps?: PropsWithRef<Omit<CardContentProps, \"role\">>;\n\n /**\n * Convenience prop to apply custom style to the `CardContent` component.\n */\n contentStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `CardContent` component.\n */\n contentClassName?: string;\n\n /**\n * Set to `true` to disable the collapse transition for the card content\n * whenever the {@link expanded} state changes.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `false`\n * @see {@link CardContentProps.disablePadding}\n */\n disableContentPadding?: boolean;\n\n /**\n * Set this to `true` to unmount the {@link children} when the\n * {@link expanded} state is `false`.\n *\n * @defaultValue `false`\n * @since 6.0.0 Renamed from `persistent` to match the\n * `useCollapseTransition` naming convention.\n */\n temporary?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * An expansion panel enables content to be either collapsed (hidden) or\n * expanded (visible) following the disclosure pattern.\n *\n * @example Simple Example\n * ```tsx\n * \"use client\";\n *\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * export default function ExpansionPanelGroupExample(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList style={{ width: \"100%\" }}>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/expansion-panel | ExpansionPanel Demos}\n * @see `useExpansionPanels` for examples.\n * @since 6.0.0 The content will be persistent and invisible using `display: none`\n * instead of unmounting and also animate the `margin-top` style.\n */\nexport const ExpansionPanel = forwardRef<\n HTMLHeadingElement,\n ExpansionPanelProps\n>(function ExpansionPanel(props, ref) {\n const {\n id: propId,\n className,\n contentProps,\n contentStyle,\n contentClassName,\n header: propHeader,\n headerProps,\n headerStyle,\n headerClassName,\n headerChildren,\n children,\n expanded,\n onExpandClick,\n disabled = false,\n fullWidth = true,\n temporary = false,\n disableTransition = false,\n disableContentPadding = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"expansion-panel\");\n const { elementProps, rendered } = useCollapseTransition({\n nodeRef: contentProps?.ref,\n style: contentStyle,\n className: contentClassName,\n timeout: disableTransition ? 0 : undefined,\n temporary,\n transitionIn: expanded,\n });\n\n let header = propHeader;\n if (header === undefined) {\n header = (\n <ExpansionPanelHeader\n style={headerStyle}\n className={headerClassName}\n disableTransition={disableTransition}\n {...headerProps}\n aria-disabled={disabled || undefined}\n id={id}\n onClick={onExpandClick}\n expanded={expanded}\n >\n {headerChildren}\n </ExpansionPanelHeader>\n );\n }\n\n return (\n <Card\n {...remaining}\n id={`${id}-container`}\n ref={ref}\n fullWidth={fullWidth}\n className={expansionPanel({\n expanded,\n disableTransition,\n className,\n })}\n >\n {header}\n {rendered && (\n <CardContent\n id={`${id}-content`}\n aria-labelledby={id}\n disablePadding={disableContentPadding}\n disableSecondaryColor\n disableLastChildPadding\n {...contentProps}\n {...elementProps}\n role=\"region\"\n >\n {children}\n </CardContent>\n )}\n </Card>\n );\n});\n"],"names":["forwardRef","Card","CardContent","useCollapseTransition","useEnsuredId","ExpansionPanelHeader","expansionPanel","ExpansionPanel","props","ref","id","propId","className","contentProps","contentStyle","contentClassName","header","propHeader","headerProps","headerStyle","headerClassName","headerChildren","children","expanded","onExpandClick","disabled","fullWidth","temporary","disableTransition","disableContentPadding","remaining","elementProps","rendered","nodeRef","style","timeout","undefined","transitionIn","aria-disabled","onClick","aria-labelledby","disablePadding","disableSecondaryColor","disableLastChildPadding","role"],"mappings":"AAAA;;AAEA,SAA6CA,UAAU,QAAQ,QAAQ;AAEvE,SAASC,IAAI,QAAwB,kBAAkB;AACvD,SAASC,WAAW,QAA+B,yBAAyB;AAC5E,SAASC,qBAAqB,QAAQ,yCAAyC;AAE/E,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SACEC,oBAAoB,QAEf,4BAA4B;AACnC,SAASC,cAAc,QAAQ,cAAc;AA0J7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCC,GACD,OAAO,MAAMC,+BAAiBP,WAG5B,SAASO,eAAeC,KAAK,EAAEC,GAAG;IAClC,MAAM,EACJC,IAAIC,MAAM,EACVC,SAAS,EACTC,YAAY,EACZC,YAAY,EACZC,gBAAgB,EAChBC,QAAQC,UAAU,EAClBC,WAAW,EACXC,WAAW,EACXC,eAAe,EACfC,cAAc,EACdC,QAAQ,EACRC,QAAQ,EACRC,aAAa,EACbC,WAAW,KAAK,EAChBC,YAAY,IAAI,EAChBC,YAAY,KAAK,EACjBC,oBAAoB,KAAK,EACzBC,wBAAwB,KAAK,EAC7B,GAAGC,WACJ,GAAGtB;IAEJ,MAAME,KAAKN,aAAaO,QAAQ;IAChC,MAAM,EAAEoB,YAAY,EAAEC,QAAQ,EAAE,GAAG7B,sBAAsB;QACvD8B,SAASpB,cAAcJ;QACvByB,OAAOpB;QACPF,WAAWG;QACXoB,SAASP,oBAAoB,IAAIQ;QACjCT;QACAU,cAAcd;IAChB;IAEA,IAAIP,SAASC;IACb,IAAID,WAAWoB,WAAW;QACxBpB,uBACE,KAACX;YACC6B,OAAOf;YACPP,WAAWQ;YACXQ,mBAAmBA;YAClB,GAAGV,WAAW;YACfoB,iBAAeb,YAAYW;YAC3B1B,IAAIA;YACJ6B,SAASf;YACTD,UAAUA;sBAETF;;IAGP;IAEA,qBACE,MAACpB;QACE,GAAG6B,SAAS;QACbpB,IAAI,GAAGA,GAAG,UAAU,CAAC;QACrBD,KAAKA;QACLiB,WAAWA;QACXd,WAAWN,eAAe;YACxBiB;YACAK;YACAhB;QACF;;YAECI;YACAgB,0BACC,KAAC9B;gBACCQ,IAAI,GAAGA,GAAG,QAAQ,CAAC;gBACnB8B,mBAAiB9B;gBACjB+B,gBAAgBZ;gBAChBa,qBAAqB;gBACrBC,uBAAuB;gBACtB,GAAG9B,YAAY;gBACf,GAAGkB,YAAY;gBAChBa,MAAK;0BAEJtB;;;;AAKX,GAAG"}
@@ -80,7 +80,7 @@ import { useReadonlySet } from "../useReadonlySet.js";
80
80
  const { value: expandedIds, setValue: setExpandedIds, toggleValue } = useReadonlySet({
81
81
  toggleType: multiple ? "multiple" : "single",
82
82
  defaultValue: ()=>{
83
- if (typeof defaultExpandedIds === "undefined") {
83
+ if (defaultExpandedIds === undefined) {
84
84
  const initialList = [];
85
85
  if (typeof defaultExpandedIndex === "number" || preventAllCollapsed) {
86
86
  initialList.push(createId(defaultExpandedIndex ?? 0));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/expansion-panel/useExpansionPanels.ts"],"sourcesContent":["\"use client\";\n\nimport type { UseStateInitializer, UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useReadonlySet } from \"../useReadonlySet.js\";\nimport type { ExpansionPanelProps } from \"./ExpansionPanel.js\";\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelHookOptions {\n /**\n * An optional id to prefix each panel with.\n *\n * @defaultValue `\"expansion-panel-\" + useId()`\n */\n baseId?: string;\n\n /**\n * Set this to `true` if multiple panels can be open at the same time.\n *\n * @defaultValue `false`\n */\n multiple?: boolean;\n\n /**\n * Set this to `true` to enforce that at least one panel must always be\n * expanded.\n *\n * @defaultValue `false`\n */\n preventAllCollapsed?: boolean;\n\n /**\n * This is a convenience option to disable the expansion transition for all\n * panels.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `preventAllCollapsed ? [\"expansion-panel-\" + useId() + \"-1\"] : []`\n */\n defaultExpandedIds?: UseStateInitializer<string[]>;\n\n /**\n * This can only be used if the {@link defaultExpandedIds} was not provided\n * and using index based panels.\n *\n * @example\n * ```tsx\n * const { getPanelProps } = useExpansionPanels({\n * defaultExpandedIndex: 2,\n * });\n *\n * return (\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * // expanded on first render\n * <ExpansionPanel {...getPanelProps(2)} />\n * <ExpansionPanel {...getPanelProps(3)} />\n * );\n * ```\n */\n defaultExpandedIndex?: number;\n\n /**\n * @defaultValue `false`\n */\n disableContentPadding?: boolean;\n}\n\n/** @since 6.0.0 */\nexport type ProvidedExpansionPanelProps = Pick<\n Required<ExpansionPanelProps>,\n | \"disabled\"\n | \"expanded\"\n | \"onExpandClick\"\n | \"disableTransition\"\n | \"disableContentPadding\"\n> & { id?: string };\n\n/**\n * @param indexOrPanelId - This should either be a DOM id to use for the panel\n * or the panel's index.\n * @returns Props to pass to an `ExpansionPanel` for it to work correctly.\n * @since 6.0.0\n */\nexport type GetExpansionPanelProps = (\n indexOrPanelId: string | number\n) => ProvidedExpansionPanelProps;\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelImplementation {\n /**\n * The current set of expanded panel ids if you need this for some reason.\n */\n expandedIds: ReadonlySet<string>;\n\n /**\n * This can be used to manually control which panels are expanded if the\n * default behavior does not work for your use case.\n */\n setExpandedIds: UseStateSetter<ReadonlySet<string>>;\n\n /**\n * @example Index Based Panels\n * ```tsx\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * <ExpansionPanel {...getPanelProps(2)} />\n * ```\n *\n * @example Custom Panel Ids\n * ```tsx\n * <ExpansionPanel {...getPanelProps(\"address-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"billing-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"confirmation-panel\")} />\n * ```\n */\n getPanelProps: GetExpansionPanelProps;\n}\n\n/**\n * Use this hook to control the expanded state for a group of `ExpansionPanel`.\n *\n * @example Index Based Panels\n * ```tsx\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @example Custom Panel Ids and Expand All Panels by Default\n * ```tsx\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * const panel1Id = \"personal-information-panel\";\n * const panel2Id = \"billing-information-panel\";\n * const panel3Id = \"billing-address-panel\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels({\n * multiple: true,\n * defaultExpandedIds: () => [panel1Id, panel2Id, panel3Id],\n * });\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(panel1Id)} headerChildren=\"Personal Information\">\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel2Id)} headerChildren=\"Billing Information\">\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel3Id)} headerChildren=\"Billing Address\">\n * <BillingAddress />\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n *\n * @see {@link https://react-md.dev/components/expansion-panel | ExpansionPanel Demos}\n * @since 6.0.0 The hook was renamed from `usePanels` to `useExpansionPanels`,\n * the API changed to return `getPanelProps` instead of a generated list of\n * panel props based on the provided `count`, and the hook no longer supports\n * having all panels expanded by default.\n */\nexport function useExpansionPanels(\n options: ExpansionPanelHookOptions = {}\n): ExpansionPanelImplementation {\n const {\n baseId: propBaseId,\n multiple = false,\n preventAllCollapsed = false,\n disableTransition = false,\n defaultExpandedIds,\n defaultExpandedIndex,\n disableContentPadding = false,\n } = options;\n\n const baseId = useEnsuredId(propBaseId, \"expansion-panel\");\n const createId = (index: number): string => `${baseId}-${index + 1}`;\n const {\n value: expandedIds,\n setValue: setExpandedIds,\n toggleValue,\n } = useReadonlySet({\n toggleType: multiple ? \"multiple\" : \"single\",\n defaultValue: () => {\n if (typeof defaultExpandedIds === \"undefined\") {\n const initialList: string[] = [];\n if (typeof defaultExpandedIndex === \"number\" || preventAllCollapsed) {\n initialList.push(createId(defaultExpandedIndex ?? 0));\n }\n\n return new Set(initialList);\n }\n\n return typeof defaultExpandedIds === \"function\"\n ? defaultExpandedIds()\n : defaultExpandedIds;\n },\n });\n\n return {\n expandedIds,\n setExpandedIds,\n getPanelProps(indexOrPanelId) {\n let id: string | undefined;\n let panelId: string;\n if (typeof indexOrPanelId === \"number\") {\n id = createId(indexOrPanelId);\n panelId = id;\n } else {\n panelId = indexOrPanelId;\n }\n\n const expanded = expandedIds.has(panelId);\n const disabled =\n expanded && preventAllCollapsed && expandedIds.size === 1;\n return {\n id,\n disabled,\n expanded,\n onExpandClick() {\n if (disabled) {\n return;\n }\n\n toggleValue(panelId);\n },\n disableTransition,\n disableContentPadding,\n };\n },\n };\n}\n"],"names":["useEnsuredId","useReadonlySet","useExpansionPanels","options","baseId","propBaseId","multiple","preventAllCollapsed","disableTransition","defaultExpandedIds","defaultExpandedIndex","disableContentPadding","createId","index","value","expandedIds","setValue","setExpandedIds","toggleValue","toggleType","defaultValue","initialList","push","Set","getPanelProps","indexOrPanelId","id","panelId","expanded","has","disabled","size","onExpandClick"],"mappings":"AAAA;AAGA,SAASA,YAAY,QAAQ,qBAAqB;AAClD,SAASC,cAAc,QAAQ,uBAAuB;AAsHtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwEC,GACD,OAAO,SAASC,mBACdC,UAAqC,CAAC,CAAC;IAEvC,MAAM,EACJC,QAAQC,UAAU,EAClBC,WAAW,KAAK,EAChBC,sBAAsB,KAAK,EAC3BC,oBAAoB,KAAK,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,wBAAwB,KAAK,EAC9B,GAAGR;IAEJ,MAAMC,SAASJ,aAAaK,YAAY;IACxC,MAAMO,WAAW,CAACC,QAA0B,GAAGT,OAAO,CAAC,EAAES,QAAQ,GAAG;IACpE,MAAM,EACJC,OAAOC,WAAW,EAClBC,UAAUC,cAAc,EACxBC,WAAW,EACZ,GAAGjB,eAAe;QACjBkB,YAAYb,WAAW,aAAa;QACpCc,cAAc;YACZ,IAAI,OAAOX,uBAAuB,aAAa;gBAC7C,MAAMY,cAAwB,EAAE;gBAChC,IAAI,OAAOX,yBAAyB,YAAYH,qBAAqB;oBACnEc,YAAYC,IAAI,CAACV,SAASF,wBAAwB;gBACpD;gBAEA,OAAO,IAAIa,IAAIF;YACjB;YAEA,OAAO,OAAOZ,uBAAuB,aACjCA,uBACAA;QACN;IACF;IAEA,OAAO;QACLM;QACAE;QACAO,eAAcC,cAAc;YAC1B,IAAIC;YACJ,IAAIC;YACJ,IAAI,OAAOF,mBAAmB,UAAU;gBACtCC,KAAKd,SAASa;gBACdE,UAAUD;YACZ,OAAO;gBACLC,UAAUF;YACZ;YAEA,MAAMG,WAAWb,YAAYc,GAAG,CAACF;YACjC,MAAMG,WACJF,YAAYrB,uBAAuBQ,YAAYgB,IAAI,KAAK;YAC1D,OAAO;gBACLL;gBACAI;gBACAF;gBACAI;oBACE,IAAIF,UAAU;wBACZ;oBACF;oBAEAZ,YAAYS;gBACd;gBACAnB;gBACAG;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/expansion-panel/useExpansionPanels.ts"],"sourcesContent":["\"use client\";\n\nimport type { UseStateInitializer, UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useReadonlySet } from \"../useReadonlySet.js\";\nimport type { ExpansionPanelProps } from \"./ExpansionPanel.js\";\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelHookOptions {\n /**\n * An optional id to prefix each panel with.\n *\n * @defaultValue `\"expansion-panel-\" + useId()`\n */\n baseId?: string;\n\n /**\n * Set this to `true` if multiple panels can be open at the same time.\n *\n * @defaultValue `false`\n */\n multiple?: boolean;\n\n /**\n * Set this to `true` to enforce that at least one panel must always be\n * expanded.\n *\n * @defaultValue `false`\n */\n preventAllCollapsed?: boolean;\n\n /**\n * This is a convenience option to disable the expansion transition for all\n * panels.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `preventAllCollapsed ? [\"expansion-panel-\" + useId() + \"-1\"] : []`\n */\n defaultExpandedIds?: UseStateInitializer<string[]>;\n\n /**\n * This can only be used if the {@link defaultExpandedIds} was not provided\n * and using index based panels.\n *\n * @example\n * ```tsx\n * const { getPanelProps } = useExpansionPanels({\n * defaultExpandedIndex: 2,\n * });\n *\n * return (\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * // expanded on first render\n * <ExpansionPanel {...getPanelProps(2)} />\n * <ExpansionPanel {...getPanelProps(3)} />\n * );\n * ```\n */\n defaultExpandedIndex?: number;\n\n /**\n * @defaultValue `false`\n */\n disableContentPadding?: boolean;\n}\n\n/** @since 6.0.0 */\nexport type ProvidedExpansionPanelProps = Pick<\n Required<ExpansionPanelProps>,\n | \"disabled\"\n | \"expanded\"\n | \"onExpandClick\"\n | \"disableTransition\"\n | \"disableContentPadding\"\n> & { id?: string };\n\n/**\n * @param indexOrPanelId - This should either be a DOM id to use for the panel\n * or the panel's index.\n * @returns Props to pass to an `ExpansionPanel` for it to work correctly.\n * @since 6.0.0\n */\nexport type GetExpansionPanelProps = (\n indexOrPanelId: string | number\n) => ProvidedExpansionPanelProps;\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelImplementation {\n /**\n * The current set of expanded panel ids if you need this for some reason.\n */\n expandedIds: ReadonlySet<string>;\n\n /**\n * This can be used to manually control which panels are expanded if the\n * default behavior does not work for your use case.\n */\n setExpandedIds: UseStateSetter<ReadonlySet<string>>;\n\n /**\n * @example Index Based Panels\n * ```tsx\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * <ExpansionPanel {...getPanelProps(2)} />\n * ```\n *\n * @example Custom Panel Ids\n * ```tsx\n * <ExpansionPanel {...getPanelProps(\"address-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"billing-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"confirmation-panel\")} />\n * ```\n */\n getPanelProps: GetExpansionPanelProps;\n}\n\n/**\n * Use this hook to control the expanded state for a group of `ExpansionPanel`.\n *\n * @example Index Based Panels\n * ```tsx\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @example Custom Panel Ids and Expand All Panels by Default\n * ```tsx\n * import { ExpansionList } from \"@react-md/core/expansion-panel/ExpansionList\";\n * import { ExpansionPanel } from \"@react-md/core/expansion-panel/ExpansionPanel\";\n * import { useExpansionPanels } from \"@react-md/core/expansion-panel/useExpansionPanels\";\n * import { type ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * const panel1Id = \"personal-information-panel\";\n * const panel2Id = \"billing-information-panel\";\n * const panel3Id = \"billing-address-panel\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels({\n * multiple: true,\n * defaultExpandedIds: () => [panel1Id, panel2Id, panel3Id],\n * });\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(panel1Id)} headerChildren=\"Personal Information\">\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel2Id)} headerChildren=\"Billing Information\">\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel3Id)} headerChildren=\"Billing Address\">\n * <BillingAddress />\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n *\n * @see {@link https://react-md.dev/components/expansion-panel | ExpansionPanel Demos}\n * @since 6.0.0 The hook was renamed from `usePanels` to `useExpansionPanels`,\n * the API changed to return `getPanelProps` instead of a generated list of\n * panel props based on the provided `count`, and the hook no longer supports\n * having all panels expanded by default.\n */\nexport function useExpansionPanels(\n options: ExpansionPanelHookOptions = {}\n): ExpansionPanelImplementation {\n const {\n baseId: propBaseId,\n multiple = false,\n preventAllCollapsed = false,\n disableTransition = false,\n defaultExpandedIds,\n defaultExpandedIndex,\n disableContentPadding = false,\n } = options;\n\n const baseId = useEnsuredId(propBaseId, \"expansion-panel\");\n const createId = (index: number): string => `${baseId}-${index + 1}`;\n const {\n value: expandedIds,\n setValue: setExpandedIds,\n toggleValue,\n } = useReadonlySet({\n toggleType: multiple ? \"multiple\" : \"single\",\n defaultValue: () => {\n if (defaultExpandedIds === undefined) {\n const initialList: string[] = [];\n if (typeof defaultExpandedIndex === \"number\" || preventAllCollapsed) {\n initialList.push(createId(defaultExpandedIndex ?? 0));\n }\n\n return new Set(initialList);\n }\n\n return typeof defaultExpandedIds === \"function\"\n ? defaultExpandedIds()\n : defaultExpandedIds;\n },\n });\n\n return {\n expandedIds,\n setExpandedIds,\n getPanelProps(indexOrPanelId) {\n let id: string | undefined;\n let panelId: string;\n if (typeof indexOrPanelId === \"number\") {\n id = createId(indexOrPanelId);\n panelId = id;\n } else {\n panelId = indexOrPanelId;\n }\n\n const expanded = expandedIds.has(panelId);\n const disabled =\n expanded && preventAllCollapsed && expandedIds.size === 1;\n return {\n id,\n disabled,\n expanded,\n onExpandClick() {\n if (disabled) {\n return;\n }\n\n toggleValue(panelId);\n },\n disableTransition,\n disableContentPadding,\n };\n },\n };\n}\n"],"names":["useEnsuredId","useReadonlySet","useExpansionPanels","options","baseId","propBaseId","multiple","preventAllCollapsed","disableTransition","defaultExpandedIds","defaultExpandedIndex","disableContentPadding","createId","index","value","expandedIds","setValue","setExpandedIds","toggleValue","toggleType","defaultValue","undefined","initialList","push","Set","getPanelProps","indexOrPanelId","id","panelId","expanded","has","disabled","size","onExpandClick"],"mappings":"AAAA;AAGA,SAASA,YAAY,QAAQ,qBAAqB;AAClD,SAASC,cAAc,QAAQ,uBAAuB;AAsHtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwEC,GACD,OAAO,SAASC,mBACdC,UAAqC,CAAC,CAAC;IAEvC,MAAM,EACJC,QAAQC,UAAU,EAClBC,WAAW,KAAK,EAChBC,sBAAsB,KAAK,EAC3BC,oBAAoB,KAAK,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,wBAAwB,KAAK,EAC9B,GAAGR;IAEJ,MAAMC,SAASJ,aAAaK,YAAY;IACxC,MAAMO,WAAW,CAACC,QAA0B,GAAGT,OAAO,CAAC,EAAES,QAAQ,GAAG;IACpE,MAAM,EACJC,OAAOC,WAAW,EAClBC,UAAUC,cAAc,EACxBC,WAAW,EACZ,GAAGjB,eAAe;QACjBkB,YAAYb,WAAW,aAAa;QACpCc,cAAc;YACZ,IAAIX,uBAAuBY,WAAW;gBACpC,MAAMC,cAAwB,EAAE;gBAChC,IAAI,OAAOZ,yBAAyB,YAAYH,qBAAqB;oBACnEe,YAAYC,IAAI,CAACX,SAASF,wBAAwB;gBACpD;gBAEA,OAAO,IAAIc,IAAIF;YACjB;YAEA,OAAO,OAAOb,uBAAuB,aACjCA,uBACAA;QACN;IACF;IAEA,OAAO;QACLM;QACAE;QACAQ,eAAcC,cAAc;YAC1B,IAAIC;YACJ,IAAIC;YACJ,IAAI,OAAOF,mBAAmB,UAAU;gBACtCC,KAAKf,SAASc;gBACdE,UAAUD;YACZ,OAAO;gBACLC,UAAUF;YACZ;YAEA,MAAMG,WAAWd,YAAYe,GAAG,CAACF;YACjC,MAAMG,WACJF,YAAYtB,uBAAuBQ,YAAYiB,IAAI,KAAK;YAC1D,OAAO;gBACLL;gBACAI;gBACAF;gBACAI;oBACE,IAAIF,UAAU;wBACZ;oBACF;oBAEAb,YAAYU;gBACd;gBACApB;gBACAG;YACF;QACF;IACF;AACF"}
@@ -71,7 +71,7 @@ import { fileInput } from "./styles.js";
71
71
  });
72
72
  const icon = getIcon("upload", propIcon);
73
73
  let children = propChildren;
74
- if (typeof propChildren === "undefined" && !props["aria-label"] && !props["aria-labelledby"]) {
74
+ if (propChildren === undefined && !props["aria-label"] && !props["aria-labelledby"]) {
75
75
  children = /*#__PURE__*/ _jsx(SrOnly, {
76
76
  phoneOnly: responsive,
77
77
  children: srOnlyLabel