@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.
- package/dist/_utils.scss +5 -1
- package/dist/autocomplete/AutocompleteChip.js +2 -2
- package/dist/autocomplete/AutocompleteChip.js.map +1 -1
- package/dist/autocomplete/AutocompleteListboxChildren.js +1 -1
- package/dist/autocomplete/AutocompleteListboxChildren.js.map +1 -1
- package/dist/autocomplete/useAutocomplete.js +4 -4
- package/dist/autocomplete/useAutocomplete.js.map +1 -1
- package/dist/autocomplete/utils.js +3 -3
- package/dist/autocomplete/utils.js.map +1 -1
- package/dist/box/styles.js +2 -2
- package/dist/box/styles.js.map +1 -1
- package/dist/button/AsyncButton.js +1 -1
- package/dist/button/AsyncButton.js.map +1 -1
- package/dist/chip/Chip.js +1 -1
- package/dist/chip/Chip.js.map +1 -1
- package/dist/cssUtils.d.ts +11 -6
- package/dist/cssUtils.js.map +1 -1
- package/dist/datetime/useTimeField.js +1 -1
- package/dist/datetime/useTimeField.js.map +1 -1
- package/dist/delegateEvent.js +9 -9
- package/dist/delegateEvent.js.map +1 -1
- package/dist/draggable/useDraggable.js +4 -4
- package/dist/draggable/useDraggable.js.map +1 -1
- package/dist/draggable/utils.js +1 -1
- package/dist/draggable/utils.js.map +1 -1
- package/dist/expansion-panel/ExpansionPanel.js +1 -1
- package/dist/expansion-panel/ExpansionPanel.js.map +1 -1
- package/dist/expansion-panel/useExpansionPanels.js +1 -1
- package/dist/expansion-panel/useExpansionPanels.js.map +1 -1
- package/dist/files/FileInput.js +1 -1
- package/dist/files/FileInput.js.map +1 -1
- package/dist/files/createAcceptFromExtensions.d.ts +5 -0
- package/dist/files/createAcceptFromExtensions.js +15 -0
- package/dist/files/createAcceptFromExtensions.js.map +1 -0
- package/dist/files/useFileUpload.js +45 -41
- package/dist/files/useFileUpload.js.map +1 -1
- package/dist/files/utils.js +14 -10
- package/dist/files/utils.js.map +1 -1
- package/dist/files/validation.js +7 -8
- package/dist/files/validation.js.map +1 -1
- package/dist/focus/useFocusContainer.js +1 -1
- package/dist/focus/useFocusContainer.js.map +1 -1
- package/dist/focus/utils.js +12 -7
- package/dist/focus/utils.js.map +1 -1
- package/dist/form/InputToggleIcon.js +5 -1
- package/dist/form/InputToggleIcon.js.map +1 -1
- package/dist/form/NativeSelect.js +1 -1
- package/dist/form/NativeSelect.js.map +1 -1
- package/dist/form/Select.js +5 -5
- package/dist/form/Select.js.map +1 -1
- package/dist/form/formConfig.js +1 -1
- package/dist/form/formConfig.js.map +1 -1
- package/dist/form/inputToggleStyles.js +7 -1
- package/dist/form/inputToggleStyles.js.map +1 -1
- package/dist/form/selectUtils.js +2 -2
- package/dist/form/selectUtils.js.map +1 -1
- package/dist/form/useCombobox.js +1 -0
- package/dist/form/useCombobox.js.map +1 -1
- package/dist/form/useFormReset.js +2 -2
- package/dist/form/useFormReset.js.map +1 -1
- package/dist/form/useNumberField.js +1 -1
- package/dist/form/useNumberField.js.map +1 -1
- package/dist/form/useResizingTextArea.js +4 -4
- package/dist/form/useResizingTextArea.js.map +1 -1
- package/dist/form/useSelectCombobox.js +1 -1
- package/dist/form/useSelectCombobox.js.map +1 -1
- package/dist/form/validation.js +1 -1
- package/dist/form/validation.js.map +1 -1
- package/dist/hoverMode/useHoverMode.js +8 -8
- package/dist/hoverMode/useHoverMode.js.map +1 -1
- package/dist/hoverMode/useHoverModeProvider.js +3 -3
- package/dist/hoverMode/useHoverModeProvider.js.map +1 -1
- package/dist/icon/config.js +3 -3
- package/dist/icon/config.js.map +1 -1
- package/dist/icon/materialConfig.js +1 -1
- package/dist/icon/materialConfig.js.map +1 -1
- package/dist/interaction/UserInteractionModeProvider.js +11 -10
- package/dist/interaction/UserInteractionModeProvider.js.map +1 -1
- package/dist/interaction/utils.js +7 -3
- package/dist/interaction/utils.js.map +1 -1
- package/dist/layout/useExpandableLayout.js +3 -4
- package/dist/layout/useExpandableLayout.js.map +1 -1
- package/dist/layout/useMainTabIndex.js +1 -1
- package/dist/layout/useMainTabIndex.js.map +1 -1
- package/dist/list/ListItem.js +1 -1
- package/dist/list/ListItem.js.map +1 -1
- package/dist/media-queries/AppSizeProvider.js +1 -1
- package/dist/media-queries/AppSizeProvider.js.map +1 -1
- package/dist/media-queries/config.js +2 -2
- package/dist/media-queries/config.js.map +1 -1
- package/dist/media-queries/useMediaQuery.js +3 -3
- package/dist/media-queries/useMediaQuery.js.map +1 -1
- package/dist/menu/Menu.js +4 -4
- package/dist/menu/Menu.js.map +1 -1
- package/dist/menu/MenuItemButton.js +1 -1
- package/dist/menu/MenuItemButton.js.map +1 -1
- package/dist/menu/MenuItemFileInput.js +1 -1
- package/dist/menu/MenuItemFileInput.js.map +1 -1
- package/dist/menu/MenuWidget.js +2 -2
- package/dist/menu/MenuWidget.js.map +1 -1
- package/dist/movement/findMatchIndex.js +2 -2
- package/dist/movement/findMatchIndex.js.map +1 -1
- package/dist/movement/useKeyboardMovementProvider.js +2 -2
- package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
- package/dist/movement/utils.js +12 -10
- package/dist/movement/utils.js.map +1 -1
- package/dist/navigation/getTableOfContentsHeadings.js +4 -3
- package/dist/navigation/getTableOfContentsHeadings.js.map +1 -1
- package/dist/navigation/useActiveHeadingId.js +9 -9
- package/dist/navigation/useActiveHeadingId.js.map +1 -1
- package/dist/navigation/useTableOfContentsHeadings.js +1 -1
- package/dist/navigation/useTableOfContentsHeadings.js.map +1 -1
- package/dist/navigation/utils.js +6 -5
- package/dist/navigation/utils.js.map +1 -1
- package/dist/portal/PortalContainerProvider.js +5 -3
- package/dist/portal/PortalContainerProvider.js.map +1 -1
- package/dist/positioning/getFixedPosition.js +2 -4
- package/dist/positioning/getFixedPosition.js.map +1 -1
- package/dist/positioning/useFixedPositioning.js +2 -2
- package/dist/positioning/useFixedPositioning.js.map +1 -1
- package/dist/positioning/utils.js +3 -3
- package/dist/positioning/utils.js.map +1 -1
- package/dist/scroll/getScrollbarWidth.js +4 -4
- package/dist/scroll/getScrollbarWidth.js.map +1 -1
- package/dist/searching/fuzzy.js +3 -2
- package/dist/searching/fuzzy.js.map +1 -1
- package/dist/searching/toSearchQuery.js +1 -1
- package/dist/searching/toSearchQuery.js.map +1 -1
- package/dist/searching/utils.js +1 -1
- package/dist/searching/utils.js.map +1 -1
- package/dist/snackbar/Toast.js +1 -1
- package/dist/snackbar/Toast.js.map +1 -1
- package/dist/snackbar/ToastContent.js +2 -2
- package/dist/snackbar/ToastContent.js.map +1 -1
- package/dist/snackbar/ToastManager.d.ts +1 -1
- package/dist/snackbar/ToastManager.js +11 -11
- package/dist/snackbar/ToastManager.js.map +1 -1
- package/dist/spinbutton/useSpinButton.js +1 -1
- package/dist/spinbutton/useSpinButton.js.map +1 -1
- package/dist/spinbutton/utils/deselectNode.js +1 -1
- package/dist/spinbutton/utils/deselectNode.js.map +1 -1
- package/dist/spinbutton/utils/resolveInputEvent.js +1 -1
- package/dist/spinbutton/utils/resolveInputEvent.js.map +1 -1
- package/dist/spinbutton/utils/selectNode.js +1 -1
- package/dist/spinbutton/utils/selectNode.js.map +1 -1
- package/dist/storage/useStorage.js +8 -3
- package/dist/storage/useStorage.js.map +1 -1
- package/dist/table/useStickyTableSection.js +1 -1
- package/dist/table/useStickyTableSection.js.map +1 -1
- package/dist/tabs/TabList.js +2 -2
- package/dist/tabs/TabList.js.map +1 -1
- package/dist/tabs/useMaxTabPanelHeight.js +4 -3
- package/dist/tabs/useMaxTabPanelHeight.js.map +1 -1
- package/dist/tabs/useTabList.js +1 -1
- package/dist/tabs/useTabList.js.map +1 -1
- package/dist/test-utils/jest-globals/match-media.d.ts +1 -1
- package/dist/test-utils/jest-globals/match-media.js +1 -1
- package/dist/test-utils/jest-globals/match-media.js.map +1 -1
- package/dist/test-utils/jest-globals/timers.js +1 -1
- package/dist/test-utils/jest-globals/timers.js.map +1 -1
- package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js +1 -1
- package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js.map +1 -1
- package/dist/test-utils/mocks/ResizeObserver.js +2 -2
- package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
- package/dist/test-utils/polyfills/IntersectionObserver.js +2 -2
- package/dist/test-utils/polyfills/IntersectionObserver.js.map +1 -1
- package/dist/test-utils/polyfills/ResizeObserver.js +2 -2
- package/dist/test-utils/polyfills/ResizeObserver.js.map +1 -1
- package/dist/test-utils/polyfills/TextDecoder.js +2 -2
- package/dist/test-utils/polyfills/TextDecoder.js.map +1 -1
- package/dist/test-utils/polyfills/TextEncoder.js +2 -2
- package/dist/test-utils/polyfills/TextEncoder.js.map +1 -1
- package/dist/test-utils/polyfills/matchMedia.js +2 -2
- package/dist/test-utils/polyfills/matchMedia.js.map +1 -1
- package/dist/test-utils/polyfills/offsetParent.js +2 -2
- package/dist/test-utils/polyfills/offsetParent.js.map +1 -1
- package/dist/test-utils/polyfills/scrollIntoView.js +1 -1
- package/dist/test-utils/polyfills/scrollIntoView.js.map +1 -1
- package/dist/test-utils/queries/select.js +2 -2
- package/dist/test-utils/queries/select.js.map +1 -1
- package/dist/test-utils/queries/slider.js +1 -1
- package/dist/test-utils/queries/slider.js.map +1 -1
- package/dist/test-utils/utils/createFileList.js +2 -0
- package/dist/test-utils/utils/createFileList.js.map +1 -1
- package/dist/test-utils/utils/createMatchMediaSpy.d.ts +1 -1
- package/dist/test-utils/utils/createMatchMediaSpy.js +3 -3
- package/dist/test-utils/utils/createMatchMediaSpy.js.map +1 -1
- package/dist/test-utils/vitest/match-media.d.ts +1 -1
- package/dist/test-utils/vitest/match-media.js +1 -1
- package/dist/test-utils/vitest/match-media.js.map +1 -1
- package/dist/test-utils/vitest/timers.js +1 -1
- package/dist/test-utils/vitest/timers.js.map +1 -1
- package/dist/test-utils/vitest/uploadMenuItemFileInput.js +1 -1
- package/dist/test-utils/vitest/uploadMenuItemFileInput.js.map +1 -1
- package/dist/theme/ThemeProvider.js +2 -2
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/getDerivedTheme.js +1 -1
- package/dist/theme/getDerivedTheme.js.map +1 -1
- package/dist/theme/useCSSVariables.js +5 -5
- package/dist/theme/useCSSVariables.js.map +1 -1
- package/dist/theme/useColorSchemeMetaTag.js +2 -2
- package/dist/theme/useColorSchemeMetaTag.js.map +1 -1
- package/dist/theme/useInlineCSSVariables.js +4 -3
- package/dist/theme/useInlineCSSVariables.js.map +1 -1
- package/dist/theme/utils.js +8 -8
- package/dist/theme/utils.js.map +1 -1
- package/dist/tooltip/useTooltip.js +7 -7
- package/dist/tooltip/useTooltip.js.map +1 -1
- package/dist/tooltip/useTooltipPosition.js +1 -1
- package/dist/tooltip/useTooltipPosition.js.map +1 -1
- package/dist/transition/useCarousel.js +2 -2
- package/dist/transition/useCarousel.js.map +1 -1
- package/dist/transition/useCollapseTransition.js +1 -1
- package/dist/transition/useCollapseTransition.js.map +1 -1
- package/dist/transition/useSkeletonPlaceholder.js +4 -4
- package/dist/transition/useSkeletonPlaceholder.js.map +1 -1
- package/dist/transition/useTransition.js +2 -2
- package/dist/transition/useTransition.js.map +1 -1
- package/dist/transition/utils.js +5 -5
- package/dist/transition/utils.js.map +1 -1
- package/dist/tree/TreeItem.js +1 -1
- package/dist/tree/TreeItem.js.map +1 -1
- package/dist/tree/useTreeItems.js +7 -5
- package/dist/tree/useTreeItems.js.map +1 -1
- package/dist/tree/useTreeMovement.js +1 -1
- package/dist/tree/useTreeMovement.js.map +1 -1
- package/dist/tree/utils.js +6 -9
- package/dist/tree/utils.js.map +1 -1
- package/dist/typography/HighlightText.js +2 -1
- package/dist/typography/HighlightText.js.map +1 -1
- package/dist/typography/SrOnly.js +7 -1
- package/dist/typography/SrOnly.js.map +1 -1
- package/dist/useDebouncedFunction.js +4 -4
- package/dist/useDebouncedFunction.js.map +1 -1
- package/dist/useDropzone.js +9 -9
- package/dist/useDropzone.js.map +1 -1
- package/dist/useEnsuredState.js +5 -5
- package/dist/useEnsuredState.js.map +1 -1
- package/dist/useIntersectionObserver.js +3 -3
- package/dist/useIntersectionObserver.js.map +1 -1
- package/dist/useIsomorphicLayoutEffect.js +1 -1
- package/dist/useIsomorphicLayoutEffect.js.map +1 -1
- package/dist/useOrientation.js +1 -1
- package/dist/useOrientation.js.map +1 -1
- package/dist/useReadonlySet.js +1 -1
- package/dist/useReadonlySet.js.map +1 -1
- package/dist/useResizeListener.js +2 -2
- package/dist/useResizeListener.js.map +1 -1
- package/dist/useResizeObserver.js +3 -4
- package/dist/useResizeObserver.js.map +1 -1
- package/dist/useThrottledFunction.js +3 -3
- package/dist/useThrottledFunction.js.map +1 -1
- package/dist/useWindowSize.js +1 -1
- package/dist/useWindowSize.js.map +1 -1
- package/dist/utils/alphaNumericSort.js +3 -1
- package/dist/utils/alphaNumericSort.js.map +1 -1
- package/dist/utils/bem.js +9 -12
- package/dist/utils/bem.js.map +1 -1
- package/dist/utils/getNumberOfDigits.js +1 -0
- package/dist/utils/getNumberOfDigits.js.map +1 -1
- package/dist/utils/getRangeDefaultValue.js +1 -1
- package/dist/utils/getRangeDefaultValue.js.map +1 -1
- package/dist/utils/nearest.js +2 -2
- package/dist/utils/nearest.js.map +1 -1
- package/dist/utils/parseCssLengthUnit.js +3 -3
- package/dist/utils/parseCssLengthUnit.js.map +1 -1
- package/dist/utils/trigonometry.js +1 -1
- package/dist/utils/trigonometry.js.map +1 -1
- package/package.json +3 -1
- package/src/autocomplete/AutocompleteChip.tsx +2 -2
- package/src/autocomplete/AutocompleteListboxChildren.tsx +1 -1
- package/src/autocomplete/useAutocomplete.ts +4 -4
- package/src/autocomplete/utils.ts +3 -3
- package/src/box/styles.ts +2 -2
- package/src/button/AsyncButton.tsx +1 -3
- package/src/chip/Chip.tsx +1 -2
- package/src/cssUtils.ts +12 -6
- package/src/datetime/useTimeField.ts +1 -1
- package/src/delegateEvent.ts +9 -9
- package/src/draggable/useDraggable.ts +4 -4
- package/src/draggable/utils.ts +1 -1
- package/src/expansion-panel/ExpansionPanel.tsx +1 -1
- package/src/expansion-panel/useExpansionPanels.ts +1 -1
- package/src/files/FileInput.tsx +1 -1
- package/src/files/createAcceptFromExtensions.ts +18 -0
- package/src/files/useFileUpload.ts +36 -37
- package/src/files/utils.ts +15 -11
- package/src/files/validation.ts +7 -9
- package/src/focus/useFocusContainer.ts +1 -1
- package/src/focus/utils.ts +11 -6
- package/src/form/InputToggleIcon.tsx +5 -5
- package/src/form/NativeSelect.tsx +1 -1
- package/src/form/Select.tsx +5 -5
- package/src/form/formConfig.ts +1 -1
- package/src/form/inputToggleStyles.ts +9 -4
- package/src/form/selectUtils.ts +2 -2
- package/src/form/useCombobox.ts +1 -0
- package/src/form/useFormReset.ts +2 -2
- package/src/form/useNumberField.ts +1 -1
- package/src/form/useResizingTextArea.ts +5 -5
- package/src/form/useSelectCombobox.ts +1 -4
- package/src/form/validation.ts +1 -1
- package/src/hoverMode/useHoverMode.ts +9 -9
- package/src/hoverMode/useHoverModeProvider.ts +4 -4
- package/src/icon/config.tsx +3 -3
- package/src/icon/materialConfig.ts +1 -1
- package/src/interaction/UserInteractionModeProvider.tsx +11 -10
- package/src/interaction/utils.ts +3 -3
- package/src/layout/useExpandableLayout.ts +3 -4
- package/src/layout/useMainTabIndex.ts +1 -1
- package/src/list/ListItem.tsx +1 -1
- package/src/media-queries/AppSizeProvider.tsx +1 -1
- package/src/media-queries/config.ts +2 -2
- package/src/media-queries/useMediaQuery.ts +3 -3
- package/src/menu/Menu.tsx +4 -4
- package/src/menu/MenuItemButton.tsx +1 -1
- package/src/menu/MenuItemFileInput.tsx +1 -1
- package/src/menu/MenuWidget.tsx +6 -4
- package/src/movement/findMatchIndex.ts +2 -2
- package/src/movement/useKeyboardMovementProvider.ts +2 -2
- package/src/movement/utils.ts +15 -14
- package/src/navigation/getTableOfContentsHeadings.ts +4 -3
- package/src/navigation/useActiveHeadingId.ts +8 -8
- package/src/navigation/useTableOfContentsHeadings.ts +1 -1
- package/src/navigation/utils.ts +6 -5
- package/src/portal/PortalContainerProvider.tsx +5 -3
- package/src/positioning/getFixedPosition.ts +9 -6
- package/src/positioning/useFixedPositioning.ts +2 -2
- package/src/positioning/utils.ts +3 -3
- package/src/scroll/getScrollbarWidth.ts +4 -4
- package/src/searching/fuzzy.ts +7 -3
- package/src/searching/toSearchQuery.ts +1 -1
- package/src/searching/utils.ts +1 -1
- package/src/snackbar/Toast.tsx +1 -1
- package/src/snackbar/ToastContent.tsx +2 -2
- package/src/snackbar/ToastManager.ts +11 -12
- package/src/spinbutton/useSpinButton.ts +1 -1
- package/src/spinbutton/utils/deselectNode.ts +1 -1
- package/src/spinbutton/utils/resolveInputEvent.ts +1 -1
- package/src/spinbutton/utils/selectNode.ts +1 -1
- package/src/storage/useStorage.ts +7 -2
- package/src/table/useStickyTableSection.tsx +1 -1
- package/src/tabs/TabList.tsx +2 -2
- package/src/tabs/useMaxTabPanelHeight.ts +6 -3
- package/src/tabs/useTabList.ts +2 -2
- package/src/test-utils/jest-globals/match-media.ts +5 -2
- package/src/test-utils/jest-globals/timers.ts +1 -1
- package/src/test-utils/jest-globals/uploadMenuItemFileInput.ts +1 -1
- package/src/test-utils/mocks/ResizeObserver.ts +2 -2
- package/src/test-utils/polyfills/IntersectionObserver.ts +2 -2
- package/src/test-utils/polyfills/ResizeObserver.ts +2 -2
- package/src/test-utils/polyfills/TextDecoder.ts +2 -2
- package/src/test-utils/polyfills/TextEncoder.ts +2 -2
- package/src/test-utils/polyfills/matchMedia.ts +5 -2
- package/src/test-utils/polyfills/offsetParent.ts +2 -2
- package/src/test-utils/polyfills/scrollIntoView.ts +1 -1
- package/src/test-utils/queries/select.ts +2 -2
- package/src/test-utils/queries/slider.ts +1 -1
- package/src/test-utils/utils/createFileList.ts +2 -0
- package/src/test-utils/utils/createMatchMediaSpy.ts +4 -4
- package/src/test-utils/vitest/match-media.ts +2 -2
- package/src/test-utils/vitest/timers.ts +1 -1
- package/src/test-utils/vitest/uploadMenuItemFileInput.ts +1 -1
- package/src/theme/ThemeProvider.tsx +2 -2
- package/src/theme/getDerivedTheme.ts +1 -1
- package/src/theme/useCSSVariables.ts +5 -5
- package/src/theme/useColorSchemeMetaTag.ts +2 -2
- package/src/theme/useInlineCSSVariables.ts +6 -7
- package/src/theme/utils.ts +8 -8
- package/src/tooltip/useTooltip.ts +7 -7
- package/src/tooltip/useTooltipPosition.ts +1 -1
- package/src/transition/useCarousel.ts +2 -2
- package/src/transition/useCollapseTransition.ts +1 -1
- package/src/transition/useSkeletonPlaceholder.ts +4 -4
- package/src/transition/useTransition.ts +2 -2
- package/src/transition/utils.ts +5 -5
- package/src/tree/TreeItem.tsx +1 -1
- package/src/tree/useTreeItems.ts +5 -5
- package/src/tree/useTreeMovement.ts +1 -1
- package/src/tree/utils.ts +9 -9
- package/src/typography/HighlightText.tsx +4 -3
- package/src/typography/SrOnly.tsx +9 -2
- package/src/useDebouncedFunction.ts +5 -5
- package/src/useDropzone.ts +10 -10
- package/src/useEnsuredState.ts +5 -5
- package/src/useIntersectionObserver.ts +3 -3
- package/src/useIsomorphicLayoutEffect.ts +3 -3
- package/src/useOrientation.ts +1 -1
- package/src/useReadonlySet.ts +3 -1
- package/src/useResizeListener.ts +2 -2
- package/src/useResizeObserver.ts +3 -4
- package/src/useThrottledFunction.ts +4 -4
- package/src/useWindowSize.ts +1 -1
- package/src/utils/alphaNumericSort.ts +1 -1
- package/src/utils/bem.ts +15 -16
- package/src/utils/getNumberOfDigits.ts +1 -0
- package/src/utils/getRangeDefaultValue.ts +1 -1
- package/src/utils/nearest.ts +5 -2
- package/src/utils/parseCssLengthUnit.ts +5 -4
- package/src/utils/trigonometry.ts +1 -1
- package/dist/form/defaultGetSelectedOptionChildren.d.ts +0 -1
- package/dist/form/getSelectedOptionChildren.d.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/movement/utils.ts"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\n\nimport { loop } from \"../utils/loop.js\";\nimport { type FocusableIndexOptions, type TabIndexBehavior } from \"./types.js\";\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport const isElementDisabled = (element: HTMLElement): boolean =>\n element.getAttribute(\"disabled\") !== null ||\n element.getAttribute(\"aria-disabled\") === \"true\";\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const isNotFocusable = (\n element: HTMLElement | undefined,\n includeDisabled: boolean\n): boolean => {\n if (!element) {\n return true;\n }\n\n if (includeDisabled) {\n return false;\n }\n\n return isElementDisabled(element);\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface VirtualFocusableIndexOptions {\n focusables: readonly HTMLElement[];\n includeDisabled: boolean;\n activeDescendantId: string;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport const getVirtualFocusDefaultIndex = (\n options: VirtualFocusableIndexOptions\n): number => {\n const { focusables, includeDisabled, activeDescendantId } = options;\n if (!focusables.length || (!activeDescendantId && includeDisabled)) {\n return 0;\n }\n\n const activeIndex = focusables.findIndex((element) => {\n if (activeDescendantId) {\n return element.id === activeDescendantId;\n }\n\n return !isElementDisabled(element);\n });\n return Math.max(0, activeIndex);\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getFirstFocusableIndex = (\n options: FocusableIndexOptions\n): number => {\n const { focusables, includeDisabled } = options;\n\n if (!focusables.length) {\n return -1;\n }\n\n let firstIndex = 0;\n while (\n firstIndex < focusables.length - 1 &&\n isNotFocusable(focusables[firstIndex], includeDisabled)\n ) {\n firstIndex += 1;\n }\n\n if (isNotFocusable(focusables[firstIndex], includeDisabled)) {\n return -1;\n }\n\n return firstIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getLastFocusableIndex = (\n options: FocusableIndexOptions\n): number => {\n const { focusables, includeDisabled } = options;\n\n if (!focusables.length) {\n return -1;\n }\n\n let lastIndex = focusables.length - 1;\n while (\n lastIndex > 0 &&\n isNotFocusable(focusables[lastIndex], includeDisabled)\n ) {\n lastIndex -= 1;\n }\n\n if (isNotFocusable(focusables[lastIndex], includeDisabled)) {\n return -1;\n }\n\n return lastIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\ninterface NextFocusableIndexOptions extends FocusableIndexOptions {\n loopable: boolean;\n increment: boolean;\n currentFocusIndex: number;\n}\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getNextFocusableIndex = (\n options: NextFocusableIndexOptions\n): number => {\n const {\n loopable,\n increment,\n focusables,\n includeDisabled,\n currentFocusIndex,\n } = options;\n if (!focusables.length) {\n return currentFocusIndex;\n }\n\n const min = getFirstFocusableIndex({ focusables, includeDisabled });\n const max = getLastFocusableIndex({ focusables, includeDisabled });\n let nextIndex = loop({\n min,\n max,\n value: currentFocusIndex,\n minmax: !loopable,\n increment,\n });\n while (\n isNotFocusable(focusables[nextIndex], includeDisabled) &&\n (loopable || nextIndex !== (increment ? max : min))\n ) {\n nextIndex = loop({\n min,\n max,\n value: nextIndex,\n minmax: !loopable,\n increment,\n });\n }\n\n // Since the `min` and `max` values are \"safely\" set, I don't need to verify\n // the nextIndex is still focusable\n return nextIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport function getSearchText(\n element: HTMLElement,\n searchable: boolean\n): string {\n if (!searchable) {\n return \"\";\n }\n\n const cloned = element.cloneNode(true) as HTMLElement;\n cloned\n .querySelectorAll(\n // Note: do not include DISPLAY_NONE_CLASS since it is presentational only\n \".rmd-icon--font,[aria-hidden=true],[hidden],[role=presentation]\"\n )\n .forEach((element) => {\n element.parentNode?.removeChild(element);\n });\n\n // Note: It would be good to use `cloned.innerText` (maybe?) at some point,\n // but it returns `undefined` in jsdom. It also does cause a reflow, so maybe\n // this is fine?\n // https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext\n return (cloned.textContent || \"\")[0].toUpperCase();\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface RecalculateOptions {\n focusables: readonly HTMLElement[];\n includeDisabled: boolean;\n tabIndexBehavior: TabIndexBehavior | undefined;\n activeDescendantId: string;\n}\n\n/**\n * This was added to help with specific widgets that cause focus index to change\n * between renders (i.e. expanding all tree items on the same level with `*`).\n * There might be a better way to handle this in the future.\n *\n * @since 6.0.0\n * @internal\n */\nexport function recalculateFocusIndex(options: RecalculateOptions): number {\n const { focusables, includeDisabled, tabIndexBehavior, activeDescendantId } =\n options;\n if (tabIndexBehavior === \"virtual\") {\n return getVirtualFocusDefaultIndex({\n focusables,\n includeDisabled,\n activeDescendantId,\n });\n }\n\n const { activeElement } = document;\n return focusables.findIndex((element) => element === activeElement);\n}\n\n/**\n * Checks if a keyboard event can trigger a search through focusable elements\n * by:\n *\n * - checking if the key is a single letter that is not the space key\n * - checking that the alt, ctrl, and meta keys are not being held\n *\n * The shift key **is allowed** because holding shift means \"search from the\n * beginning\" instead of \"search from current location\".\n *\n * @since 6.0.0\n * @internal\n */\nexport function isSearchableEvent(event: KeyboardEvent): boolean {\n const { key, altKey, ctrlKey, metaKey } = event;\n\n return (\n key.length === 1 &&\n // can't search with space since it is generally a click event\n key !== \" \" &&\n !altKey &&\n !ctrlKey &&\n !metaKey\n );\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport function isTypeEvent(event: KeyboardEvent): boolean {\n return (\n isSearchableEvent(event) || [\"Backspace\", \"Delete\", \" \"].includes(event.key)\n );\n}\n"],"names":["loop","isElementDisabled","element","getAttribute","isNotFocusable","includeDisabled","getVirtualFocusDefaultIndex","options","focusables","activeDescendantId","length","activeIndex","findIndex","id","Math","max","getFirstFocusableIndex","firstIndex","getLastFocusableIndex","lastIndex","getNextFocusableIndex","loopable","increment","currentFocusIndex","min","nextIndex","value","minmax","getSearchText","searchable","cloned","cloneNode","querySelectorAll","forEach","parentNode","removeChild","textContent","toUpperCase","recalculateFocusIndex","tabIndexBehavior","activeElement","document","isSearchableEvent","event","key","altKey","ctrlKey","metaKey","isTypeEvent","includes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/movement/utils.ts"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\n\nimport { loop } from \"../utils/loop.js\";\nimport { type FocusableIndexOptions, type TabIndexBehavior } from \"./types.js\";\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport const isElementDisabled = (element: HTMLElement): boolean =>\n element.getAttribute(\"disabled\") !== null ||\n element.getAttribute(\"aria-disabled\") === \"true\";\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const isNotFocusable = (\n element: HTMLElement | undefined,\n includeDisabled: boolean\n): boolean => {\n if (!element) {\n return true;\n }\n\n if (includeDisabled) {\n return false;\n }\n\n return isElementDisabled(element);\n};\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface VirtualFocusableIndexOptions {\n focusables: readonly HTMLElement[];\n includeDisabled: boolean;\n activeDescendantId: string;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport const getVirtualFocusDefaultIndex = (\n options: VirtualFocusableIndexOptions\n): number => {\n const { focusables, includeDisabled, activeDescendantId } = options;\n if (focusables.length === 0 || (!activeDescendantId && includeDisabled)) {\n return 0;\n }\n\n const activeIndex = focusables.findIndex((element) => {\n if (activeDescendantId) {\n return element.id === activeDescendantId;\n }\n\n return !isElementDisabled(element);\n });\n return Math.max(0, activeIndex);\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getFirstFocusableIndex = (\n options: FocusableIndexOptions\n): number => {\n const { focusables, includeDisabled } = options;\n\n if (focusables.length === 0) {\n return -1;\n }\n\n let firstIndex = 0;\n while (\n firstIndex < focusables.length - 1 &&\n isNotFocusable(focusables[firstIndex], includeDisabled)\n ) {\n firstIndex += 1;\n }\n\n if (isNotFocusable(focusables[firstIndex], includeDisabled)) {\n return -1;\n }\n\n return firstIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getLastFocusableIndex = (\n options: FocusableIndexOptions\n): number => {\n const { focusables, includeDisabled } = options;\n\n if (focusables.length === 0) {\n return -1;\n }\n\n let lastIndex = focusables.length - 1;\n while (\n lastIndex > 0 &&\n isNotFocusable(focusables[lastIndex], includeDisabled)\n ) {\n lastIndex -= 1;\n }\n\n if (isNotFocusable(focusables[lastIndex], includeDisabled)) {\n return -1;\n }\n\n return lastIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\ninterface NextFocusableIndexOptions extends FocusableIndexOptions {\n loopable: boolean;\n increment: boolean;\n currentFocusIndex: number;\n}\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport const getNextFocusableIndex = (\n options: NextFocusableIndexOptions\n): number => {\n const {\n loopable,\n increment,\n focusables,\n includeDisabled,\n currentFocusIndex,\n } = options;\n if (focusables.length === 0) {\n return currentFocusIndex;\n }\n\n const min = getFirstFocusableIndex({ focusables, includeDisabled });\n const max = getLastFocusableIndex({ focusables, includeDisabled });\n let nextIndex = loop({\n min,\n max,\n value: currentFocusIndex,\n minmax: !loopable,\n increment,\n });\n while (\n isNotFocusable(focusables[nextIndex], includeDisabled) &&\n (loopable || nextIndex !== (increment ? max : min))\n ) {\n nextIndex = loop({\n min,\n max,\n value: nextIndex,\n minmax: !loopable,\n increment,\n });\n }\n\n // Since the `min` and `max` values are \"safely\" set, I don't need to verify\n // the nextIndex is still focusable\n return nextIndex;\n};\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport function getSearchText(\n element: HTMLElement,\n searchable: boolean\n): string {\n if (!searchable) {\n return \"\";\n }\n\n const cloned = element.cloneNode(true) as HTMLElement;\n\n const invisibleElements = cloned.querySelectorAll(\n // Note: do not include DISPLAY_NONE_CLASS since it is presentational only\n \".rmd-icon--font,[aria-hidden=true],[hidden],[role=presentation]\"\n );\n for (const element of invisibleElements) {\n element.remove();\n }\n\n // Note: It would be good to use `cloned.innerText` (maybe?) at some point,\n // but it returns `undefined` in jsdom. It also does cause a reflow, so maybe\n // this is fine?\n // https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext\n return (cloned.textContent || \"\")[0].toUpperCase();\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface RecalculateOptions {\n focusables: readonly HTMLElement[];\n includeDisabled: boolean;\n tabIndexBehavior: TabIndexBehavior | undefined;\n activeDescendantId: string;\n}\n\n/**\n * This was added to help with specific widgets that cause focus index to change\n * between renders (i.e. expanding all tree items on the same level with `*`).\n * There might be a better way to handle this in the future.\n *\n * @since 6.0.0\n * @internal\n */\nexport function recalculateFocusIndex(options: RecalculateOptions): number {\n const { focusables, includeDisabled, tabIndexBehavior, activeDescendantId } =\n options;\n if (tabIndexBehavior === \"virtual\") {\n return getVirtualFocusDefaultIndex({\n focusables,\n includeDisabled,\n activeDescendantId,\n });\n }\n\n // do type-casting since the types don't matter much here\n const activeElement = document.activeElement as HTMLElement;\n return focusables.indexOf(activeElement);\n}\n\n/**\n * Checks if a keyboard event can trigger a search through focusable elements\n * by:\n *\n * - checking if the key is a single letter that is not the space key\n * - checking that the alt, ctrl, and meta keys are not being held\n *\n * The shift key **is allowed** because holding shift means \"search from the\n * beginning\" instead of \"search from current location\".\n *\n * @since 6.0.0\n * @internal\n */\nexport function isSearchableEvent(event: KeyboardEvent): boolean {\n const { key, altKey, ctrlKey, metaKey } = event;\n\n return (\n key.length === 1 &&\n // can't search with space since it is generally a click event\n key !== \" \" &&\n !altKey &&\n !ctrlKey &&\n !metaKey\n );\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport function isTypeEvent(event: KeyboardEvent): boolean {\n return (\n isSearchableEvent(event) || [\"Backspace\", \"Delete\", \" \"].includes(event.key)\n );\n}\n"],"names":["loop","isElementDisabled","element","getAttribute","isNotFocusable","includeDisabled","getVirtualFocusDefaultIndex","options","focusables","activeDescendantId","length","activeIndex","findIndex","id","Math","max","getFirstFocusableIndex","firstIndex","getLastFocusableIndex","lastIndex","getNextFocusableIndex","loopable","increment","currentFocusIndex","min","nextIndex","value","minmax","getSearchText","searchable","cloned","cloneNode","invisibleElements","querySelectorAll","remove","textContent","toUpperCase","recalculateFocusIndex","tabIndexBehavior","activeElement","document","indexOf","isSearchableEvent","event","key","altKey","ctrlKey","metaKey","isTypeEvent","includes"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @since 6.0.0
|
|
11
11
|
*/ export function getTableOfContentsHeadings(options) {
|
|
12
12
|
const { ssr, selector, getDepth, getHeadingText } = options;
|
|
13
|
-
if (ssr ||
|
|
13
|
+
if (ssr || globalThis.window === undefined) {
|
|
14
14
|
return [];
|
|
15
15
|
}
|
|
16
16
|
const root = {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
let previous = root;
|
|
23
23
|
const parents = [];
|
|
24
24
|
const headings = document.querySelectorAll(selector);
|
|
25
|
-
|
|
25
|
+
for (const heading of headings){
|
|
26
26
|
const depth = getDepth(heading);
|
|
27
27
|
const item = {
|
|
28
28
|
id: heading.id,
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
}
|
|
37
37
|
parents.push(previous);
|
|
38
38
|
} else if (depth < previous.depth) {
|
|
39
|
+
// eslint-disable-next-line unicorn/prefer-at
|
|
39
40
|
while(parents[parents.length - 1].depth >= depth){
|
|
40
41
|
parents.pop();
|
|
41
42
|
}
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
item
|
|
47
48
|
];
|
|
48
49
|
previous = item;
|
|
49
|
-
}
|
|
50
|
+
}
|
|
50
51
|
return root.items;
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/navigation/getTableOfContentsHeadings.ts"],"sourcesContent":["import {\n type TableOfContentsHeadingItem,\n type TableOfContentsHeadings,\n type TableOfContentsHeadingsOptions,\n} from \"./types.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface GetTableOfContentsHeadingsOptions extends Required<TableOfContentsHeadingsOptions> {\n ssr: boolean;\n}\n\n/**\n * This is used by the `useTableOfContentsHeadings` hook to find\n * the active heading element which is why it is marked as\n * internal.\n *\n * This will always return an empty list if `ssr` is `true` or\n * `typeof window === \"undefined\"`.\n *\n * @internal\n * @since 6.0.0\n */\nexport function getTableOfContentsHeadings(\n options: GetTableOfContentsHeadingsOptions\n): TableOfContentsHeadings {\n const { ssr, selector, getDepth, getHeadingText } = options;\n\n if (ssr ||
|
|
1
|
+
{"version":3,"sources":["../../src/navigation/getTableOfContentsHeadings.ts"],"sourcesContent":["import {\n type TableOfContentsHeadingItem,\n type TableOfContentsHeadings,\n type TableOfContentsHeadingsOptions,\n} from \"./types.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport interface GetTableOfContentsHeadingsOptions extends Required<TableOfContentsHeadingsOptions> {\n ssr: boolean;\n}\n\n/**\n * This is used by the `useTableOfContentsHeadings` hook to find\n * the active heading element which is why it is marked as\n * internal.\n *\n * This will always return an empty list if `ssr` is `true` or\n * `typeof window === \"undefined\"`.\n *\n * @internal\n * @since 6.0.0\n */\nexport function getTableOfContentsHeadings(\n options: GetTableOfContentsHeadingsOptions\n): TableOfContentsHeadings {\n const { ssr, selector, getDepth, getHeadingText } = options;\n\n if (ssr || globalThis.window === undefined) {\n return [];\n }\n\n const root = {\n id: \"\",\n depth: 0,\n items: [],\n children: \"\",\n } satisfies TableOfContentsHeadingItem;\n let previous: TableOfContentsHeadingItem = root;\n const parents: TableOfContentsHeadingItem[] = [];\n const headings = document.querySelectorAll(selector);\n for (const heading of headings) {\n const depth = getDepth(heading);\n const item: TableOfContentsHeadingItem = {\n id: heading.id,\n depth,\n items: [],\n children: getHeadingText(heading),\n };\n if (depth > previous.depth) {\n if (!previous.items) {\n previous.items = [];\n }\n\n parents.push(previous);\n } else if (depth < previous.depth) {\n // eslint-disable-next-line unicorn/prefer-at\n while (parents[parents.length - 1].depth >= depth) {\n parents.pop();\n }\n }\n const i = parents.length - 1;\n parents[i].items = [...(parents[i].items ?? []), item];\n previous = item;\n }\n\n return root.items;\n}\n"],"names":["getTableOfContentsHeadings","options","ssr","selector","getDepth","getHeadingText","globalThis","window","undefined","root","id","depth","items","children","previous","parents","headings","document","querySelectorAll","heading","item","push","length","pop","i"],"mappings":"AAcA;;;;;;;;;;CAUC,GACD,OAAO,SAASA,2BACdC,OAA0C;IAE1C,MAAM,EAAEC,GAAG,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,cAAc,EAAE,GAAGJ;IAEpD,IAAIC,OAAOI,WAAWC,MAAM,KAAKC,WAAW;QAC1C,OAAO,EAAE;IACX;IAEA,MAAMC,OAAO;QACXC,IAAI;QACJC,OAAO;QACPC,OAAO,EAAE;QACTC,UAAU;IACZ;IACA,IAAIC,WAAuCL;IAC3C,MAAMM,UAAwC,EAAE;IAChD,MAAMC,WAAWC,SAASC,gBAAgB,CAACf;IAC3C,KAAK,MAAMgB,WAAWH,SAAU;QAC9B,MAAML,QAAQP,SAASe;QACvB,MAAMC,OAAmC;YACvCV,IAAIS,QAAQT,EAAE;YACdC;YACAC,OAAO,EAAE;YACTC,UAAUR,eAAec;QAC3B;QACA,IAAIR,QAAQG,SAASH,KAAK,EAAE;YAC1B,IAAI,CAACG,SAASF,KAAK,EAAE;gBACnBE,SAASF,KAAK,GAAG,EAAE;YACrB;YAEAG,QAAQM,IAAI,CAACP;QACf,OAAO,IAAIH,QAAQG,SAASH,KAAK,EAAE;YACjC,6CAA6C;YAC7C,MAAOI,OAAO,CAACA,QAAQO,MAAM,GAAG,EAAE,CAACX,KAAK,IAAIA,MAAO;gBACjDI,QAAQQ,GAAG;YACb;QACF;QACA,MAAMC,IAAIT,QAAQO,MAAM,GAAG;QAC3BP,OAAO,CAACS,EAAE,CAACZ,KAAK,GAAG;eAAKG,OAAO,CAACS,EAAE,CAACZ,KAAK,IAAI,EAAE;YAAGQ;SAAK;QACtDN,WAAWM;IACb;IAEA,OAAOX,KAAKG,KAAK;AACnB"}
|
|
@@ -6,8 +6,8 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
6
6
|
* @defaultValue `[0.0, 1.0]`
|
|
7
7
|
* @since 6.0.0
|
|
8
8
|
*/ export const DEFAULT_ACTIVE_HEADING_THRESHOLD = [
|
|
9
|
-
0
|
|
10
|
-
1
|
|
9
|
+
0,
|
|
10
|
+
1
|
|
11
11
|
];
|
|
12
12
|
/**
|
|
13
13
|
* ```tsx
|
|
@@ -22,7 +22,7 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
22
22
|
* ```
|
|
23
23
|
* @since 6.0.0
|
|
24
24
|
*/ export const DEFAULT_ACTIVE_HEADING_GET_ROOT_MARGIN = ()=>{
|
|
25
|
-
const headerHeightVar =
|
|
25
|
+
const headerHeightVar = globalThis.getComputedStyle(document.documentElement).getPropertyValue("--rmd-layout-header-height");
|
|
26
26
|
const headerHeight = parseCssLengthUnit({
|
|
27
27
|
value: headerHeightVar || "3.5rem"
|
|
28
28
|
});
|
|
@@ -33,7 +33,7 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
33
33
|
* @since 6.0.0
|
|
34
34
|
*/ function getHeadingElements(items) {
|
|
35
35
|
const headings = [];
|
|
36
|
-
|
|
36
|
+
for (const item of items){
|
|
37
37
|
const heading = document.getElementById(item.id);
|
|
38
38
|
if (heading) {
|
|
39
39
|
headings.push(heading);
|
|
@@ -41,7 +41,7 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
41
41
|
if (item.items) {
|
|
42
42
|
headings.push(...getHeadingElements(item.items));
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
return headings;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
@@ -78,9 +78,9 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
78
78
|
getTargets: useCallback(()=>{
|
|
79
79
|
const headingElements = getHeadingElements(headings);
|
|
80
80
|
const lookup = new Map();
|
|
81
|
-
|
|
81
|
+
for (const heading of headingElements){
|
|
82
82
|
lookup.set(heading.id, false);
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
84
|
elements.current = lookup;
|
|
85
85
|
return headingElements;
|
|
86
86
|
}, [
|
|
@@ -91,9 +91,9 @@ import { parseCssLengthUnit } from "../utils/parseCssLengthUnit.js";
|
|
|
91
91
|
if (!lookup) {
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
for (const entry of entries){
|
|
95
95
|
lookup.set(entry.target.id, entry.isIntersecting);
|
|
96
|
-
}
|
|
96
|
+
}
|
|
97
97
|
// get the first visible/intersecting item and set it
|
|
98
98
|
let foundId = [
|
|
99
99
|
...lookup.entries()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/navigation/useActiveHeadingId.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\n\nimport { type UseStateInitializer } from \"../types.js\";\nimport {\n type IntersectionObserverRootMargin,\n type IntersectionObserverThreshold,\n useIntersectionObserver,\n} from \"../useIntersectionObserver.js\";\nimport { parseCssLengthUnit } from \"../utils/parseCssLengthUnit.js\";\nimport { type HeadingReferenceWithChildren } from \"./types.js\";\n\n/**\n * @defaultValue `[0.0, 1.0]`\n * @since 6.0.0\n */\nexport const DEFAULT_ACTIVE_HEADING_THRESHOLD: IntersectionObserverThreshold = [\n 0
|
|
1
|
+
{"version":3,"sources":["../../src/navigation/useActiveHeadingId.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\n\nimport { type UseStateInitializer } from \"../types.js\";\nimport {\n type IntersectionObserverRootMargin,\n type IntersectionObserverThreshold,\n useIntersectionObserver,\n} from \"../useIntersectionObserver.js\";\nimport { parseCssLengthUnit } from \"../utils/parseCssLengthUnit.js\";\nimport { type HeadingReferenceWithChildren } from \"./types.js\";\n\n/**\n * @defaultValue `[0.0, 1.0]`\n * @since 6.0.0\n */\nexport const DEFAULT_ACTIVE_HEADING_THRESHOLD: IntersectionObserverThreshold = [\n 0, 1,\n];\n\n/**\n * ```tsx\n * const headerHeightVar = window\n * .getComputedStyle(document.documentElement)\n * .getPropertyValue(\"--rmd-layout-header-height\");\n * const headerHeight = parseCssLengthUnit({\n * value: headerHeightVar || \"3.5rem\",\n * });\n\n * return `-${headerHeight}px 0px 0px 0px`;\n * ```\n * @since 6.0.0\n */\nexport const DEFAULT_ACTIVE_HEADING_GET_ROOT_MARGIN = (): string => {\n const headerHeightVar = globalThis\n .getComputedStyle(document.documentElement)\n .getPropertyValue(\"--rmd-layout-header-height\");\n const headerHeight = parseCssLengthUnit({\n value: headerHeightVar || \"3.5rem\",\n });\n\n return `-${headerHeight}px 0px 0px 0px`;\n};\n\n/**\n * @internal\n * @since 6.0.0\n */\nfunction getHeadingElements(\n items: readonly HeadingReferenceWithChildren[]\n): readonly HTMLElement[] {\n const headings: HTMLElement[] = [];\n for (const item of items) {\n const heading = document.getElementById(item.id);\n if (heading) {\n headings.push(heading);\n }\n\n if (item.items) {\n headings.push(...getHeadingElements(item.items));\n }\n }\n\n return headings;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nfunction getLastHeadingId(\n items: readonly HeadingReferenceWithChildren[]\n): string {\n const last = items.at(-1);\n if (!last) {\n return \"\";\n }\n\n if (last.items) {\n return getLastHeadingId(last.items);\n }\n\n return last.id;\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nconst isScrolledNearPageBottom = (threshold: number): boolean =>\n window.scrollY >= document.documentElement.scrollHeight * threshold;\n\n/**\n * @since 6.0.0\n */\nexport interface ActiveHeadingIdOptions {\n headings: readonly HeadingReferenceWithChildren[];\n\n /** @see {@link DEFAULT_ACTIVE_HEADING_THRESHOLD} */\n threshold?: IntersectionObserverThreshold;\n\n /** @see {@link DEFAULT_ACTIVE_HEADING_GET_ROOT_MARGIN} */\n getRootMargin?: () => IntersectionObserverRootMargin;\n\n /** @defaultValue `headings[0]?.id ?? \"\"` */\n defaultActiveId?: UseStateInitializer<string>;\n\n /** @defaultValue `0.8` */\n scrollBottomThreshold?: number;\n}\n\n/**\n * This is heavily inspired by:\n * @see https://github.com/mdn/yari/blob/231d6aab8f1c8efe159d268c261446c5b7ae12d9/client/src/document/hooks.ts#L171\n *\n * @see {@link https://react-md.dev/hooks/use-active-heading-id | useActiveHeadingId Demos}\n * @since 6.0.0\n */\nexport function useActiveHeadingId(options: ActiveHeadingIdOptions): string {\n const {\n headings,\n threshold = DEFAULT_ACTIVE_HEADING_THRESHOLD,\n getRootMargin = DEFAULT_ACTIVE_HEADING_GET_ROOT_MARGIN,\n defaultActiveId = headings[0]?.id ?? \"\",\n scrollBottomThreshold = 0.8,\n } = options;\n const elements = useRef<Map<string, boolean>>();\n const isFirstRender = useRef(true);\n const [activeHeadingId, setActiveHeadingId] = useState(defaultActiveId);\n useIntersectionObserver({\n threshold,\n getRootMargin,\n getTargets: useCallback(() => {\n const headingElements = getHeadingElements(headings);\n const lookup = new Map<string, boolean>();\n for (const heading of headingElements) {\n lookup.set(heading.id, false);\n }\n elements.current = lookup;\n\n return headingElements;\n }, [headings]),\n onUpdate: useCallback(\n (entries) => {\n const lookup = elements.current;\n if (!lookup) {\n return;\n }\n\n for (const entry of entries) {\n lookup.set(entry.target.id, entry.isIntersecting);\n }\n\n // get the first visible/intersecting item and set it\n let foundId = [...lookup.entries()].find(\n ([_id, isIntersecting]) => isIntersecting\n )?.[0];\n if (\n !foundId &&\n isFirstRender.current &&\n isScrolledNearPageBottom(scrollBottomThreshold)\n ) {\n foundId = getLastHeadingId(headings);\n }\n\n isFirstRender.current = false;\n\n // if there isn't a found id, it might be a really large section where\n // another heading isn't visible, so maintain the previous one\n if (foundId) {\n setActiveHeadingId(foundId);\n }\n },\n [headings, scrollBottomThreshold]\n ),\n });\n\n return activeHeadingId;\n}\n"],"names":["useCallback","useRef","useState","useIntersectionObserver","parseCssLengthUnit","DEFAULT_ACTIVE_HEADING_THRESHOLD","DEFAULT_ACTIVE_HEADING_GET_ROOT_MARGIN","headerHeightVar","globalThis","getComputedStyle","document","documentElement","getPropertyValue","headerHeight","value","getHeadingElements","items","headings","item","heading","getElementById","id","push","getLastHeadingId","last","at","isScrolledNearPageBottom","threshold","window","scrollY","scrollHeight","useActiveHeadingId","options","getRootMargin","defaultActiveId","scrollBottomThreshold","elements","isFirstRender","activeHeadingId","setActiveHeadingId","getTargets","headingElements","lookup","Map","set","current","onUpdate","entries","entry","target","isIntersecting","foundId","find","_id"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ import { getTableOfContentsHeadings } from "./getTableOfContentsHeadings.js";
|
|
|
14
14
|
*
|
|
15
15
|
* @since 6.0.0
|
|
16
16
|
*/ export const DEFAULT_GET_HEADING_DEPTH = (element)=>{
|
|
17
|
-
const depth = parseInt(element.tagName.
|
|
17
|
+
const depth = Number.parseInt(element.tagName.slice(1));
|
|
18
18
|
return Number.isNaN(depth) ? 0 : depth;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/navigation/useTableOfContentsHeadings.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { getTableOfContentsHeadings } from \"./getTableOfContentsHeadings.js\";\nimport {\n type TableOfContentsHeadings,\n type TableOfContentsHeadingsOptions,\n} from \"./types.js\";\n\n/**\n * This will find all headings that have an `id` that are not part of a `<nav>`\n * element since that should normally be a table of contents component.\n *\n * @since 6.0.0\n */\nexport const DEFAULT_HEADING_SELECTOR =\n \"main :where(:not(nav *)):where(h1[id],h2[id],h3[id],h4[id],h5[id],h6[id])\";\n\n/**\n * This only works for heading elements since it is pretty much:\n * `return parseInt(element.tagName.substring(1))`\n *\n * @since 6.0.0\n */\nexport const DEFAULT_GET_HEADING_DEPTH = (element: Element): number => {\n const depth = parseInt(element.tagName.
|
|
1
|
+
{"version":3,"sources":["../../src/navigation/useTableOfContentsHeadings.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { getTableOfContentsHeadings } from \"./getTableOfContentsHeadings.js\";\nimport {\n type TableOfContentsHeadings,\n type TableOfContentsHeadingsOptions,\n} from \"./types.js\";\n\n/**\n * This will find all headings that have an `id` that are not part of a `<nav>`\n * element since that should normally be a table of contents component.\n *\n * @since 6.0.0\n */\nexport const DEFAULT_HEADING_SELECTOR =\n \"main :where(:not(nav *)):where(h1[id],h2[id],h3[id],h4[id],h5[id],h6[id])\";\n\n/**\n * This only works for heading elements since it is pretty much:\n * `return parseInt(element.tagName.substring(1))`\n *\n * @since 6.0.0\n */\nexport const DEFAULT_GET_HEADING_DEPTH = (element: Element): number => {\n const depth = Number.parseInt(element.tagName.slice(1));\n return Number.isNaN(depth) ? 0 : depth;\n};\n\n/**\n * @since 6.0.0\n */\nexport const DEFAULT_GET_HEADING_TEXT = (element: Element): string =>\n element.textContent || \"\";\n\n/**\n * The `useTableOfContentsHeadings` should normally be used with the\n * `useActiveHeadingId` hook to generate a table of contents for the current\n * page.\n *\n * @example Example Usage\n * ```tsx\n * import { useActiveHeadingId } from \"@react-md/core/navigation/useActiveHeadingId\";\n * import { useTableOfContentsHeadings } from \"@react-md/core/navigation/useTableOfContentsHeadings\";\n *\n * function Example() {\n * const headings = useTableOfContentsHeadings();\n * const activeHeadingId = useActiveHeadingId({ headings });\n *\n * return <TableOfContents headings={headings} activeHeadingId={activeHeadingId} />;\n * }\n * ```\n *\n * @see {@link https://react-md.dev/hooks/use-table-of-contents-headings | useTableOfContentsHeadings Demos}\n * @since 6.0.0\n */\nexport function useTableOfContentsHeadings(\n options: TableOfContentsHeadingsOptions = {}\n): TableOfContentsHeadings {\n const {\n selector = DEFAULT_HEADING_SELECTOR,\n getDepth = DEFAULT_GET_HEADING_DEPTH,\n getHeadingText = DEFAULT_GET_HEADING_TEXT,\n } = options;\n const ssr = useSsr();\n const [headings, setHeadings] = useState(() =>\n getTableOfContentsHeadings({\n ssr,\n selector,\n getDepth,\n getHeadingText,\n })\n );\n useEffect(() => {\n setHeadings(\n getTableOfContentsHeadings({ ssr, selector, getDepth, getHeadingText })\n );\n }, [getDepth, getHeadingText, selector, ssr]);\n\n return headings;\n}\n"],"names":["useEffect","useState","useSsr","getTableOfContentsHeadings","DEFAULT_HEADING_SELECTOR","DEFAULT_GET_HEADING_DEPTH","element","depth","Number","parseInt","tagName","slice","isNaN","DEFAULT_GET_HEADING_TEXT","textContent","useTableOfContentsHeadings","options","selector","getDepth","getHeadingText","ssr","headings","setHeadings"],"mappings":"AAAA;AAEA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAE5C,SAASC,MAAM,QAAQ,oBAAoB;AAC3C,SAASC,0BAA0B,QAAQ,kCAAkC;AAM7E;;;;;CAKC,GACD,OAAO,MAAMC,2BACX,4EAA4E;AAE9E;;;;;CAKC,GACD,OAAO,MAAMC,4BAA4B,CAACC;IACxC,MAAMC,QAAQC,OAAOC,QAAQ,CAACH,QAAQI,OAAO,CAACC,KAAK,CAAC;IACpD,OAAOH,OAAOI,KAAK,CAACL,SAAS,IAAIA;AACnC,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMM,2BAA2B,CAACP,UACvCA,QAAQQ,WAAW,IAAI,GAAG;AAE5B;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,SAASC,2BACdC,UAA0C,CAAC,CAAC;IAE5C,MAAM,EACJC,WAAWb,wBAAwB,EACnCc,WAAWb,yBAAyB,EACpCc,iBAAiBN,wBAAwB,EAC1C,GAAGG;IACJ,MAAMI,MAAMlB;IACZ,MAAM,CAACmB,UAAUC,YAAY,GAAGrB,SAAS,IACvCE,2BAA2B;YACzBiB;YACAH;YACAC;YACAC;QACF;IAEFnB,UAAU;QACRsB,YACEnB,2BAA2B;YAAEiB;YAAKH;YAAUC;YAAUC;QAAe;IAEzE,GAAG;QAACD;QAAUC;QAAgBF;QAAUG;KAAI;IAE5C,OAAOC;AACT"}
|
package/dist/navigation/utils.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 6.0.0
|
|
3
3
|
*/ export function getHrefFromParents(parents) {
|
|
4
|
-
|
|
4
|
+
let result = "";
|
|
5
|
+
for (const parent of parents){
|
|
5
6
|
if ("href" in parent && parent.href) {
|
|
6
7
|
const { href } = parent;
|
|
7
|
-
|
|
8
|
+
result += href;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
14
|
* @since 6.0.0
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
* @since 6.0.0
|
|
22
23
|
*/ export function getPartsFromPathname(pathname) {
|
|
23
24
|
// remove trailing slashes just in case there aren't rewrites in place
|
|
24
|
-
const href = pathname.
|
|
25
|
+
const href = pathname.replaceAll(/\/{2,}/g, "/").replace(/\/+$/, "");
|
|
25
26
|
const parts = href.split("/");
|
|
26
27
|
const set = new Set();
|
|
27
28
|
let prefix = "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/navigation/utils.ts"],"sourcesContent":["import { type NavigationItem } from \"./types.js\";\n\n/**\n * @since 6.0.0\n */\nexport function getHrefFromParents(parents: readonly NavigationItem[]): string {\n
|
|
1
|
+
{"version":3,"sources":["../../src/navigation/utils.ts"],"sourcesContent":["import { type NavigationItem } from \"./types.js\";\n\n/**\n * @since 6.0.0\n */\nexport function getHrefFromParents(parents: readonly NavigationItem[]): string {\n let result = \"\";\n for (const parent of parents) {\n if (\"href\" in parent && parent.href) {\n const { href } = parent;\n result += href;\n }\n }\n\n return result;\n}\n\n/**\n * @since 6.0.0\n */\nexport function getNavigationGroupId(\n group: NavigationItem,\n parents: readonly NavigationItem[]\n): string {\n if (\"id\" in group && typeof group.id === \"string\" && group.id) {\n return group.id;\n }\n\n return getHrefFromParents(parents);\n}\n\n/**\n * @since 6.0.0\n */\nexport function getPartsFromPathname(pathname: string): ReadonlySet<string> {\n // remove trailing slashes just in case there aren't rewrites in place\n const href = pathname.replaceAll(/\\/{2,}/g, \"/\").replace(/\\/+$/, \"\");\n const parts = href.split(\"/\");\n const set = new Set<string>();\n let prefix = \"\";\n for (const part of parts) {\n const slashed = `/${part}`;\n prefix = prefix === \"/\" ? slashed : prefix + slashed;\n set.add(prefix);\n }\n\n return set;\n}\n"],"names":["getHrefFromParents","parents","result","parent","href","getNavigationGroupId","group","id","getPartsFromPathname","pathname","replaceAll","replace","parts","split","set","Set","prefix","part","slashed","add"],"mappings":"AAEA;;CAEC,GACD,OAAO,SAASA,mBAAmBC,OAAkC;IACnE,IAAIC,SAAS;IACb,KAAK,MAAMC,UAAUF,QAAS;QAC5B,IAAI,UAAUE,UAAUA,OAAOC,IAAI,EAAE;YACnC,MAAM,EAAEA,IAAI,EAAE,GAAGD;YACjBD,UAAUE;QACZ;IACF;IAEA,OAAOF;AACT;AAEA;;CAEC,GACD,OAAO,SAASG,qBACdC,KAAqB,EACrBL,OAAkC;IAElC,IAAI,QAAQK,SAAS,OAAOA,MAAMC,EAAE,KAAK,YAAYD,MAAMC,EAAE,EAAE;QAC7D,OAAOD,MAAMC,EAAE;IACjB;IAEA,OAAOP,mBAAmBC;AAC5B;AAEA;;CAEC,GACD,OAAO,SAASO,qBAAqBC,QAAgB;IACnD,sEAAsE;IACtE,MAAML,OAAOK,SAASC,UAAU,CAAC,WAAW,KAAKC,OAAO,CAAC,QAAQ;IACjE,MAAMC,QAAQR,KAAKS,KAAK,CAAC;IACzB,MAAMC,MAAM,IAAIC;IAChB,IAAIC,SAAS;IACb,KAAK,MAAMC,QAAQL,MAAO;QACxB,MAAMM,UAAU,CAAC,CAAC,EAAED,MAAM;QAC1BD,SAASA,WAAW,MAAME,UAAUF,SAASE;QAC7CJ,IAAIK,GAAG,CAACH;IACV;IAEA,OAAOF;AACT"}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
4
4
|
export const PORTAL_CONTAINER_ID = "rmd-portal-container";
|
|
5
5
|
let portalContainer = null;
|
|
6
|
-
const getPortalContainer = ()=>
|
|
6
|
+
const getPortalContainer = ()=>globalThis.window === undefined ? null : document.body;
|
|
7
7
|
const context = /*#__PURE__*/ createContext(getPortalContainer());
|
|
8
8
|
context.displayName = "PortalContainer";
|
|
9
9
|
const { Provider } = context;
|
|
@@ -32,7 +32,7 @@ const { Provider } = context;
|
|
|
32
32
|
setValue(container.current);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
-
if (
|
|
35
|
+
if (container !== undefined) {
|
|
36
36
|
setValue(container);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -41,11 +41,13 @@ const { Provider } = context;
|
|
|
41
41
|
portalContainer.id = PORTAL_CONTAINER_ID;
|
|
42
42
|
}
|
|
43
43
|
if (!document.body.contains(portalContainer)) {
|
|
44
|
-
document.body.
|
|
44
|
+
document.body.append(portalContainer);
|
|
45
45
|
}
|
|
46
46
|
setValue(portalContainer);
|
|
47
47
|
return ()=>{
|
|
48
48
|
if (portalContainer && document.body.contains(portalContainer)) {
|
|
49
|
+
// can't use `portalContainer.remove()` since `DocumentFragment` does not have `.remove()`
|
|
50
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
49
51
|
document.body.removeChild(portalContainer);
|
|
50
52
|
}
|
|
51
53
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/portal/PortalContainerProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ReactElement,\n type ReactNode,\n type RefObject,\n createContext,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type PortalContainerNode = Element | DocumentFragment | null;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type PortalContainer =\n | PortalContainerNode\n | RefObject<PortalContainerNode>;\n\nexport const PORTAL_CONTAINER_ID = \"rmd-portal-container\";\n\nlet portalContainer: PortalContainerNode = null;\n\nconst getPortalContainer = (): PortalContainerNode =>\n
|
|
1
|
+
{"version":3,"sources":["../../src/portal/PortalContainerProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ReactElement,\n type ReactNode,\n type RefObject,\n createContext,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type PortalContainerNode = Element | DocumentFragment | null;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type PortalContainer =\n | PortalContainerNode\n | RefObject<PortalContainerNode>;\n\nexport const PORTAL_CONTAINER_ID = \"rmd-portal-container\";\n\nlet portalContainer: PortalContainerNode = null;\n\nconst getPortalContainer = (): PortalContainerNode =>\n globalThis.window === undefined ? null : document.body;\n\nconst context = createContext<PortalContainerNode>(getPortalContainer());\ncontext.displayName = \"PortalContainer\";\nconst { Provider } = context;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function usePortalContainer(): PortalContainerNode {\n return useContext(context);\n}\n\n/** @since 6.0.0 */\nexport interface PortalContainerProviderProps {\n /**\n * An optional container element to use. When this is `undefined`, a\n * `<div id=\"rmd-portal-container\"></div>` will be added as the last child to\n * the `document.body` and be used as the container element.\n */\n container?: PortalContainer;\n children: ReactNode;\n}\n\n/**\n * **Client Component**\n *\n * This component allows for all child `Portal` components to render within the\n * same container element. If a custom `container` element is not provided, a\n * `<div id=\"rmd-portal-container\"></div>` will be added as the last child to\n * the `document.body` and be used as the container element.\n *\n * @see {@link https://react-md.dev/components/portal | Portal Demos}\n * @see {@link Portal}\n * @since 6.0.0\n */\nexport function PortalContainerProvider(\n props: PortalContainerProviderProps\n): ReactElement {\n const { container, children } = props;\n const [value, setValue] = useState<PortalContainerNode>(portalContainer);\n useEffect(() => {\n if (container && \"current\" in container) {\n setValue(container.current);\n return;\n }\n\n if (container !== undefined) {\n setValue(container);\n return;\n }\n\n if (!portalContainer) {\n portalContainer = document.createElement(\"div\");\n portalContainer.id = PORTAL_CONTAINER_ID;\n }\n if (!document.body.contains(portalContainer)) {\n document.body.append(portalContainer);\n }\n\n setValue(portalContainer);\n\n return () => {\n if (portalContainer && document.body.contains(portalContainer)) {\n // can't use `portalContainer.remove()` since `DocumentFragment` does not have `.remove()`\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n document.body.removeChild(portalContainer);\n }\n };\n }, [container]);\n\n const containerValue =\n (container && \"current\" in container) || !container ? value : container;\n return <Provider value={containerValue}>{children}</Provider>;\n}\n"],"names":["createContext","useContext","useEffect","useState","PORTAL_CONTAINER_ID","portalContainer","getPortalContainer","globalThis","window","undefined","document","body","context","displayName","Provider","usePortalContainer","PortalContainerProvider","props","container","children","value","setValue","current","createElement","id","contains","append","removeChild","containerValue"],"mappings":"AAAA;;AAEA,SAIEA,aAAa,EACbC,UAAU,EACVC,SAAS,EACTC,QAAQ,QACH,QAAQ;AAgBf,OAAO,MAAMC,sBAAsB,uBAAuB;AAE1D,IAAIC,kBAAuC;AAE3C,MAAMC,qBAAqB,IACzBC,WAAWC,MAAM,KAAKC,YAAY,OAAOC,SAASC,IAAI;AAExD,MAAMC,wBAAUZ,cAAmCM;AACnDM,QAAQC,WAAW,GAAG;AACtB,MAAM,EAAEC,QAAQ,EAAE,GAAGF;AAErB;;;CAGC,GACD,OAAO,SAASG;IACd,OAAOd,WAAWW;AACpB;AAaA;;;;;;;;;;;CAWC,GACD,OAAO,SAASI,wBACdC,KAAmC;IAEnC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGF;IAChC,MAAM,CAACG,OAAOC,SAAS,GAAGlB,SAA8BE;IACxDH,UAAU;QACR,IAAIgB,aAAa,aAAaA,WAAW;YACvCG,SAASH,UAAUI,OAAO;YAC1B;QACF;QAEA,IAAIJ,cAAcT,WAAW;YAC3BY,SAASH;YACT;QACF;QAEA,IAAI,CAACb,iBAAiB;YACpBA,kBAAkBK,SAASa,aAAa,CAAC;YACzClB,gBAAgBmB,EAAE,GAAGpB;QACvB;QACA,IAAI,CAACM,SAASC,IAAI,CAACc,QAAQ,CAACpB,kBAAkB;YAC5CK,SAASC,IAAI,CAACe,MAAM,CAACrB;QACvB;QAEAgB,SAAShB;QAET,OAAO;YACL,IAAIA,mBAAmBK,SAASC,IAAI,CAACc,QAAQ,CAACpB,kBAAkB;gBAC9D,0FAA0F;gBAC1F,0DAA0D;gBAC1DK,SAASC,IAAI,CAACgB,WAAW,CAACtB;YAC5B;QACF;IACF,GAAG;QAACa;KAAU;IAEd,MAAMU,iBACJ,AAACV,aAAa,aAAaA,aAAc,CAACA,YAAYE,QAAQF;IAChE,qBAAO,KAACJ;QAASM,OAAOQ;kBAAiBT;;AAC3C"}
|
|
@@ -57,10 +57,8 @@ import { findSizingContainer, getElementRect, getTransformOrigin } from "./utils
|
|
|
57
57
|
const { element, anchor = BELOW_CENTER_ANCHOR, initialX, vwMargin = 16, vhMargin = 16, xMargin = 0, yMargin = 0, width: widthType = "auto", preventOverlap = false, transformOrigin = false, disableSwapping = false, disableVHBounds = false } = options;
|
|
58
58
|
let { initialY } = options;
|
|
59
59
|
const container = findSizingContainer(options.container);
|
|
60
|
-
if (process.env.NODE_ENV !== "production") {
|
|
61
|
-
|
|
62
|
-
throw new Error('Unable to prevent overlap when the vertical anchor is not `"above"` or `"below"`');
|
|
63
|
-
}
|
|
60
|
+
if (process.env.NODE_ENV !== "production" && preventOverlap && anchor.y !== "above" && anchor.y !== "below") {
|
|
61
|
+
throw new Error('Unable to prevent overlap when the vertical anchor is not `"above"` or `"below"`');
|
|
64
62
|
}
|
|
65
63
|
if (!element) {
|
|
66
64
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/positioning/getFixedPosition.ts"],"sourcesContent":["import { getScrollbarWidth } from \"../scroll/getScrollbarWidth.js\";\nimport { BELOW_CENTER_ANCHOR } from \"./constants.js\";\nimport { createHorizontalPosition } from \"./createHorizontalPosition.js\";\nimport { createVerticalPosition } from \"./createVerticalPosition.js\";\nimport { type FixedPosition, type FixedPositionOptions } from \"./types.js\";\nimport {\n findSizingContainer,\n getElementRect,\n getTransformOrigin,\n} from \"./utils.js\";\n\n/**\n * This is used when there is no `container` element so that some styles can\n * still be created. The main use-case for this is context menus and when the\n * `initialX` and `initialY` options have been provided.\n *\n * @internal\n * @since 5.0.0\n */\nconst FALLBACK_DOM_RECT: DOMRect = {\n x: 0,\n y: 0,\n height: 0,\n width: 0,\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n toJSON() {\n // do nothing\n },\n};\n\n/**\n * One of the most complicated functions in this project that will attempt to\n * position an element relative to another container element while still being\n * visible within the viewport. Below is the logical flow for attempting to fix\n * the element to the container:\n *\n * No Container: If there is no container element, return the provided x and y\n * positions and no styles since there's nothing we can use to calculate the\n * position.\n *\n * No Element: If the container was provided but the element to position does\n * not exist, return an style object containing the `left` and `top` values for\n * the container and apply as many of the positioning options as possible so\n * that the styles are \"as close as possible\" before the fixed element is added\n * to the DOM. This will also return the provided x and y positions since\n * nothing could be swapped around yet.\n *\n * Container and Element: If both the container and fixed element were provided,\n * apply all the positioning options to the `left` and `top` values of the\n * container based on the sizes of both elements.\n *\n * Now that the `left` and `top` values were applied, check to see if the\n * element is fully visible within the viewport with the provided positioning\n * options. If it is fully visible, do nothing else. If it isn't... follow the\n * next flow:\n *\n * First, check the horizontal sizes and make sure that the element is still\n * within the viewport with the provided view width margin. If it isn't, first\n * try to swap only to a `right` style instead of left to see if that fixes it,\n * otherwise keep both the `left` and `right` styles.\n */\nexport function getFixedPosition(options: FixedPositionOptions): FixedPosition {\n const {\n element,\n anchor = BELOW_CENTER_ANCHOR,\n initialX,\n vwMargin = 16,\n vhMargin = 16,\n xMargin = 0,\n yMargin = 0,\n width: widthType = \"auto\",\n preventOverlap = false,\n transformOrigin = false,\n disableSwapping = false,\n disableVHBounds = false,\n } = options;\n let { initialY } = options;\n const container = findSizingContainer(options.container);\n\n if (process.env.NODE_ENV !== \"production\"
|
|
1
|
+
{"version":3,"sources":["../../src/positioning/getFixedPosition.ts"],"sourcesContent":["import { getScrollbarWidth } from \"../scroll/getScrollbarWidth.js\";\nimport { BELOW_CENTER_ANCHOR } from \"./constants.js\";\nimport { createHorizontalPosition } from \"./createHorizontalPosition.js\";\nimport { createVerticalPosition } from \"./createVerticalPosition.js\";\nimport { type FixedPosition, type FixedPositionOptions } from \"./types.js\";\nimport {\n findSizingContainer,\n getElementRect,\n getTransformOrigin,\n} from \"./utils.js\";\n\n/**\n * This is used when there is no `container` element so that some styles can\n * still be created. The main use-case for this is context menus and when the\n * `initialX` and `initialY` options have been provided.\n *\n * @internal\n * @since 5.0.0\n */\nconst FALLBACK_DOM_RECT: DOMRect = {\n x: 0,\n y: 0,\n height: 0,\n width: 0,\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n toJSON() {\n // do nothing\n },\n};\n\n/**\n * One of the most complicated functions in this project that will attempt to\n * position an element relative to another container element while still being\n * visible within the viewport. Below is the logical flow for attempting to fix\n * the element to the container:\n *\n * No Container: If there is no container element, return the provided x and y\n * positions and no styles since there's nothing we can use to calculate the\n * position.\n *\n * No Element: If the container was provided but the element to position does\n * not exist, return an style object containing the `left` and `top` values for\n * the container and apply as many of the positioning options as possible so\n * that the styles are \"as close as possible\" before the fixed element is added\n * to the DOM. This will also return the provided x and y positions since\n * nothing could be swapped around yet.\n *\n * Container and Element: If both the container and fixed element were provided,\n * apply all the positioning options to the `left` and `top` values of the\n * container based on the sizes of both elements.\n *\n * Now that the `left` and `top` values were applied, check to see if the\n * element is fully visible within the viewport with the provided positioning\n * options. If it is fully visible, do nothing else. If it isn't... follow the\n * next flow:\n *\n * First, check the horizontal sizes and make sure that the element is still\n * within the viewport with the provided view width margin. If it isn't, first\n * try to swap only to a `right` style instead of left to see if that fixes it,\n * otherwise keep both the `left` and `right` styles.\n */\nexport function getFixedPosition(options: FixedPositionOptions): FixedPosition {\n const {\n element,\n anchor = BELOW_CENTER_ANCHOR,\n initialX,\n vwMargin = 16,\n vhMargin = 16,\n xMargin = 0,\n yMargin = 0,\n width: widthType = \"auto\",\n preventOverlap = false,\n transformOrigin = false,\n disableSwapping = false,\n disableVHBounds = false,\n } = options;\n let { initialY } = options;\n const container = findSizingContainer(options.container);\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n preventOverlap &&\n anchor.y !== \"above\" &&\n anchor.y !== \"below\"\n ) {\n throw new Error(\n 'Unable to prevent overlap when the vertical anchor is not `\"above\"` or `\"below\"`'\n );\n }\n\n if (!element) {\n return {\n actualX: anchor.x,\n actualY: anchor.y,\n style: {\n left: initialX,\n top: initialY,\n position: disableVHBounds ? \"absolute\" : \"fixed\",\n transformOrigin: transformOrigin\n ? getTransformOrigin({ x: anchor.x, y: anchor.y })\n : undefined,\n },\n };\n }\n\n const containerRect = container?.getBoundingClientRect() ?? FALLBACK_DOM_RECT;\n const vh = window.innerHeight;\n const vw = window.innerWidth;\n\n const { minWidth: elMinWidth } = element.style;\n // Note: This makes it \"min-content\" or \"min-container-width\"\n if (widthType === \"min\") {\n element.style.overflow = \"visible\";\n element.style.minWidth = \"\";\n }\n const elementRect = getElementRect(element);\n const { height } = elementRect;\n let elWidth = elementRect.width;\n if (widthType === \"min\") {\n elWidth += getScrollbarWidth();\n element.style.overflow = \"\";\n element.style.minWidth = elMinWidth;\n }\n if (disableVHBounds) {\n const dialog = element.closest(\"[role='dialog']\");\n if (!dialog) {\n initialY = (initialY ?? 0) + window.scrollY;\n }\n }\n\n const { left, right, width, minWidth, actualX } = createHorizontalPosition({\n x: anchor.x,\n vw,\n vwMargin,\n xMargin,\n width: widthType,\n elWidth,\n initialX,\n containerRect,\n disableSwapping,\n });\n const { top, bottom, actualY, transformOriginY } = createVerticalPosition({\n y: anchor.y,\n vh,\n vhMargin,\n yMargin,\n initialY,\n elHeight: height,\n containerRect,\n disableSwapping,\n preventOverlap,\n disableVHBounds,\n });\n\n return {\n actualX,\n actualY,\n style: {\n left,\n top,\n right,\n bottom,\n width,\n minWidth,\n position: disableVHBounds ? \"absolute\" : \"fixed\",\n transformOrigin: transformOrigin\n ? getTransformOrigin({\n x: actualX,\n y: actualY,\n transformOriginY,\n })\n : undefined,\n },\n };\n}\n"],"names":["getScrollbarWidth","BELOW_CENTER_ANCHOR","createHorizontalPosition","createVerticalPosition","findSizingContainer","getElementRect","getTransformOrigin","FALLBACK_DOM_RECT","x","y","height","width","left","right","top","bottom","toJSON","getFixedPosition","options","element","anchor","initialX","vwMargin","vhMargin","xMargin","yMargin","widthType","preventOverlap","transformOrigin","disableSwapping","disableVHBounds","initialY","container","process","env","NODE_ENV","Error","actualX","actualY","style","position","undefined","containerRect","getBoundingClientRect","vh","window","innerHeight","vw","innerWidth","minWidth","elMinWidth","overflow","elementRect","elWidth","dialog","closest","scrollY","transformOriginY","elHeight"],"mappings":"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"}
|
|
@@ -186,8 +186,8 @@ const noop = ()=>undefined;
|
|
|
186
186
|
}
|
|
187
187
|
updateStyle();
|
|
188
188
|
};
|
|
189
|
-
const resizeHandler = delegateEvent("resize", window, true);
|
|
190
|
-
const scrollHandler = delegateEvent("scroll", window, true, {
|
|
189
|
+
const resizeHandler = delegateEvent("resize", globalThis.window, true);
|
|
190
|
+
const scrollHandler = delegateEvent("scroll", globalThis.window, true, {
|
|
191
191
|
passive: true
|
|
192
192
|
});
|
|
193
193
|
resizeHandler.add(resizeCallback);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/positioning/useFixedPositioning.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { delegateEvent } from \"../delegateEvent.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport { BELOW_CENTER_ANCHOR } from \"./constants.js\";\nimport { getFixedPosition } from \"./getFixedPosition.js\";\nimport {\n type CalculateFixedPositionOptions,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type FixedPositionStyle,\n} from \"./types.js\";\nimport { isWithinViewport } from \"./utils.js\";\n\nconst noop = (): undefined => undefined;\n\n/**\n * @since 4.0.0\n */\nexport type FixedPositioningTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEnter\" | \"onEntering\" | \"onEntered\" | \"onExited\"\n>;\n\n/**\n * This options should be passed to the {@link useCSSTransition} for the styling\n * and positioning to work correctly.\n *\n * @typeParam E - An HTMLElement type used for the ref required for the\n * transition.\n * @since 4.0.0\n */\nexport interface FixedPositioningTransitionOptions<\n E extends HTMLElement,\n> extends FixedPositioningTransitionCallbacks {\n /** {@inheritDoc TransitionOptions.nodeRef} */\n nodeRef?: Ref<E>;\n}\n\n/**\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport interface FixedPositioningScrollData<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n> {\n fixedElement: FixedElement;\n fixedToElement: FixedToElement;\n\n /**\n * Boolean if the {@link fixedToElement} is visible within the viewport.\n */\n visible: boolean;\n}\n\n/**\n * This function is called when the page is scrolled while the fixed element is\n * visible. This is generally used to reposition the fixed element or hide it if\n * it is no longer visible within the viewport.\n *\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @param event - The scroll event\n * @param data - The {@link FixedPositioningScrollData} that can be used for\n * custom scroll behavior.\n * @since 4.0.0\n */\nexport type TransitionScrollCallback<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n> = (\n event: Event,\n data: Readonly<FixedPositioningScrollData<FixedToElement, FixedElement>>\n) => void;\n\n/**\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport interface FixedPositioningOptions<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n>\n extends\n FixedPositioningTransitionOptions<FixedElement>,\n CalculateFixedPositionOptions {\n /**\n * An optional style that will be merged with the fixed positioning required\n * styles.\n *\n * @see {@link FixedPositionStyle}\n */\n style?: CSSProperties;\n\n /**\n * A ref pointing to an element that another element should be fixed to. This\n * **must** be provided for the positioning to work.\n */\n fixedTo: RefObject<FixedToElement>;\n\n /**\n * An optional function that can be used to override positioning options if\n * some options require the element to be in the DOM for specific\n * calculations.\n */\n getFixedPositionOptions?: () => CalculateFixedPositionOptions;\n\n /**\n * An optional function to call if the page resizes while the `FixedElement`\n * is visible.\n */\n onResize?: EventListener;\n /** @see {@link TransitionScrollCallback} */\n onScroll?: TransitionScrollCallback<FixedToElement, FixedElement>;\n\n /**\n * Set this to `true` to disable the fixed positioning behavior so it can be\n * customized within CSS or manually instead. This was added mostly to just\n * support rendering menus inline with other content (like autocompletes\n * within a dialog).\n *\n * @defaultValue `false`\n * @since 6.0.0\n */\n disabled?: boolean;\n}\n\n/**\n * @typeParam E - An HTMLElement type for the fixed element.\n * @since 4.0.0\n * @since 6.0.0 Renamed from `FixedPositioningHookReturnValue` to\n * `FixedPositioningImplementation` to match naming conventions.\n */\nexport interface FixedPositioningImplementation<E extends HTMLElement> {\n /**\n * A ref that should be passed to a component for the fixed positioning\n * behavior to work correctly.\n *\n * This should really only be used if the {@link TransitionOptions} is not\n * being used.\n */\n ref: RefCallback<E>;\n\n /**\n * This is the {@link FixedPositionStyle} merged with the\n * {@link FixedPositioningOptions.style}. This will only return `undefined`\n * when {@link FixedPositioningOptions.disabled} is `true` and no `style` was\n * provided.\n */\n style: CSSProperties | undefined;\n\n /**\n * This should really only be used if the {@link transitionOptions} is not\n * being used.\n */\n callbacks: Readonly<Required<FixedPositioningTransitionCallbacks>>;\n\n /**\n * A function that can be called to update the style for the fixed element.\n */\n updateStyle: () => void;\n\n /** {@inheritDoc FixedPositioningTransitionOptions} */\n transitionOptions: Readonly<Required<FixedPositioningTransitionOptions<E>>>;\n}\n\n/**\n * This hook is used to attach a temporary (fixed) element to another element\n * within the page. In other words, this is a way to have an element with\n * `position: fixed` as if it were `position: absolute` to a parent element that\n * had `position: relative`.\n *\n * @example Simple Example\n * ```tsx\n * \"use client\";\n *\n * import { Button } from \"@react-md/core/button/Button\";\n * import { useFixedPositioning } from \"@react-md/core/positioning/useFixedPositioning\";\n * import { useCSSTransition } from \"@react-md/core/transition/useCSSTransition\";\n * import { type ReactElement, useRef, useState } from \"react\";\n *\n * function Example(): ReactElement {\n * const fixedTo = useRef<HTMLButtonElement>(null);\n * const [transitionIn, setTransitionIn] = useState(false);\n * const { style, transitionOptions } = useFixedPositioning({\n * fixedTo,\n * });\n * const { elementProps, rendered } = useCSSTransition({\n * ...transitionOptions,\n * transitionIn,\n * temporary: true,\n * timeout: {\n * enter: 200,\n * exit: 150,\n * },\n * classNames: {\n * enter: \"enter\",\n * enterActive: \"enter--active\",\n * exit: \"exit\",\n * exitActive: \"exit--active\",\n * },\n * });\n *\n * return (\n * <>\n * <Button ref={fixedTo} onClick={() => setTransitionIn(!transitionIn)}>\n * Toggle\n * </Button>\n * {rendered && (\n * <div {...elementProps} style={style}>\n * Fixed Temporary Element\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/hooks/use-fixed-positioning | useFixedPositioning Demos}\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport function useFixedPositioning<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n>(\n options: FixedPositioningOptions<FixedToElement, FixedElement>\n): FixedPositioningImplementation<FixedElement> {\n const {\n style: propStyle,\n nodeRef,\n fixedTo,\n disabled,\n onEnter = noop,\n onEntering = noop,\n onEntered = noop,\n onExited = noop,\n anchor = BELOW_CENTER_ANCHOR,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions = noop,\n onScroll,\n onResize = noop,\n } = options;\n\n const [active, setActive] = useState(false);\n const [ref, refHandler] = useEnsuredRef(nodeRef);\n const optionsRef = useRef({\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n } as const);\n useIsomorphicLayoutEffect(() => {\n optionsRef.current = {\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n };\n }, [\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n ]);\n const [style, setStyle] = useState<CSSProperties | undefined>(\n () =>\n getFixedPosition({\n container: ref.current,\n element: fixedTo.current,\n anchor,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n ...getFixedPositionOptions(),\n }).style\n );\n\n const updateStyle = useCallback(() => {\n if (disabled) {\n return;\n }\n\n const {\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n } = optionsRef.current;\n const element = ref.current;\n const container = fixedTo.current;\n const { style } = getFixedPosition({\n container,\n element,\n anchor,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n ...getFixedPositionOptions(),\n });\n\n setStyle(style);\n setActive(!!element && !element.hidden);\n\n // Only changing the initialX, initialY, or disabled should cause the\n // useEffect below to trigger, which is why everything else is set in a ref.\n }, [disabled, initialX, initialY]);\n\n useEffect(() => {\n if (!active || disabled) {\n return;\n }\n\n const resizeCallback = (event: Event): void => {\n onResize(event);\n updateStyle();\n };\n const scrollCallback = (event: Event): void => {\n const fixedElement = ref.current;\n const fixedToElement = fixedTo.current;\n if (onScroll && fixedElement && fixedToElement) {\n onScroll(event, {\n visible: isWithinViewport({ fixedElement, fixedToElement }),\n fixedElement,\n fixedToElement,\n });\n }\n\n updateStyle();\n };\n\n const resizeHandler = delegateEvent(\"resize\", window, true);\n const scrollHandler = delegateEvent(\"scroll\", window, true, {\n passive: true,\n });\n resizeHandler.add(resizeCallback);\n scrollHandler.add(scrollCallback);\n return () => {\n resizeHandler.remove(resizeCallback);\n scrollHandler.remove(scrollCallback);\n };\n }, [active, disabled, fixedTo, onResize, onScroll, ref, updateStyle]);\n\n const callbacks: Required<FixedPositioningTransitionCallbacks> = {\n onEnter(appearing) {\n onEnter(appearing);\n updateStyle();\n },\n onEntering(appearing) {\n onEntering(appearing);\n updateStyle();\n },\n onEntered(appearing) {\n onEntered(appearing);\n updateStyle();\n },\n onExited() {\n onExited();\n setActive(false);\n },\n };\n\n return {\n ref: refHandler,\n style: disabled ? propStyle : { ...style, ...propStyle },\n callbacks,\n updateStyle,\n transitionOptions: {\n ...callbacks,\n nodeRef: refHandler,\n },\n };\n}\n"],"names":["useCallback","useEffect","useRef","useState","delegateEvent","useEnsuredRef","useIsomorphicLayoutEffect","BELOW_CENTER_ANCHOR","getFixedPosition","isWithinViewport","noop","undefined","useFixedPositioning","options","style","propStyle","nodeRef","fixedTo","disabled","onEnter","onEntering","onEntered","onExited","anchor","disableSwapping","disableVHBounds","initialX","initialY","preventOverlap","transformOrigin","vhMargin","vwMargin","width","xMargin","yMargin","getFixedPositionOptions","onScroll","onResize","active","setActive","ref","refHandler","optionsRef","current","setStyle","container","element","updateStyle","hidden","resizeCallback","event","scrollCallback","fixedElement","fixedToElement","visible","resizeHandler","window","scrollHandler","passive","add","remove","callbacks","appearing","transitionOptions"],"mappings":"AAAA;AAEA,SAKEA,WAAW,EACXC,SAAS,EACTC,MAAM,EACNC,QAAQ,QACH,QAAQ;AAEf,SAASC,aAAa,QAAQ,sBAAsB;AAEpD,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAASC,yBAAyB,QAAQ,kCAAkC;AAC5E,SAASC,mBAAmB,QAAQ,iBAAiB;AACrD,SAASC,gBAAgB,QAAQ,wBAAwB;AAMzD,SAASC,gBAAgB,QAAQ,aAAa;AAE9C,MAAMC,OAAO,IAAiBC;AA2J9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDC,GACD,OAAO,SAASC,oBAIdC,OAA8D;IAE9D,MAAM,EACJC,OAAOC,SAAS,EAChBC,OAAO,EACPC,OAAO,EACPC,QAAQ,EACRC,UAAUT,IAAI,EACdU,aAAaV,IAAI,EACjBW,YAAYX,IAAI,EAChBY,WAAWZ,IAAI,EACfa,SAAShB,mBAAmB,EAC5BiB,eAAe,EACfC,eAAe,EACfC,QAAQ,EACRC,QAAQ,EACRC,cAAc,EACdC,eAAe,EACfC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,0BAA0BzB,IAAI,EAC9B0B,QAAQ,EACRC,WAAW3B,IAAI,EAChB,GAAGG;IAEJ,MAAM,CAACyB,QAAQC,UAAU,GAAGpC,SAAS;IACrC,MAAM,CAACqC,KAAKC,WAAW,GAAGpC,cAAcW;IACxC,MAAM0B,aAAaxC,OAAO;QACxBsC;QACAvB;QACAM;QACAC;QACAC;QACAG;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;IACA7B,0BAA0B;QACxBoC,WAAWC,OAAO,GAAG;YACnBH;YACAvB;YACAM;YACAC;YACAC;YACAG;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;QACF;IACF,GAAG;QACDK;QACAvB;QACAM;QACAC;QACAC;QACAG;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;KACD;IACD,MAAM,CAACrB,OAAO8B,SAAS,GAAGzC,SACxB,IACEK,iBAAiB;YACfqC,WAAWL,IAAIG,OAAO;YACtBG,SAAS7B,QAAQ0B,OAAO;YACxBpB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACA,GAAGC,yBAAyB;QAC9B,GAAGrB,KAAK;IAGZ,MAAMiC,cAAc/C,YAAY;QAC9B,IAAIkB,UAAU;YACZ;QACF;QAEA,MAAM,EACJsB,GAAG,EACHvB,OAAO,EACPM,MAAM,EACNC,eAAe,EACfC,eAAe,EACfG,cAAc,EACdC,eAAe,EACfC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,uBAAuB,EACxB,GAAGO,WAAWC,OAAO;QACtB,MAAMG,UAAUN,IAAIG,OAAO;QAC3B,MAAME,YAAY5B,QAAQ0B,OAAO;QACjC,MAAM,EAAE7B,KAAK,EAAE,GAAGN,iBAAiB;YACjCqC;YACAC;YACAvB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACA,GAAGC,yBAAyB;QAC9B;QAEAS,SAAS9B;QACTyB,UAAU,CAAC,CAACO,WAAW,CAACA,QAAQE,MAAM;IAEtC,qEAAqE;IACrE,4EAA4E;IAC9E,GAAG;QAAC9B;QAAUQ;QAAUC;KAAS;IAEjC1B,UAAU;QACR,IAAI,CAACqC,UAAUpB,UAAU;YACvB;QACF;QAEA,MAAM+B,iBAAiB,CAACC;YACtBb,SAASa;YACTH;QACF;QACA,MAAMI,iBAAiB,CAACD;YACtB,MAAME,eAAeZ,IAAIG,OAAO;YAChC,MAAMU,iBAAiBpC,QAAQ0B,OAAO;YACtC,IAAIP,YAAYgB,gBAAgBC,gBAAgB;gBAC9CjB,SAASc,OAAO;oBACdI,SAAS7C,iBAAiB;wBAAE2C;wBAAcC;oBAAe;oBACzDD;oBACAC;gBACF;YACF;YAEAN;QACF;QAEA,MAAMQ,gBAAgBnD,cAAc,UAAUoD,QAAQ;QACtD,MAAMC,gBAAgBrD,cAAc,UAAUoD,QAAQ,MAAM;YAC1DE,SAAS;QACX;QACAH,cAAcI,GAAG,CAACV;QAClBQ,cAAcE,GAAG,CAACR;QAClB,OAAO;YACLI,cAAcK,MAAM,CAACX;YACrBQ,cAAcG,MAAM,CAACT;QACvB;IACF,GAAG;QAACb;QAAQpB;QAAUD;QAASoB;QAAUD;QAAUI;QAAKO;KAAY;IAEpE,MAAMc,YAA2D;QAC/D1C,SAAQ2C,SAAS;YACf3C,QAAQ2C;YACRf;QACF;QACA3B,YAAW0C,SAAS;YAClB1C,WAAW0C;YACXf;QACF;QACA1B,WAAUyC,SAAS;YACjBzC,UAAUyC;YACVf;QACF;QACAzB;YACEA;YACAiB,UAAU;QACZ;IACF;IAEA,OAAO;QACLC,KAAKC;QACL3B,OAAOI,WAAWH,YAAY;YAAE,GAAGD,KAAK;YAAE,GAAGC,SAAS;QAAC;QACvD8C;QACAd;QACAgB,mBAAmB;YACjB,GAAGF,SAAS;YACZ7C,SAASyB;QACX;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/positioning/useFixedPositioning.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { delegateEvent } from \"../delegateEvent.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport { BELOW_CENTER_ANCHOR } from \"./constants.js\";\nimport { getFixedPosition } from \"./getFixedPosition.js\";\nimport {\n type CalculateFixedPositionOptions,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type FixedPositionStyle,\n} from \"./types.js\";\nimport { isWithinViewport } from \"./utils.js\";\n\nconst noop = (): undefined => undefined;\n\n/**\n * @since 4.0.0\n */\nexport type FixedPositioningTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEnter\" | \"onEntering\" | \"onEntered\" | \"onExited\"\n>;\n\n/**\n * This options should be passed to the {@link useCSSTransition} for the styling\n * and positioning to work correctly.\n *\n * @typeParam E - An HTMLElement type used for the ref required for the\n * transition.\n * @since 4.0.0\n */\nexport interface FixedPositioningTransitionOptions<\n E extends HTMLElement,\n> extends FixedPositioningTransitionCallbacks {\n /** {@inheritDoc TransitionOptions.nodeRef} */\n nodeRef?: Ref<E>;\n}\n\n/**\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport interface FixedPositioningScrollData<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n> {\n fixedElement: FixedElement;\n fixedToElement: FixedToElement;\n\n /**\n * Boolean if the {@link fixedToElement} is visible within the viewport.\n */\n visible: boolean;\n}\n\n/**\n * This function is called when the page is scrolled while the fixed element is\n * visible. This is generally used to reposition the fixed element or hide it if\n * it is no longer visible within the viewport.\n *\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @param event - The scroll event\n * @param data - The {@link FixedPositioningScrollData} that can be used for\n * custom scroll behavior.\n * @since 4.0.0\n */\nexport type TransitionScrollCallback<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n> = (\n event: Event,\n data: Readonly<FixedPositioningScrollData<FixedToElement, FixedElement>>\n) => void;\n\n/**\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport interface FixedPositioningOptions<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n>\n extends\n FixedPositioningTransitionOptions<FixedElement>,\n CalculateFixedPositionOptions {\n /**\n * An optional style that will be merged with the fixed positioning required\n * styles.\n *\n * @see {@link FixedPositionStyle}\n */\n style?: CSSProperties;\n\n /**\n * A ref pointing to an element that another element should be fixed to. This\n * **must** be provided for the positioning to work.\n */\n fixedTo: RefObject<FixedToElement>;\n\n /**\n * An optional function that can be used to override positioning options if\n * some options require the element to be in the DOM for specific\n * calculations.\n */\n getFixedPositionOptions?: () => CalculateFixedPositionOptions;\n\n /**\n * An optional function to call if the page resizes while the `FixedElement`\n * is visible.\n */\n onResize?: EventListener;\n /** @see {@link TransitionScrollCallback} */\n onScroll?: TransitionScrollCallback<FixedToElement, FixedElement>;\n\n /**\n * Set this to `true` to disable the fixed positioning behavior so it can be\n * customized within CSS or manually instead. This was added mostly to just\n * support rendering menus inline with other content (like autocompletes\n * within a dialog).\n *\n * @defaultValue `false`\n * @since 6.0.0\n */\n disabled?: boolean;\n}\n\n/**\n * @typeParam E - An HTMLElement type for the fixed element.\n * @since 4.0.0\n * @since 6.0.0 Renamed from `FixedPositioningHookReturnValue` to\n * `FixedPositioningImplementation` to match naming conventions.\n */\nexport interface FixedPositioningImplementation<E extends HTMLElement> {\n /**\n * A ref that should be passed to a component for the fixed positioning\n * behavior to work correctly.\n *\n * This should really only be used if the {@link TransitionOptions} is not\n * being used.\n */\n ref: RefCallback<E>;\n\n /**\n * This is the {@link FixedPositionStyle} merged with the\n * {@link FixedPositioningOptions.style}. This will only return `undefined`\n * when {@link FixedPositioningOptions.disabled} is `true` and no `style` was\n * provided.\n */\n style: CSSProperties | undefined;\n\n /**\n * This should really only be used if the {@link transitionOptions} is not\n * being used.\n */\n callbacks: Readonly<Required<FixedPositioningTransitionCallbacks>>;\n\n /**\n * A function that can be called to update the style for the fixed element.\n */\n updateStyle: () => void;\n\n /** {@inheritDoc FixedPositioningTransitionOptions} */\n transitionOptions: Readonly<Required<FixedPositioningTransitionOptions<E>>>;\n}\n\n/**\n * This hook is used to attach a temporary (fixed) element to another element\n * within the page. In other words, this is a way to have an element with\n * `position: fixed` as if it were `position: absolute` to a parent element that\n * had `position: relative`.\n *\n * @example Simple Example\n * ```tsx\n * \"use client\";\n *\n * import { Button } from \"@react-md/core/button/Button\";\n * import { useFixedPositioning } from \"@react-md/core/positioning/useFixedPositioning\";\n * import { useCSSTransition } from \"@react-md/core/transition/useCSSTransition\";\n * import { type ReactElement, useRef, useState } from \"react\";\n *\n * function Example(): ReactElement {\n * const fixedTo = useRef<HTMLButtonElement>(null);\n * const [transitionIn, setTransitionIn] = useState(false);\n * const { style, transitionOptions } = useFixedPositioning({\n * fixedTo,\n * });\n * const { elementProps, rendered } = useCSSTransition({\n * ...transitionOptions,\n * transitionIn,\n * temporary: true,\n * timeout: {\n * enter: 200,\n * exit: 150,\n * },\n * classNames: {\n * enter: \"enter\",\n * enterActive: \"enter--active\",\n * exit: \"exit\",\n * exitActive: \"exit--active\",\n * },\n * });\n *\n * return (\n * <>\n * <Button ref={fixedTo} onClick={() => setTransitionIn(!transitionIn)}>\n * Toggle\n * </Button>\n * {rendered && (\n * <div {...elementProps} style={style}>\n * Fixed Temporary Element\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/hooks/use-fixed-positioning | useFixedPositioning Demos}\n * @typeParam FixedToElement - An HTMLElement type for the static element.\n * @typeParam FixedElement - An HTMLElement type for the fixed element.\n * @since 4.0.0\n */\nexport function useFixedPositioning<\n FixedToElement extends HTMLElement,\n FixedElement extends HTMLElement,\n>(\n options: FixedPositioningOptions<FixedToElement, FixedElement>\n): FixedPositioningImplementation<FixedElement> {\n const {\n style: propStyle,\n nodeRef,\n fixedTo,\n disabled,\n onEnter = noop,\n onEntering = noop,\n onEntered = noop,\n onExited = noop,\n anchor = BELOW_CENTER_ANCHOR,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions = noop,\n onScroll,\n onResize = noop,\n } = options;\n\n const [active, setActive] = useState(false);\n const [ref, refHandler] = useEnsuredRef(nodeRef);\n const optionsRef = useRef({\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n } as const);\n useIsomorphicLayoutEffect(() => {\n optionsRef.current = {\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n };\n }, [\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n ]);\n const [style, setStyle] = useState<CSSProperties | undefined>(\n () =>\n getFixedPosition({\n container: ref.current,\n element: fixedTo.current,\n anchor,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n ...getFixedPositionOptions(),\n }).style\n );\n\n const updateStyle = useCallback(() => {\n if (disabled) {\n return;\n }\n\n const {\n ref,\n fixedTo,\n anchor,\n disableSwapping,\n disableVHBounds,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n getFixedPositionOptions,\n } = optionsRef.current;\n const element = ref.current;\n const container = fixedTo.current;\n const { style } = getFixedPosition({\n container,\n element,\n anchor,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n preventOverlap,\n transformOrigin,\n vhMargin,\n vwMargin,\n width,\n xMargin,\n yMargin,\n ...getFixedPositionOptions(),\n });\n\n setStyle(style);\n setActive(!!element && !element.hidden);\n\n // Only changing the initialX, initialY, or disabled should cause the\n // useEffect below to trigger, which is why everything else is set in a ref.\n }, [disabled, initialX, initialY]);\n\n useEffect(() => {\n if (!active || disabled) {\n return;\n }\n\n const resizeCallback = (event: Event): void => {\n onResize(event);\n updateStyle();\n };\n const scrollCallback = (event: Event): void => {\n const fixedElement = ref.current;\n const fixedToElement = fixedTo.current;\n if (onScroll && fixedElement && fixedToElement) {\n onScroll(event, {\n visible: isWithinViewport({ fixedElement, fixedToElement }),\n fixedElement,\n fixedToElement,\n });\n }\n\n updateStyle();\n };\n\n const resizeHandler = delegateEvent(\"resize\", globalThis.window, true);\n const scrollHandler = delegateEvent(\"scroll\", globalThis.window, true, {\n passive: true,\n });\n resizeHandler.add(resizeCallback);\n scrollHandler.add(scrollCallback);\n return () => {\n resizeHandler.remove(resizeCallback);\n scrollHandler.remove(scrollCallback);\n };\n }, [active, disabled, fixedTo, onResize, onScroll, ref, updateStyle]);\n\n const callbacks: Required<FixedPositioningTransitionCallbacks> = {\n onEnter(appearing) {\n onEnter(appearing);\n updateStyle();\n },\n onEntering(appearing) {\n onEntering(appearing);\n updateStyle();\n },\n onEntered(appearing) {\n onEntered(appearing);\n updateStyle();\n },\n onExited() {\n onExited();\n setActive(false);\n },\n };\n\n return {\n ref: refHandler,\n style: disabled ? propStyle : { ...style, ...propStyle },\n callbacks,\n updateStyle,\n transitionOptions: {\n ...callbacks,\n nodeRef: refHandler,\n },\n };\n}\n"],"names":["useCallback","useEffect","useRef","useState","delegateEvent","useEnsuredRef","useIsomorphicLayoutEffect","BELOW_CENTER_ANCHOR","getFixedPosition","isWithinViewport","noop","undefined","useFixedPositioning","options","style","propStyle","nodeRef","fixedTo","disabled","onEnter","onEntering","onEntered","onExited","anchor","disableSwapping","disableVHBounds","initialX","initialY","preventOverlap","transformOrigin","vhMargin","vwMargin","width","xMargin","yMargin","getFixedPositionOptions","onScroll","onResize","active","setActive","ref","refHandler","optionsRef","current","setStyle","container","element","updateStyle","hidden","resizeCallback","event","scrollCallback","fixedElement","fixedToElement","visible","resizeHandler","globalThis","window","scrollHandler","passive","add","remove","callbacks","appearing","transitionOptions"],"mappings":"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"}
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
return label;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
const data = el.
|
|
185
|
+
const data = el.dataset.sizingSelector;
|
|
186
186
|
if (data) {
|
|
187
187
|
const content = el.querySelector(data);
|
|
188
188
|
if (content) {
|
|
@@ -221,9 +221,9 @@
|
|
|
221
221
|
// reset transforms so that custom animations don't mess with the sizing
|
|
222
222
|
cloned.style.transform = "none";
|
|
223
223
|
const parent = element.parentElement || document.body;
|
|
224
|
-
parent.
|
|
224
|
+
parent.append(cloned);
|
|
225
225
|
const rect = cloned.getBoundingClientRect();
|
|
226
|
-
|
|
226
|
+
cloned.remove();
|
|
227
227
|
return rect;
|
|
228
228
|
}
|
|
229
229
|
/**
|