@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
package/dist/menu/Menu.js
CHANGED
|
@@ -203,12 +203,12 @@ const noop = ()=>{
|
|
|
203
203
|
};
|
|
204
204
|
// wait an animation frame so the initial click event that caused the menu
|
|
205
205
|
// to become visible does not immediately close the menu
|
|
206
|
-
const frame =
|
|
207
|
-
|
|
206
|
+
const frame = globalThis.requestAnimationFrame(()=>{
|
|
207
|
+
globalThis.addEventListener("click", callback);
|
|
208
208
|
});
|
|
209
209
|
return ()=>{
|
|
210
|
-
|
|
211
|
-
|
|
210
|
+
globalThis.cancelAnimationFrame(frame);
|
|
211
|
+
globalThis.removeEventListener("click", callback);
|
|
212
212
|
};
|
|
213
213
|
}, [
|
|
214
214
|
disableHoverMode,
|
package/dist/menu/Menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/Menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n forwardRef,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { type FloatingActionButtonPosition } from \"../button/FloatingActionButton.js\";\nimport { useFocusContainer } from \"../focus/useFocusContainer.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { type ListProps } from \"../list/List.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { type GetDefaultFocusedIndex } from \"../movement/types.js\";\nimport { Portal } from \"../portal/Portal.js\";\nimport { type CalculateFixedPositionOptions } from \"../positioning/types.js\";\nimport {\n type FixedPositioningOptions,\n useFixedPositioning,\n} from \"../positioning/useFixedPositioning.js\";\nimport { useScrollLock } from \"../scroll/useScrollLock.js\";\nimport {\n type ScaleTransitionHookOptions,\n useScaleTransition,\n} from \"../transition/useScaleTransition.js\";\nimport { type LabelRequiredForA11y, type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport {\n type MenuConfiguration,\n MenuConfigurationProvider,\n type MenuOrientationProps,\n useMenuConfiguration,\n} from \"./MenuConfigurationProvider.js\";\nimport { MenuSheet, type MenuSheetConvenienceProps } from \"./MenuSheet.js\";\nimport { MenuWidget } from \"./MenuWidget.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\nimport { getDefaultAnchor } from \"./utils.js\";\n\n// NOTE: The augmentation is in this file since no types are imported from the\n// `styles` file at this time\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-menu-background-color\"?: string;\n \"--rmd-menu-color\"?: string;\n \"--rmd-menu-min-width\"?: string | number;\n \"--rmd-menu-spacing\"?: string | number;\n }\n}\n\nconst noop = (): void => {\n // do nothing\n};\n\n/** @since 5.0.0 */\nexport type MenuTransitionProps = Omit<\n ScaleTransitionHookOptions<HTMLDivElement>,\n \"transitionIn\" | \"vertical\" | \"nodeRef\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface MenuConfigurationProps extends CalculateFixedPositionOptions {\n /**\n * @see {@link ScaleTransitionHookOptions.temporary}\n * @defaultValue `true`\n */\n temporary?: boolean;\n\n /**\n * @defaultValue `false`\n */\n disablePortal?: boolean;\n\n /**\n * Boolean if the menu should not gain the elevation styles and should only be\n * set to `true` when rendering within a `Sheet`.\n *\n * @defaultValue `false`\n */\n disableElevation?: boolean;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @see {@link FixedPositioningOptions.transformOrigin}\n * @defaultValue `true`\n */\n transformOrigin?: boolean;\n\n /**\n * Boolean if the menu should close if the page is scrolled. The default\n * behavior is to just update the position of the menu relative to the menu\n * button until it can no longer be visible within the viewport.\n *\n * @defaultValue `false`\n */\n closeOnScroll?: boolean;\n\n /**\n * Boolean if the page should no longer be scrollable while the menu is\n * visible.\n *\n * @defaultValue `false`\n */\n preventScroll?: boolean;\n\n /**\n * Boolean if the menu should close instead of repositioning itself if the\n * browser window is resized.\n *\n * @defaultValue `false`\n */\n closeOnResize?: boolean;\n\n /** @see {@link FixedPositioningOptions.getFixedPositionOptions} */\n getFixedPositionOptions?: () => CalculateFixedPositionOptions;\n\n /**\n * @defaultValue `false`\n * @see {@link FixedPositioningOptions.disabled}\n */\n disableFixedPositioning?: boolean;\n}\n\n/**\n * @since 5.1.0\n * @since 6.0.0 Renamed from `MenuListProps` to `MenuListConvenienceProps`\n */\nexport interface MenuListConvenienceProps {\n /**\n * An optional style to provide to the `List` component that surrounds the\n * `MenuItem` within a `Menu`.\n */\n listStyle?: CSSProperties;\n\n /**\n * An optional className to provide to the `List` component that surrounds the\n * `MenuItem` within a `Menu`.\n */\n listClassName?: string;\n\n /**\n * Any additional props to pass to the `List` component that surrounds the\n * `Menu`'s `MenuItem`s.\n */\n listProps?: PropsWithRef<Omit<ListProps, \"horizontal\">>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface MenuConvenienceProps extends MenuConfigurationProps {\n /**\n * This can be used to apply additional props to the `Menu` component.\n *\n * Note: You can override the `style` and `className` using\n * {@link menuStyle} and {@link menuClassName} instead for convenience.\n *\n * @example\n * ```tsx\n * <DropdownMenu\n * {...props}\n * menuProps={{\n * style: {\n * // custom inline style\n * },\n * className: \"come-class-name\",\n * getFixedPositionOptions: () => ({\n * preventOverlap: true,\n * }),\n * }}\n * />\n * ```\n */\n menuProps?: PropsWithRef<\n Omit<\n MenuProps,\n | \"children\"\n | \"fixedTo\"\n | \"visible\"\n | \"onRequestClose\"\n | \"getDefaultFocusedIndex\"\n >\n >;\n\n /**\n * Convenience prop to apply custom style to the `Menu` component.\n */\n menuStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `Menu` component.\n */\n menuClassName?: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport type MenuFixedPositioningOptions = Omit<\n FixedPositioningOptions<HTMLElement, HTMLDivElement>,\n \"onScroll\" | \"onResize\" | \"nodeRef\" | \"disabled\"\n>;\n\n/**\n * @since 5.0.0\n * @since 6.0.0 Updated to use the latest Menu, Transition, and Portal API.\n */\nexport interface MenuProps\n extends\n HTMLAttributes<HTMLDivElement>,\n MenuConfiguration,\n MenuConfigurationProps,\n MenuFixedPositioningOptions,\n MenuOrientationProps,\n MenuTransitionProps,\n MenuListConvenienceProps,\n MenuSheetConvenienceProps {\n visible: boolean;\n onRequestClose: () => void;\n\n /**\n * @defaultValue `\"menu-\" + useId()`\n */\n id?: string;\n\n /**\n * This is used to set the default focus index when the menu is visible.\n *\n * @internal\n */\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n\n /**\n * Custom style that should be applied to the menu only while not rendered\n * within a sheet since the {@link style} would be applied to both versions.\n */\n menuStyle?: CSSProperties;\n\n /**\n * Custom class name that should be applied only while not rendered within a\n * sheet.\n */\n menuClassName?: string;\n\n /**\n * @internal\n *\n * This is only used to update the default anchor when the DropdownMenu's\n * toggle is a floating action button.\n */\n floating?: FloatingActionButtonPosition;\n}\n\n/**\n * **Client Component**\n *\n * This component should generally only be used to implement context menus with\n * the `useContextMenu` hook. Otherwise, the `DropdownMenu` component should be\n * used.\n *\n * @see The `useContextMenu` hook for an example.\n *\n * @see {@link https://react-md.dev/components/menu | Menu Demos}\n * @since 5.0.0\n * @since 6.0.0 Updated this component to implement all the `Menu`\n * functionality instead of requiring the `useMenu` hook and `MenuWidget`\n * component. In addition, the `renderAsSheet` behavior has been moved into this\n * implementation so that the `MenuRenderer` is no longer required and context\n * menus can appear as a `Sheet`.\n */\nexport const Menu = forwardRef<HTMLDivElement, LabelRequiredForA11y<MenuProps>>(\n function Menu(props, propRef) {\n const {\n id: propId,\n style: propStyle,\n role = \"menu\",\n children,\n horizontal: _horizontal,\n sheetHeader: _sheetHeader,\n sheetFooter: _sheetFooter,\n renderAsSheet: _renderAsSheet,\n sheetPosition: _sheetPosition,\n sheetVerticalSize: _sheetVerticalSize,\n sheetProps,\n sheetStyle,\n sheetClassName,\n menuStyle,\n menuClassName,\n disableElevation = false,\n temporary = true,\n tabIndex = -1,\n fixedTo,\n className,\n classNames,\n timeout,\n appear,\n enter,\n exit,\n onEnter,\n onEntering = noop,\n onEntered = noop,\n onExit,\n onExiting,\n onExited = noop,\n onKeyDown = noop,\n listProps,\n listStyle,\n listClassName,\n visible,\n onRequestClose,\n floating,\n anchor,\n closeOnResize = false,\n closeOnScroll = false,\n preventScroll = false,\n vwMargin,\n vhMargin,\n xMargin,\n yMargin,\n width,\n transformOrigin = true,\n preventOverlap,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n disableFixedPositioning,\n getFixedPositionOptions,\n disablePortal: propDisablePortal,\n disableTransition,\n ...remaining\n } = props;\n const { \"aria-label\": ariaLabel, \"aria-labelledby\": ariaLabelledBy } =\n props;\n\n const id = useEnsuredId(propId, \"menu\");\n const {\n root,\n menubar,\n menuitem,\n activeId,\n animatedOnceRef,\n hoverTimeoutRef,\n disableHoverMode,\n } = useMenuBarContext();\n const {\n horizontal,\n sheetHeader,\n sheetFooter,\n renderAsSheet,\n sheetPosition,\n sheetVerticalSize,\n } = useMenuConfiguration(props);\n const { isPhone } = useAppSize();\n const isSheet =\n renderAsSheet === true || (renderAsSheet === \"phone\" && isPhone);\n\n const entered = useRef(false);\n const cancelUnmountFocus = useRef(false);\n const hideWithoutRefocus = (): void => {\n cancelUnmountFocus.current = true;\n onRequestClose();\n };\n const mode = useUserInteractionMode();\n const mouse = mode === \"mouse\";\n\n const { eventHandlers, transitionOptions } = useFocusContainer({\n nodeRef: propRef,\n activate: visible,\n onKeyDown(event) {\n onKeyDown(event);\n\n // when a menu is within a sheet, it should not trigger the custom\n // keyboard behavior\n if (isSheet) {\n return;\n }\n\n switch (event.key) {\n case \"Escape\":\n // prevent parent components that have an \"Escape\" keypress event\n // from being triggered as well\n event.stopPropagation();\n disableHoverMode();\n onRequestClose();\n break;\n case \"Tab\":\n // since menus are portalled, tab index is kinda broke so just close\n // the menu instead of doing default tab behavior\n event.preventDefault();\n\n if (!menuitem) {\n // pressing the tab key should still cascade close all menus\n event.stopPropagation();\n }\n disableHoverMode();\n onRequestClose();\n break;\n case \"ArrowUp\":\n if (!root && menuitem && horizontal) {\n event.stopPropagation();\n event.preventDefault();\n onRequestClose();\n }\n break;\n case \"ArrowLeft\":\n if (!root && menuitem && !horizontal) {\n event.stopPropagation();\n event.preventDefault();\n onRequestClose();\n }\n break;\n }\n },\n onEnter,\n onEntering(appearing) {\n onEntering(appearing);\n entered.current = true;\n },\n onEntered(appearing) {\n onEntered(appearing);\n entered.current = true;\n cancelUnmountFocus.current = false;\n animatedOnceRef.current = true;\n },\n onExit,\n onExiting,\n onExited() {\n onExited();\n entered.current = false;\n },\n disableTransition,\n isFocusTypeDisabled(type) {\n if (role === \"listbox\") {\n return !isSheet;\n }\n\n if (type === \"keyboard\") {\n return isSheet;\n }\n\n const isHoverDisabled = mouse && hoverTimeoutRef.current === 0;\n if (type === \"mount\") {\n return isHoverDisabled;\n }\n\n return (\n isHoverDisabled ||\n cancelUnmountFocus.current ||\n (root && !!activeId && id !== activeId)\n );\n },\n });\n\n const { ref, style, callbacks, updateStyle } = useFixedPositioning({\n ...transitionOptions,\n disabled: disableFixedPositioning,\n style: isSheet ? propStyle : menuStyle,\n fixedTo,\n anchor: getDefaultAnchor({\n anchor,\n menubar,\n floating,\n menuitem: !root && menuitem,\n horizontal,\n }),\n vwMargin,\n vhMargin,\n xMargin,\n yMargin,\n width,\n transformOrigin,\n preventOverlap,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n getFixedPositionOptions,\n onResize: closeOnResize ? hideWithoutRefocus : undefined,\n onScroll(_event, data) {\n if (!data.visible || closeOnScroll) {\n hideWithoutRefocus();\n }\n },\n });\n const { rendered, disablePortal, elementProps } = useScaleTransition({\n className: cnb(!isSheet && menuClassName, className),\n transitionIn: visible,\n vertical: !horizontal,\n temporary,\n timeout: isSheet || disableTransition ? 0 : timeout,\n classNames,\n appear,\n enter,\n exit,\n exitedHidden: true,\n // merge the transition callbacks\n ...transitionOptions,\n ...callbacks,\n // but prefer the latest defined ref\n nodeRef: ref,\n });\n useScrollLock(visible && preventScroll);\n\n // need to make sure that the useEffect does not refire for hiding on click\n // events because of the `window.requestAnimationFrame`. It'll make it so\n // that menu items that update state are unable to close when clicked\n const hide = useRef(onRequestClose);\n useEffect(() => {\n hide.current = onRequestClose;\n });\n useEffect(() => {\n if (!visible) {\n return;\n }\n\n const callback = (event: globalThis.MouseEvent): void => {\n // this is required for when the transition is disabled\n if (!entered.current) {\n return;\n }\n\n // if the user clicks outside of the menu to close it, the toggle button\n // should not be focused. instead the nearest focusable element from the\n // click event should be focused when Tab or Shift + tab is pressed\n cancelUnmountFocus.current =\n !(event.target instanceof HTMLElement) ||\n !event.target.closest(`[role=\"${role}\"]`);\n\n // this won't be called if `event.stopPropagation()` is called\n hide.current();\n disableHoverMode();\n };\n\n // wait an animation frame so the initial click event that caused the menu\n // to become visible does not immediately close the menu\n const frame = window.requestAnimationFrame(() => {\n window.addEventListener(\"click\", callback);\n });\n\n return () => {\n window.cancelAnimationFrame(frame);\n window.removeEventListener(\"click\", callback);\n };\n }, [disableHoverMode, role, visible]);\n useIsomorphicLayoutEffect(() => {\n if (!visible) {\n return;\n }\n\n updateStyle();\n }, [updateStyle, children, visible]);\n\n return (\n <MenuConfigurationProvider\n horizontal={horizontal}\n renderAsSheet={renderAsSheet}\n sheetFooter={sheetFooter}\n sheetHeader={sheetHeader}\n sheetPosition={sheetPosition}\n sheetVerticalSize={sheetVerticalSize}\n >\n <MenuSheet\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy as string}\n header={sheetHeader}\n footer={sheetFooter}\n position={sheetPosition}\n verticalSize={sheetVerticalSize}\n visible={visible}\n enabled={isSheet}\n onRequestClose={onRequestClose}\n style={sheetStyle}\n className={sheetClassName}\n disablePortal={propDisablePortal}\n temporary={temporary}\n disableTransition={disableTransition}\n {...sheetProps}\n >\n <Portal disabled={isSheet || (propDisablePortal ?? disablePortal)}>\n {(rendered || isSheet) && (\n <MenuWidget\n {...remaining}\n {...elementProps}\n {...eventHandlers}\n id={id}\n role={role}\n style={isSheet ? propStyle : style}\n isSheet={isSheet}\n tabIndex={tabIndex}\n horizontal={horizontal}\n listProps={listProps}\n listStyle={listStyle}\n listClassName={listClassName}\n disableElevation={disableElevation}\n cancelUnmountFocus={cancelUnmountFocus}\n >\n {children}\n </MenuWidget>\n )}\n </Portal>\n </MenuSheet>\n </MenuConfigurationProvider>\n );\n }\n);\n"],"names":["cnb","forwardRef","useEffect","useRef","useFocusContainer","useUserInteractionMode","useAppSize","Portal","useFixedPositioning","useScrollLock","useScaleTransition","useEnsuredId","useIsomorphicLayoutEffect","MenuConfigurationProvider","useMenuConfiguration","MenuSheet","MenuWidget","useMenuBarContext","getDefaultAnchor","noop","Menu","props","propRef","id","propId","style","propStyle","role","children","horizontal","_horizontal","sheetHeader","_sheetHeader","sheetFooter","_sheetFooter","renderAsSheet","_renderAsSheet","sheetPosition","_sheetPosition","sheetVerticalSize","_sheetVerticalSize","sheetProps","sheetStyle","sheetClassName","menuStyle","menuClassName","disableElevation","temporary","tabIndex","fixedTo","className","classNames","timeout","appear","enter","exit","onEnter","onEntering","onEntered","onExit","onExiting","onExited","onKeyDown","listProps","listStyle","listClassName","visible","onRequestClose","floating","anchor","closeOnResize","closeOnScroll","preventScroll","vwMargin","vhMargin","xMargin","yMargin","width","transformOrigin","preventOverlap","disableSwapping","disableVHBounds","initialX","initialY","disableFixedPositioning","getFixedPositionOptions","disablePortal","propDisablePortal","disableTransition","remaining","ariaLabel","ariaLabelledBy","root","menubar","menuitem","activeId","animatedOnceRef","hoverTimeoutRef","disableHoverMode","isPhone","isSheet","entered","cancelUnmountFocus","hideWithoutRefocus","current","mode","mouse","eventHandlers","transitionOptions","nodeRef","activate","event","key","stopPropagation","preventDefault","appearing","isFocusTypeDisabled","type","isHoverDisabled","ref","callbacks","updateStyle","disabled","onResize","undefined","onScroll","_event","data","rendered","elementProps","transitionIn","vertical","exitedHidden","hide","callback","target","HTMLElement","closest","frame","window","requestAnimationFrame","addEventListener","cancelAnimationFrame","removeEventListener","aria-label","aria-labelledby","header","footer","position","verticalSize","enabled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/menu/Menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n forwardRef,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { type FloatingActionButtonPosition } from \"../button/FloatingActionButton.js\";\nimport { useFocusContainer } from \"../focus/useFocusContainer.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { type ListProps } from \"../list/List.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { type GetDefaultFocusedIndex } from \"../movement/types.js\";\nimport { Portal } from \"../portal/Portal.js\";\nimport { type CalculateFixedPositionOptions } from \"../positioning/types.js\";\nimport {\n type FixedPositioningOptions,\n useFixedPositioning,\n} from \"../positioning/useFixedPositioning.js\";\nimport { useScrollLock } from \"../scroll/useScrollLock.js\";\nimport {\n type ScaleTransitionHookOptions,\n useScaleTransition,\n} from \"../transition/useScaleTransition.js\";\nimport { type LabelRequiredForA11y, type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport {\n type MenuConfiguration,\n MenuConfigurationProvider,\n type MenuOrientationProps,\n useMenuConfiguration,\n} from \"./MenuConfigurationProvider.js\";\nimport { MenuSheet, type MenuSheetConvenienceProps } from \"./MenuSheet.js\";\nimport { MenuWidget } from \"./MenuWidget.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\nimport { getDefaultAnchor } from \"./utils.js\";\n\n// NOTE: The augmentation is in this file since no types are imported from the\n// `styles` file at this time\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-menu-background-color\"?: string;\n \"--rmd-menu-color\"?: string;\n \"--rmd-menu-min-width\"?: string | number;\n \"--rmd-menu-spacing\"?: string | number;\n }\n}\n\nconst noop = (): void => {\n // do nothing\n};\n\n/** @since 5.0.0 */\nexport type MenuTransitionProps = Omit<\n ScaleTransitionHookOptions<HTMLDivElement>,\n \"transitionIn\" | \"vertical\" | \"nodeRef\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport interface MenuConfigurationProps extends CalculateFixedPositionOptions {\n /**\n * @see {@link ScaleTransitionHookOptions.temporary}\n * @defaultValue `true`\n */\n temporary?: boolean;\n\n /**\n * @defaultValue `false`\n */\n disablePortal?: boolean;\n\n /**\n * Boolean if the menu should not gain the elevation styles and should only be\n * set to `true` when rendering within a `Sheet`.\n *\n * @defaultValue `false`\n */\n disableElevation?: boolean;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @see {@link FixedPositioningOptions.transformOrigin}\n * @defaultValue `true`\n */\n transformOrigin?: boolean;\n\n /**\n * Boolean if the menu should close if the page is scrolled. The default\n * behavior is to just update the position of the menu relative to the menu\n * button until it can no longer be visible within the viewport.\n *\n * @defaultValue `false`\n */\n closeOnScroll?: boolean;\n\n /**\n * Boolean if the page should no longer be scrollable while the menu is\n * visible.\n *\n * @defaultValue `false`\n */\n preventScroll?: boolean;\n\n /**\n * Boolean if the menu should close instead of repositioning itself if the\n * browser window is resized.\n *\n * @defaultValue `false`\n */\n closeOnResize?: boolean;\n\n /** @see {@link FixedPositioningOptions.getFixedPositionOptions} */\n getFixedPositionOptions?: () => CalculateFixedPositionOptions;\n\n /**\n * @defaultValue `false`\n * @see {@link FixedPositioningOptions.disabled}\n */\n disableFixedPositioning?: boolean;\n}\n\n/**\n * @since 5.1.0\n * @since 6.0.0 Renamed from `MenuListProps` to `MenuListConvenienceProps`\n */\nexport interface MenuListConvenienceProps {\n /**\n * An optional style to provide to the `List` component that surrounds the\n * `MenuItem` within a `Menu`.\n */\n listStyle?: CSSProperties;\n\n /**\n * An optional className to provide to the `List` component that surrounds the\n * `MenuItem` within a `Menu`.\n */\n listClassName?: string;\n\n /**\n * Any additional props to pass to the `List` component that surrounds the\n * `Menu`'s `MenuItem`s.\n */\n listProps?: PropsWithRef<Omit<ListProps, \"horizontal\">>;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface MenuConvenienceProps extends MenuConfigurationProps {\n /**\n * This can be used to apply additional props to the `Menu` component.\n *\n * Note: You can override the `style` and `className` using\n * {@link menuStyle} and {@link menuClassName} instead for convenience.\n *\n * @example\n * ```tsx\n * <DropdownMenu\n * {...props}\n * menuProps={{\n * style: {\n * // custom inline style\n * },\n * className: \"come-class-name\",\n * getFixedPositionOptions: () => ({\n * preventOverlap: true,\n * }),\n * }}\n * />\n * ```\n */\n menuProps?: PropsWithRef<\n Omit<\n MenuProps,\n | \"children\"\n | \"fixedTo\"\n | \"visible\"\n | \"onRequestClose\"\n | \"getDefaultFocusedIndex\"\n >\n >;\n\n /**\n * Convenience prop to apply custom style to the `Menu` component.\n */\n menuStyle?: CSSProperties;\n\n /**\n * Convenience prop to apply custom class name to the `Menu` component.\n */\n menuClassName?: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport type MenuFixedPositioningOptions = Omit<\n FixedPositioningOptions<HTMLElement, HTMLDivElement>,\n \"onScroll\" | \"onResize\" | \"nodeRef\" | \"disabled\"\n>;\n\n/**\n * @since 5.0.0\n * @since 6.0.0 Updated to use the latest Menu, Transition, and Portal API.\n */\nexport interface MenuProps\n extends\n HTMLAttributes<HTMLDivElement>,\n MenuConfiguration,\n MenuConfigurationProps,\n MenuFixedPositioningOptions,\n MenuOrientationProps,\n MenuTransitionProps,\n MenuListConvenienceProps,\n MenuSheetConvenienceProps {\n visible: boolean;\n onRequestClose: () => void;\n\n /**\n * @defaultValue `\"menu-\" + useId()`\n */\n id?: string;\n\n /**\n * This is used to set the default focus index when the menu is visible.\n *\n * @internal\n */\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n\n /**\n * Custom style that should be applied to the menu only while not rendered\n * within a sheet since the {@link style} would be applied to both versions.\n */\n menuStyle?: CSSProperties;\n\n /**\n * Custom class name that should be applied only while not rendered within a\n * sheet.\n */\n menuClassName?: string;\n\n /**\n * @internal\n *\n * This is only used to update the default anchor when the DropdownMenu's\n * toggle is a floating action button.\n */\n floating?: FloatingActionButtonPosition;\n}\n\n/**\n * **Client Component**\n *\n * This component should generally only be used to implement context menus with\n * the `useContextMenu` hook. Otherwise, the `DropdownMenu` component should be\n * used.\n *\n * @see The `useContextMenu` hook for an example.\n *\n * @see {@link https://react-md.dev/components/menu | Menu Demos}\n * @since 5.0.0\n * @since 6.0.0 Updated this component to implement all the `Menu`\n * functionality instead of requiring the `useMenu` hook and `MenuWidget`\n * component. In addition, the `renderAsSheet` behavior has been moved into this\n * implementation so that the `MenuRenderer` is no longer required and context\n * menus can appear as a `Sheet`.\n */\nexport const Menu = forwardRef<HTMLDivElement, LabelRequiredForA11y<MenuProps>>(\n function Menu(props, propRef) {\n const {\n id: propId,\n style: propStyle,\n role = \"menu\",\n children,\n horizontal: _horizontal,\n sheetHeader: _sheetHeader,\n sheetFooter: _sheetFooter,\n renderAsSheet: _renderAsSheet,\n sheetPosition: _sheetPosition,\n sheetVerticalSize: _sheetVerticalSize,\n sheetProps,\n sheetStyle,\n sheetClassName,\n menuStyle,\n menuClassName,\n disableElevation = false,\n temporary = true,\n tabIndex = -1,\n fixedTo,\n className,\n classNames,\n timeout,\n appear,\n enter,\n exit,\n onEnter,\n onEntering = noop,\n onEntered = noop,\n onExit,\n onExiting,\n onExited = noop,\n onKeyDown = noop,\n listProps,\n listStyle,\n listClassName,\n visible,\n onRequestClose,\n floating,\n anchor,\n closeOnResize = false,\n closeOnScroll = false,\n preventScroll = false,\n vwMargin,\n vhMargin,\n xMargin,\n yMargin,\n width,\n transformOrigin = true,\n preventOverlap,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n disableFixedPositioning,\n getFixedPositionOptions,\n disablePortal: propDisablePortal,\n disableTransition,\n ...remaining\n } = props;\n const { \"aria-label\": ariaLabel, \"aria-labelledby\": ariaLabelledBy } =\n props;\n\n const id = useEnsuredId(propId, \"menu\");\n const {\n root,\n menubar,\n menuitem,\n activeId,\n animatedOnceRef,\n hoverTimeoutRef,\n disableHoverMode,\n } = useMenuBarContext();\n const {\n horizontal,\n sheetHeader,\n sheetFooter,\n renderAsSheet,\n sheetPosition,\n sheetVerticalSize,\n } = useMenuConfiguration(props);\n const { isPhone } = useAppSize();\n const isSheet =\n renderAsSheet === true || (renderAsSheet === \"phone\" && isPhone);\n\n const entered = useRef(false);\n const cancelUnmountFocus = useRef(false);\n const hideWithoutRefocus = (): void => {\n cancelUnmountFocus.current = true;\n onRequestClose();\n };\n const mode = useUserInteractionMode();\n const mouse = mode === \"mouse\";\n\n const { eventHandlers, transitionOptions } = useFocusContainer({\n nodeRef: propRef,\n activate: visible,\n onKeyDown(event) {\n onKeyDown(event);\n\n // when a menu is within a sheet, it should not trigger the custom\n // keyboard behavior\n if (isSheet) {\n return;\n }\n\n switch (event.key) {\n case \"Escape\":\n // prevent parent components that have an \"Escape\" keypress event\n // from being triggered as well\n event.stopPropagation();\n disableHoverMode();\n onRequestClose();\n break;\n case \"Tab\":\n // since menus are portalled, tab index is kinda broke so just close\n // the menu instead of doing default tab behavior\n event.preventDefault();\n\n if (!menuitem) {\n // pressing the tab key should still cascade close all menus\n event.stopPropagation();\n }\n disableHoverMode();\n onRequestClose();\n break;\n case \"ArrowUp\":\n if (!root && menuitem && horizontal) {\n event.stopPropagation();\n event.preventDefault();\n onRequestClose();\n }\n break;\n case \"ArrowLeft\":\n if (!root && menuitem && !horizontal) {\n event.stopPropagation();\n event.preventDefault();\n onRequestClose();\n }\n break;\n }\n },\n onEnter,\n onEntering(appearing) {\n onEntering(appearing);\n entered.current = true;\n },\n onEntered(appearing) {\n onEntered(appearing);\n entered.current = true;\n cancelUnmountFocus.current = false;\n animatedOnceRef.current = true;\n },\n onExit,\n onExiting,\n onExited() {\n onExited();\n entered.current = false;\n },\n disableTransition,\n isFocusTypeDisabled(type) {\n if (role === \"listbox\") {\n return !isSheet;\n }\n\n if (type === \"keyboard\") {\n return isSheet;\n }\n\n const isHoverDisabled = mouse && hoverTimeoutRef.current === 0;\n if (type === \"mount\") {\n return isHoverDisabled;\n }\n\n return (\n isHoverDisabled ||\n cancelUnmountFocus.current ||\n (root && !!activeId && id !== activeId)\n );\n },\n });\n\n const { ref, style, callbacks, updateStyle } = useFixedPositioning({\n ...transitionOptions,\n disabled: disableFixedPositioning,\n style: isSheet ? propStyle : menuStyle,\n fixedTo,\n anchor: getDefaultAnchor({\n anchor,\n menubar,\n floating,\n menuitem: !root && menuitem,\n horizontal,\n }),\n vwMargin,\n vhMargin,\n xMargin,\n yMargin,\n width,\n transformOrigin,\n preventOverlap,\n disableSwapping,\n disableVHBounds,\n initialX,\n initialY,\n getFixedPositionOptions,\n onResize: closeOnResize ? hideWithoutRefocus : undefined,\n onScroll(_event, data) {\n if (!data.visible || closeOnScroll) {\n hideWithoutRefocus();\n }\n },\n });\n const { rendered, disablePortal, elementProps } = useScaleTransition({\n className: cnb(!isSheet && menuClassName, className),\n transitionIn: visible,\n vertical: !horizontal,\n temporary,\n timeout: isSheet || disableTransition ? 0 : timeout,\n classNames,\n appear,\n enter,\n exit,\n exitedHidden: true,\n // merge the transition callbacks\n ...transitionOptions,\n ...callbacks,\n // but prefer the latest defined ref\n nodeRef: ref,\n });\n useScrollLock(visible && preventScroll);\n\n // need to make sure that the useEffect does not refire for hiding on click\n // events because of the `window.requestAnimationFrame`. It'll make it so\n // that menu items that update state are unable to close when clicked\n const hide = useRef(onRequestClose);\n useEffect(() => {\n hide.current = onRequestClose;\n });\n useEffect(() => {\n if (!visible) {\n return;\n }\n\n const callback = (event: globalThis.MouseEvent): void => {\n // this is required for when the transition is disabled\n if (!entered.current) {\n return;\n }\n\n // if the user clicks outside of the menu to close it, the toggle button\n // should not be focused. instead the nearest focusable element from the\n // click event should be focused when Tab or Shift + tab is pressed\n cancelUnmountFocus.current =\n !(event.target instanceof HTMLElement) ||\n !event.target.closest(`[role=\"${role}\"]`);\n\n // this won't be called if `event.stopPropagation()` is called\n hide.current();\n disableHoverMode();\n };\n\n // wait an animation frame so the initial click event that caused the menu\n // to become visible does not immediately close the menu\n const frame = globalThis.requestAnimationFrame(() => {\n globalThis.addEventListener(\"click\", callback);\n });\n\n return () => {\n globalThis.cancelAnimationFrame(frame);\n globalThis.removeEventListener(\"click\", callback);\n };\n }, [disableHoverMode, role, visible]);\n useIsomorphicLayoutEffect(() => {\n if (!visible) {\n return;\n }\n\n updateStyle();\n }, [updateStyle, children, visible]);\n\n return (\n <MenuConfigurationProvider\n horizontal={horizontal}\n renderAsSheet={renderAsSheet}\n sheetFooter={sheetFooter}\n sheetHeader={sheetHeader}\n sheetPosition={sheetPosition}\n sheetVerticalSize={sheetVerticalSize}\n >\n <MenuSheet\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy as string}\n header={sheetHeader}\n footer={sheetFooter}\n position={sheetPosition}\n verticalSize={sheetVerticalSize}\n visible={visible}\n enabled={isSheet}\n onRequestClose={onRequestClose}\n style={sheetStyle}\n className={sheetClassName}\n disablePortal={propDisablePortal}\n temporary={temporary}\n disableTransition={disableTransition}\n {...sheetProps}\n >\n <Portal disabled={isSheet || (propDisablePortal ?? disablePortal)}>\n {(rendered || isSheet) && (\n <MenuWidget\n {...remaining}\n {...elementProps}\n {...eventHandlers}\n id={id}\n role={role}\n style={isSheet ? propStyle : style}\n isSheet={isSheet}\n tabIndex={tabIndex}\n horizontal={horizontal}\n listProps={listProps}\n listStyle={listStyle}\n listClassName={listClassName}\n disableElevation={disableElevation}\n cancelUnmountFocus={cancelUnmountFocus}\n >\n {children}\n </MenuWidget>\n )}\n </Portal>\n </MenuSheet>\n </MenuConfigurationProvider>\n );\n }\n);\n"],"names":["cnb","forwardRef","useEffect","useRef","useFocusContainer","useUserInteractionMode","useAppSize","Portal","useFixedPositioning","useScrollLock","useScaleTransition","useEnsuredId","useIsomorphicLayoutEffect","MenuConfigurationProvider","useMenuConfiguration","MenuSheet","MenuWidget","useMenuBarContext","getDefaultAnchor","noop","Menu","props","propRef","id","propId","style","propStyle","role","children","horizontal","_horizontal","sheetHeader","_sheetHeader","sheetFooter","_sheetFooter","renderAsSheet","_renderAsSheet","sheetPosition","_sheetPosition","sheetVerticalSize","_sheetVerticalSize","sheetProps","sheetStyle","sheetClassName","menuStyle","menuClassName","disableElevation","temporary","tabIndex","fixedTo","className","classNames","timeout","appear","enter","exit","onEnter","onEntering","onEntered","onExit","onExiting","onExited","onKeyDown","listProps","listStyle","listClassName","visible","onRequestClose","floating","anchor","closeOnResize","closeOnScroll","preventScroll","vwMargin","vhMargin","xMargin","yMargin","width","transformOrigin","preventOverlap","disableSwapping","disableVHBounds","initialX","initialY","disableFixedPositioning","getFixedPositionOptions","disablePortal","propDisablePortal","disableTransition","remaining","ariaLabel","ariaLabelledBy","root","menubar","menuitem","activeId","animatedOnceRef","hoverTimeoutRef","disableHoverMode","isPhone","isSheet","entered","cancelUnmountFocus","hideWithoutRefocus","current","mode","mouse","eventHandlers","transitionOptions","nodeRef","activate","event","key","stopPropagation","preventDefault","appearing","isFocusTypeDisabled","type","isHoverDisabled","ref","callbacks","updateStyle","disabled","onResize","undefined","onScroll","_event","data","rendered","elementProps","transitionIn","vertical","exitedHidden","hide","callback","target","HTMLElement","closest","frame","globalThis","requestAnimationFrame","addEventListener","cancelAnimationFrame","removeEventListener","aria-label","aria-labelledby","header","footer","position","verticalSize","enabled"],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ const noop = ()=>{
|
|
|
23
23
|
* @internal
|
|
24
24
|
* @since 5.0.0
|
|
25
25
|
*/ export const MenuItemButton = /*#__PURE__*/ forwardRef(function MenuItemButton(props, ref) {
|
|
26
|
-
const { id: propId, children, height: propHeight, onClick = noop, onKeyDown = noop, onMouseEnter = noop, onMouseLeave = noop, rightAddon: propRightAddon, iconRotatorProps, disableDropdownIcon =
|
|
26
|
+
const { id: propId, children, height: propHeight, onClick = noop, onKeyDown = noop, onMouseEnter = noop, onMouseLeave = noop, rightAddon: propRightAddon, iconRotatorProps, disableDropdownIcon = propRightAddon !== undefined, ...remaining } = props;
|
|
27
27
|
const { disabled } = props;
|
|
28
28
|
const id = useEnsuredId(propId, "menuitem");
|
|
29
29
|
const mode = useUserInteractionMode();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuItemButton.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useEffect } from \"react\";\n\nimport { useHoverMode } from \"../hoverMode/useHoverMode.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type BaseMenuButtonProps } from \"./MenuButton.js\";\nimport { useMenuConfiguration } from \"./MenuConfigurationProvider.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\nimport { useMenuVisibility } from \"./MenuVisibilityProvider.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n * @since 5.0.0\n */\nexport interface MenuItemButtonProps\n extends BaseMenuButtonProps, MenuItemProps {}\n\n/**\n * **Client Component**\n *\n * This is just an internal component that handles rendering a submenu as a\n * menuitem for a `DropdownMenu` with a conditional dropdown icon.\n *\n * @internal\n * @since 5.0.0\n */\nexport const MenuItemButton = forwardRef<HTMLLIElement, MenuItemButtonProps>(\n function MenuItemButton(props, ref) {\n const {\n id: propId,\n children,\n height: propHeight,\n onClick = noop,\n onKeyDown = noop,\n onMouseEnter = noop,\n onMouseLeave = noop,\n rightAddon: propRightAddon,\n iconRotatorProps,\n disableDropdownIcon =
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuItemButton.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useEffect } from \"react\";\n\nimport { useHoverMode } from \"../hoverMode/useHoverMode.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type BaseMenuButtonProps } from \"./MenuButton.js\";\nimport { useMenuConfiguration } from \"./MenuConfigurationProvider.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\nimport { useMenuVisibility } from \"./MenuVisibilityProvider.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n * @since 5.0.0\n */\nexport interface MenuItemButtonProps\n extends BaseMenuButtonProps, MenuItemProps {}\n\n/**\n * **Client Component**\n *\n * This is just an internal component that handles rendering a submenu as a\n * menuitem for a `DropdownMenu` with a conditional dropdown icon.\n *\n * @internal\n * @since 5.0.0\n */\nexport const MenuItemButton = forwardRef<HTMLLIElement, MenuItemButtonProps>(\n function MenuItemButton(props, ref) {\n const {\n id: propId,\n children,\n height: propHeight,\n onClick = noop,\n onKeyDown = noop,\n onMouseEnter = noop,\n onMouseLeave = noop,\n rightAddon: propRightAddon,\n iconRotatorProps,\n disableDropdownIcon = propRightAddon !== undefined,\n ...remaining\n } = props;\n const { disabled } = props;\n\n const id = useEnsuredId(propId, \"menuitem\");\n const mode = useUserInteractionMode();\n const { renderAsSheet } = useMenuConfiguration();\n const { isPhone } = useAppSize();\n const isSheet =\n renderAsSheet === true || (renderAsSheet === \"phone\" && isPhone);\n const {\n root,\n menubar,\n activeId,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n clearDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n } = useMenuBarContext();\n const { visible, setVisible, defaultFocusIndex } = useMenuVisibility();\n const { startShowFlow, clearVisibilityTimeout } = useHoverMode({\n setVisible,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n clearDisableTimer,\n });\n const { horizontal } = useMenuConfiguration();\n\n useEffect(() => {\n setVisible(id === activeId);\n }, [activeId, defaultFocusIndex, id, menubar, setVisible]);\n\n let height = propHeight;\n let rightAddon = propRightAddon;\n const dropdownIcon = getIcon(root ? \"dropdown\" : \"forward\");\n if (!disableDropdownIcon) {\n if (!height && !props.leftAddon) {\n height = \"normal\";\n }\n\n rightAddon = (\n <IconRotator {...iconRotatorProps} rotated={visible}>\n {dropdownIcon}\n </IconRotator>\n );\n }\n\n const updateVisibility = (nextVisible: boolean, focusIndex = 0): void => {\n defaultFocusIndex.current = focusIndex;\n setVisible(nextVisible);\n if (!menubar) {\n return;\n }\n\n if (nextVisible) {\n enableHoverMode(id);\n } else {\n disableHoverMode();\n }\n };\n\n return (\n <MenuItem\n {...remaining}\n aria-haspopup={isSheet ? \"dialog\" : \"menu\"}\n aria-expanded={visible || undefined}\n id={id}\n ref={ref}\n rightAddon={rightAddon}\n onClick={(event) => {\n onClick(event);\n\n event.stopPropagation();\n updateVisibility(!visible);\n }}\n onKeyDown={(event) => {\n onKeyDown(event);\n\n switch (event.key) {\n case \"ArrowDown\":\n if (horizontal || root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n case \"ArrowRight\":\n if (!horizontal && !root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n }\n }}\n onMouseEnter={(event) => {\n onMouseEnter(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n defaultFocusIndex.current = 0;\n startShowFlow(id);\n }}\n onMouseLeave={(event) => {\n onMouseLeave(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n clearVisibilityTimeout();\n }}\n >\n {children}\n </MenuItem>\n );\n }\n);\n"],"names":["forwardRef","useEffect","useHoverMode","IconRotator","getIcon","useUserInteractionMode","useAppSize","useEnsuredId","useMenuConfiguration","MenuItem","useMenuVisibility","useMenuBarContext","noop","MenuItemButton","props","ref","id","propId","children","height","propHeight","onClick","onKeyDown","onMouseEnter","onMouseLeave","rightAddon","propRightAddon","iconRotatorProps","disableDropdownIcon","undefined","remaining","disabled","mode","renderAsSheet","isPhone","isSheet","root","menubar","activeId","enableHoverMode","disableHoverMode","startDisableTimer","clearDisableTimer","leaveTimeoutRef","hoverTimeoutRef","visible","setVisible","defaultFocusIndex","startShowFlow","clearVisibilityTimeout","horizontal","dropdownIcon","leftAddon","rotated","updateVisibility","nextVisible","focusIndex","current","aria-haspopup","aria-expanded","event","stopPropagation","key","preventDefault"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuItemFileInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ChangeEventHandler,\n type InputHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0 Removed most of the shared `FileInputProps` from this\n * implementation.\n */\nexport interface MenuItemFileInputProps\n extends\n Omit<MenuItemProps, \"onChange\">,\n Pick<\n InputHTMLAttributes<HTMLInputElement>,\n \"accept\" | \"capture\" | \"multiple\"\n > {\n /**\n * A change event handler that should do something with the selected files.\n * Usually the `onChange` returned by `useFileUpload` or:\n *\n * ```ts\n * onChange={(event) => {\n * const { files } = event.currentTarget;\n * // do something with files\n * }}\n * ```\n *\n * This is actually a native `Event` and not a `SyntheticEvent` because the\n * file input is created through `document.createElement` instead of `React`.\n * You can still access the files through `event.currentTarget.files` like\n * normal.\n */\n onChange: ChangeEventHandler<HTMLInputElement>;\n\n /**\n * Set this to `true` if the `Menu` should not close when the file input's\n * menu item is clicked.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * A wrapper for the `<input type=\"file\">` element that works within menus.\n *\n * @see {@link https://react-md.dev/components/menu#menuitemfileinput-example | DropdownMenu Demos}\n * @since 5.0.0\n * @since 6.0.0 No longer creates an invisible file input element within the\n * menu item. This allows the menu to be closed immediately when this menu item\n * is clicked.\n */\nexport const MenuItemFileInput = forwardRef<\n HTMLLIElement,\n MenuItemFileInputProps\n>(function MenuItemFileInput(props, ref) {\n const {\n id: propId,\n onClick = noop,\n onChange,\n accept,\n capture,\n multiple,\n children,\n leftAddon: propLeftAddon,\n preventMenuHideOnClick = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"menu-item\");\n const leftAddon = getIcon(\"upload\", propLeftAddon);\n\n return (\n <MenuItem\n {...remaining}\n id={id}\n ref={ref}\n leftAddon={leftAddon}\n onClick={(event) => {\n onClick(event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n\n // Since the menu closes when the menu item is clicked causing the\n // elements to be removed from the DOM, a normal `<input type=\"file\" />`\n // can't be used. Instead, create a temporary file input element and\n // click it to trigger the file upload behavior.\n let input: HTMLInputElement | null = document.createElement(\"input\");\n input.type = \"file\";\n if (accept) {\n input.accept = accept;\n }\n if (multiple) {\n input.multiple = multiple;\n }\n if (capture) {\n input.capture = capture === true ? \"\" : capture;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n input.
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuItemFileInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ChangeEventHandler,\n type InputHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0 Removed most of the shared `FileInputProps` from this\n * implementation.\n */\nexport interface MenuItemFileInputProps\n extends\n Omit<MenuItemProps, \"onChange\">,\n Pick<\n InputHTMLAttributes<HTMLInputElement>,\n \"accept\" | \"capture\" | \"multiple\"\n > {\n /**\n * A change event handler that should do something with the selected files.\n * Usually the `onChange` returned by `useFileUpload` or:\n *\n * ```ts\n * onChange={(event) => {\n * const { files } = event.currentTarget;\n * // do something with files\n * }}\n * ```\n *\n * This is actually a native `Event` and not a `SyntheticEvent` because the\n * file input is created through `document.createElement` instead of `React`.\n * You can still access the files through `event.currentTarget.files` like\n * normal.\n */\n onChange: ChangeEventHandler<HTMLInputElement>;\n\n /**\n * Set this to `true` if the `Menu` should not close when the file input's\n * menu item is clicked.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * A wrapper for the `<input type=\"file\">` element that works within menus.\n *\n * @see {@link https://react-md.dev/components/menu#menuitemfileinput-example | DropdownMenu Demos}\n * @since 5.0.0\n * @since 6.0.0 No longer creates an invisible file input element within the\n * menu item. This allows the menu to be closed immediately when this menu item\n * is clicked.\n */\nexport const MenuItemFileInput = forwardRef<\n HTMLLIElement,\n MenuItemFileInputProps\n>(function MenuItemFileInput(props, ref) {\n const {\n id: propId,\n onClick = noop,\n onChange,\n accept,\n capture,\n multiple,\n children,\n leftAddon: propLeftAddon,\n preventMenuHideOnClick = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"menu-item\");\n const leftAddon = getIcon(\"upload\", propLeftAddon);\n\n return (\n <MenuItem\n {...remaining}\n id={id}\n ref={ref}\n leftAddon={leftAddon}\n onClick={(event) => {\n onClick(event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n\n // Since the menu closes when the menu item is clicked causing the\n // elements to be removed from the DOM, a normal `<input type=\"file\" />`\n // can't be used. Instead, create a temporary file input element and\n // click it to trigger the file upload behavior.\n let input: HTMLInputElement | null = document.createElement(\"input\");\n input.type = \"file\";\n if (accept) {\n input.accept = accept;\n }\n if (multiple) {\n input.multiple = multiple;\n }\n if (capture) {\n input.capture = capture === true ? \"\" : capture;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n input.addEventListener(\"change\", onChange);\n input.click();\n input = null;\n }}\n >\n {children}\n </MenuItem>\n );\n});\n"],"names":["forwardRef","getIcon","useEnsuredId","MenuItem","noop","MenuItemFileInput","props","ref","id","propId","onClick","onChange","accept","capture","multiple","children","leftAddon","propLeftAddon","preventMenuHideOnClick","remaining","event","stopPropagation","input","document","createElement","type","addEventListener","click"],"mappings":"AAAA;;AAEA,SAGEA,UAAU,QACL,QAAQ;AAEf,SAASC,OAAO,QAAQ,oBAAoB;AAC5C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,QAAQ,QAA4B,gBAAgB;AAE7D,MAAMC,OAAO;AACX,aAAa;AACf;AAwCA;;;;;;;;;;CAUC,GACD,OAAO,MAAMC,kCAAoBL,WAG/B,SAASK,kBAAkBC,KAAK,EAAEC,GAAG;IACrC,MAAM,EACJC,IAAIC,MAAM,EACVC,UAAUN,IAAI,EACdO,QAAQ,EACRC,MAAM,EACNC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,WAAWC,aAAa,EACxBC,yBAAyB,KAAK,EAC9B,GAAGC,WACJ,GAAGb;IAEJ,MAAME,KAAKN,aAAaO,QAAQ;IAChC,MAAMO,YAAYf,QAAQ,UAAUgB;IAEpC,qBACE,KAACd;QACE,GAAGgB,SAAS;QACbX,IAAIA;QACJD,KAAKA;QACLS,WAAWA;QACXN,SAAS,CAACU;YACRV,QAAQU;YAER,IAAIF,wBAAwB;gBAC1BE,MAAMC,eAAe;YACvB;YAEA,kEAAkE;YAClE,wEAAwE;YACxE,oEAAoE;YACpE,gDAAgD;YAChD,IAAIC,QAAiCC,SAASC,aAAa,CAAC;YAC5DF,MAAMG,IAAI,GAAG;YACb,IAAIb,QAAQ;gBACVU,MAAMV,MAAM,GAAGA;YACjB;YACA,IAAIE,UAAU;gBACZQ,MAAMR,QAAQ,GAAGA;YACnB;YACA,IAAID,SAAS;gBACXS,MAAMT,OAAO,GAAGA,YAAY,OAAO,KAAKA;YAC1C;YAEA,6DAA6D;YAC7D,mBAAmB;YACnBS,MAAMI,gBAAgB,CAAC,UAAUf;YACjCW,MAAMK,KAAK;YACXL,QAAQ;QACV;kBAECP;;AAGP,GAAG"}
|
package/dist/menu/MenuWidget.js
CHANGED
|
@@ -46,7 +46,7 @@ const noop = ()=>{
|
|
|
46
46
|
if (!isSheet) {
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
globalThis.cancelAnimationFrame(sheetBlurredFame.current);
|
|
50
50
|
setSheetMenuFocused(true);
|
|
51
51
|
},
|
|
52
52
|
onKeyDown,
|
|
@@ -84,7 +84,7 @@ const noop = ()=>{
|
|
|
84
84
|
if (!isSheet) {
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
|
-
sheetBlurredFame.current =
|
|
87
|
+
sheetBlurredFame.current = globalThis.requestAnimationFrame(()=>{
|
|
88
88
|
setSheetMenuFocused(false);
|
|
89
89
|
});
|
|
90
90
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuWidget.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef, useRef, useState } from \"react\";\n\nimport { List } from \"../list/List.js\";\nimport { type GetDefaultFocusedIndex } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { type NonNullMutableRef } from \"../types.js\";\nimport { type MenuListConvenienceProps } from \"./Menu.js\";\nimport { MenuWidgetKeyboardProvider } from \"./MenuWidgetKeyboardProvider.js\";\nimport { menu } from \"./styles.js\";\nimport {\n MenuBarProvider,\n useMenuBarContext,\n useMenuBarProvider,\n} from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n */\nexport interface MenuWidgetProps\n extends HTMLAttributes<HTMLDivElement>, MenuListConvenienceProps {\n isSheet: boolean;\n horizontal: boolean;\n disableElevation?: boolean;\n cancelUnmountFocus: NonNullMutableRef<boolean>;\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n}\n\n/**\n * **Client Component**\n *\n * This component was added to support the listbox role and the `useId()` hook.\n * If the `temporary` prop is set, the `MenuItem`'s ids will not be the same the\n * next time the menu opens, so the aria-activedescendant will point to a\n * non-existing id\n *\n * @internal\n */\nexport const MenuWidget = forwardRef<HTMLDivElement, MenuWidgetProps>(\n function MenuWidget(props, ref) {\n const {\n id,\n role = \"menu\",\n className,\n listStyle,\n listClassName,\n listProps,\n children,\n onClick,\n onBlur = noop,\n onFocus = noop,\n onKeyDown = noop,\n tabIndex = -1,\n isSheet,\n horizontal,\n disableElevation,\n cancelUnmountFocus,\n getDefaultFocusedIndex,\n ...remaining\n } = props;\n const isListbox = role === \"listbox\";\n const { menubar } = useMenuBarContext();\n\n // Since there is the possibility of other tab focusable elements within the\n // sheet and the menu items are programmatically focused, the menu's\n // tabIndex needs to be set to `-1` while one of the child menu items are\n // focused. This allows Shift+Tab correctly focuses the previous focusable\n // element within the sheet. Since `onFocus` and `onBlur` will be bubbled up\n // to the menu widget each time a new MenuItem is focused, only disable the\n // focused state if the blur event is fired without another focus event\n // within an animation frame.\n const [sheetMenuFocused, setSheetMenuFocused] = useState(false);\n const sheetBlurredFame = useRef(0);\n const menuBarContext = useMenuBarProvider({\n root: false,\n menubar,\n hoverTimeout: menubar ? 0 : undefined,\n defaultActiveId: id,\n });\n const { movementProps, movementContext } = useKeyboardMovementProvider({\n ref,\n onClick,\n onFocus(event) {\n onFocus(event);\n\n if (!isSheet) {\n return;\n }\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuWidget.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef, useRef, useState } from \"react\";\n\nimport { List } from \"../list/List.js\";\nimport { type GetDefaultFocusedIndex } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\nimport { type NonNullMutableRef } from \"../types.js\";\nimport { type MenuListConvenienceProps } from \"./Menu.js\";\nimport { MenuWidgetKeyboardProvider } from \"./MenuWidgetKeyboardProvider.js\";\nimport { menu } from \"./styles.js\";\nimport {\n MenuBarProvider,\n useMenuBarContext,\n useMenuBarProvider,\n} from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n */\nexport interface MenuWidgetProps\n extends HTMLAttributes<HTMLDivElement>, MenuListConvenienceProps {\n isSheet: boolean;\n horizontal: boolean;\n disableElevation?: boolean;\n cancelUnmountFocus: NonNullMutableRef<boolean>;\n getDefaultFocusedIndex?: GetDefaultFocusedIndex;\n}\n\n/**\n * **Client Component**\n *\n * This component was added to support the listbox role and the `useId()` hook.\n * If the `temporary` prop is set, the `MenuItem`'s ids will not be the same the\n * next time the menu opens, so the aria-activedescendant will point to a\n * non-existing id\n *\n * @internal\n */\nexport const MenuWidget = forwardRef<HTMLDivElement, MenuWidgetProps>(\n function MenuWidget(props, ref) {\n const {\n id,\n role = \"menu\",\n className,\n listStyle,\n listClassName,\n listProps,\n children,\n onClick,\n onBlur = noop,\n onFocus = noop,\n onKeyDown = noop,\n tabIndex = -1,\n isSheet,\n horizontal,\n disableElevation,\n cancelUnmountFocus,\n getDefaultFocusedIndex,\n ...remaining\n } = props;\n const isListbox = role === \"listbox\";\n const { menubar } = useMenuBarContext();\n\n // Since there is the possibility of other tab focusable elements within the\n // sheet and the menu items are programmatically focused, the menu's\n // tabIndex needs to be set to `-1` while one of the child menu items are\n // focused. This allows Shift+Tab correctly focuses the previous focusable\n // element within the sheet. Since `onFocus` and `onBlur` will be bubbled up\n // to the menu widget each time a new MenuItem is focused, only disable the\n // focused state if the blur event is fired without another focus event\n // within an animation frame.\n const [sheetMenuFocused, setSheetMenuFocused] = useState(false);\n const sheetBlurredFame = useRef(0);\n const menuBarContext = useMenuBarProvider({\n root: false,\n menubar,\n hoverTimeout: menubar ? 0 : undefined,\n defaultActiveId: id,\n });\n const { movementProps, movementContext } = useKeyboardMovementProvider({\n ref,\n onClick,\n onFocus(event) {\n onFocus(event);\n\n if (!isSheet) {\n return;\n }\n\n globalThis.cancelAnimationFrame(sheetBlurredFame.current);\n setSheetMenuFocused(true);\n },\n onKeyDown,\n horizontal,\n loopable: true,\n searchable: true,\n programmatic: true,\n includeDisabled: true,\n getDefaultFocusedIndex,\n });\n\n return (\n <MenuWidgetKeyboardProvider disabled={isListbox} value={movementContext}>\n <MenuBarProvider value={menuBarContext}>\n <div\n aria-orientation={horizontal ? \"horizontal\" : undefined}\n {...remaining}\n {...(isListbox\n ? { onClick, onFocus, onKeyDown, ref }\n : movementProps)}\n id={id}\n role={role}\n className={menu({\n className,\n elevated: !disableElevation && !isSheet,\n horizontal,\n })}\n tabIndex={isSheet && !sheetMenuFocused ? 0 : tabIndex}\n onBlur={(event) => {\n onBlur(event);\n if (!isSheet) {\n return;\n }\n\n sheetBlurredFame.current = globalThis.requestAnimationFrame(\n () => {\n setSheetMenuFocused(false);\n }\n );\n }}\n >\n <List\n {...listProps}\n style={listStyle ?? listProps?.style}\n className={listClassName || listProps?.className}\n horizontal={horizontal}\n onClick={(event) => {\n listProps?.onClick?.(event);\n\n // this makes it so you can click on the menu/list without\n // closing the menu\n if (event.target === event.currentTarget) {\n event.stopPropagation();\n }\n\n // This might be a test only workaround since clicking links move focus\n // somewhere else\n if (event.target instanceof HTMLElement) {\n cancelUnmountFocus.current = event.currentTarget.contains(\n event.target.closest(\"a\")\n );\n }\n }}\n >\n {children}\n </List>\n </div>\n </MenuBarProvider>\n </MenuWidgetKeyboardProvider>\n );\n }\n);\n"],"names":["forwardRef","useRef","useState","List","useKeyboardMovementProvider","MenuWidgetKeyboardProvider","menu","MenuBarProvider","useMenuBarContext","useMenuBarProvider","noop","MenuWidget","props","ref","id","role","className","listStyle","listClassName","listProps","children","onClick","onBlur","onFocus","onKeyDown","tabIndex","isSheet","horizontal","disableElevation","cancelUnmountFocus","getDefaultFocusedIndex","remaining","isListbox","menubar","sheetMenuFocused","setSheetMenuFocused","sheetBlurredFame","menuBarContext","root","hoverTimeout","undefined","defaultActiveId","movementProps","movementContext","event","globalThis","cancelAnimationFrame","current","loopable","searchable","programmatic","includeDisabled","disabled","value","div","aria-orientation","elevated","requestAnimationFrame","style","target","currentTarget","stopPropagation","HTMLElement","contains","closest"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @internal
|
|
10
10
|
*/ export function findMatchInRange(options) {
|
|
11
11
|
const { values, startIndex, endIndex } = options;
|
|
12
|
-
if (
|
|
12
|
+
if (values.length === 0) {
|
|
13
13
|
return -1;
|
|
14
14
|
}
|
|
15
15
|
const value = options.value.toUpperCase();
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
*/ export function findMatchIndex(options) {
|
|
35
35
|
const { value, values, startIndex, isSelfMatchable = true } = options;
|
|
36
36
|
// this was added to support comboboxes when there are no options available
|
|
37
|
-
if (
|
|
37
|
+
if (values.length === 0) {
|
|
38
38
|
return -1;
|
|
39
39
|
}
|
|
40
40
|
let index = findMatchInRange({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/movement/findMatchIndex.ts"],"sourcesContent":["/** @internal */\nexport interface BaseOptions {\n /**\n * The current query string to find within the values\n */\n value: string;\n\n /**\n * The list of values to search within\n */\n values: readonly string[];\n\n /**\n * The start index for the search\n */\n startIndex: number;\n}\n\n/** @internal */\nexport interface MatchInRangeOptions extends BaseOptions {\n /**\n * The end index for the search\n */\n endIndex: number;\n}\n\n/**\n * Attempts to find the first match index for a list of values that starts with\n * the provided query string and is within the start and end indexes. If no\n * matches are found, -1 will be returned instead.\n *\n * Since this is normally coming from a keydown event, the query *must* be a\n * string of all capital letters to work as each value will be converted to\n * uppercase before checking.\n * @internal\n */\nexport function findMatchInRange(options: MatchInRangeOptions): number {\n const { values, startIndex, endIndex } = options;\n if (
|
|
1
|
+
{"version":3,"sources":["../../src/movement/findMatchIndex.ts"],"sourcesContent":["/** @internal */\nexport interface BaseOptions {\n /**\n * The current query string to find within the values\n */\n value: string;\n\n /**\n * The list of values to search within\n */\n values: readonly string[];\n\n /**\n * The start index for the search\n */\n startIndex: number;\n}\n\n/** @internal */\nexport interface MatchInRangeOptions extends BaseOptions {\n /**\n * The end index for the search\n */\n endIndex: number;\n}\n\n/**\n * Attempts to find the first match index for a list of values that starts with\n * the provided query string and is within the start and end indexes. If no\n * matches are found, -1 will be returned instead.\n *\n * Since this is normally coming from a keydown event, the query *must* be a\n * string of all capital letters to work as each value will be converted to\n * uppercase before checking.\n * @internal\n */\nexport function findMatchInRange(options: MatchInRangeOptions): number {\n const { values, startIndex, endIndex } = options;\n if (values.length === 0) {\n return -1;\n }\n\n const value = options.value.toUpperCase();\n\n for (let i = startIndex; i < endIndex; i += 1) {\n const content = values[i];\n if (content.toUpperCase().indexOf(value) === 0) {\n return i;\n }\n }\n\n return -1;\n}\n\n/** @internal */\nexport interface MatchIndexOptions extends BaseOptions {\n /**\n * Boolean if the current index can be included in the search\n *\n * @defaultValue `true`\n */\n isSelfMatchable?: boolean;\n}\n\n/**\n * A function that is used to find the next match index within a list of values\n * by comparing the start values ignoring case.\n *\n * If a match can not be found from the search string, `-1` will be returned.\n * The search value is self-matchable by default, but it can be omitted by\n * disabling the `isSelfMatchable` argument. This will make a self-match return\n * `-1`.\n *\n * @internal\n */\nexport function findMatchIndex(options: MatchIndexOptions): number {\n const { value, values, startIndex, isSelfMatchable = true } = options;\n // this was added to support comboboxes when there are no options available\n if (values.length === 0) {\n return -1;\n }\n\n let index = findMatchInRange({\n value,\n values,\n startIndex: startIndex + 1,\n endIndex: values.length,\n });\n if (index === -1) {\n const endIndex = startIndex + (isSelfMatchable ? 1 : 0);\n index = findMatchInRange({\n value,\n values,\n startIndex: 0,\n endIndex,\n });\n }\n\n return index;\n}\n"],"names":["findMatchInRange","options","values","startIndex","endIndex","length","value","toUpperCase","i","content","indexOf","findMatchIndex","isSelfMatchable","index"],"mappings":"AAAA,cAAc,GA0Bd;;;;;;;;;CASC,GACD,OAAO,SAASA,iBAAiBC,OAA4B;IAC3D,MAAM,EAAEC,MAAM,EAAEC,UAAU,EAAEC,QAAQ,EAAE,GAAGH;IACzC,IAAIC,OAAOG,MAAM,KAAK,GAAG;QACvB,OAAO,CAAC;IACV;IAEA,MAAMC,QAAQL,QAAQK,KAAK,CAACC,WAAW;IAEvC,IAAK,IAAIC,IAAIL,YAAYK,IAAIJ,UAAUI,KAAK,EAAG;QAC7C,MAAMC,UAAUP,MAAM,CAACM,EAAE;QACzB,IAAIC,QAAQF,WAAW,GAAGG,OAAO,CAACJ,WAAW,GAAG;YAC9C,OAAOE;QACT;IACF;IAEA,OAAO,CAAC;AACV;AAYA;;;;;;;;;;CAUC,GACD,OAAO,SAASG,eAAeV,OAA0B;IACvD,MAAM,EAAEK,KAAK,EAAEJ,MAAM,EAAEC,UAAU,EAAES,kBAAkB,IAAI,EAAE,GAAGX;IAC9D,2EAA2E;IAC3E,IAAIC,OAAOG,MAAM,KAAK,GAAG;QACvB,OAAO,CAAC;IACV;IAEA,IAAIQ,QAAQb,iBAAiB;QAC3BM;QACAJ;QACAC,YAAYA,aAAa;QACzBC,UAAUF,OAAOG,MAAM;IACzB;IACA,IAAIQ,UAAU,CAAC,GAAG;QAChB,MAAMT,WAAWD,aAAcS,CAAAA,kBAAkB,IAAI,CAAA;QACrDC,QAAQb,iBAAiB;YACvBM;YACAJ;YACAC,YAAY;YACZC;QACF;IACF;IAEA,OAAOS;AACT"}
|
|
@@ -394,7 +394,7 @@ const returnNegative1 = ()=>-1;
|
|
|
394
394
|
}
|
|
395
395
|
const focusables = getFocusableElements(currentTarget, programmatic);
|
|
396
396
|
const focusedIndex = focusables.findIndex((element)=>element === target || element.contains(target));
|
|
397
|
-
if (focusedIndex === -1 ||
|
|
397
|
+
if (focusedIndex === -1 || focusables.length === 0) {
|
|
398
398
|
return;
|
|
399
399
|
}
|
|
400
400
|
currentFocusIndex.current = focusedIndex;
|
|
@@ -423,7 +423,7 @@ const returnNegative1 = ()=>-1;
|
|
|
423
423
|
return;
|
|
424
424
|
}
|
|
425
425
|
const focusables = getFocusableElements(event.currentTarget, programmatic);
|
|
426
|
-
if (
|
|
426
|
+
if (focusables.length === 0) {
|
|
427
427
|
return;
|
|
428
428
|
}
|
|
429
429
|
let defaultFocusIndex = getDefaultFocusedIndex({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/movement/useKeyboardMovementProvider.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { getFocusableElements as defaultGetFocusableElements } from \"../focus/utils.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useDir } from \"../typography/WritingDirectionProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport {\n DEFAULT_KEYBOARD_MOVEMENT,\n DEFAULT_LTR_KEYBOARD_MOVEMENT,\n DEFAULT_RTL_KEYBOARD_MOVEMENT,\n} from \"./constants.js\";\nimport { findMatchIndex } from \"./findMatchIndex.js\";\nimport {\n type KeyboardFocusFromKeyOptions,\n type KeyboardMovementConfig,\n type KeyboardMovementConfiguration,\n type KeyboardMovementContext,\n type KeyboardMovementProviderImplementation,\n type KeyboardMovementProviderOptions,\n type KeyboardMovementUpdateFocusIndexOptions,\n} from \"./types.js\";\nimport {\n getFirstFocusableIndex,\n getLastFocusableIndex,\n getNextFocusableIndex,\n getSearchText,\n getVirtualFocusDefaultIndex,\n isElementDisabled,\n isNotFocusable,\n isSearchableEvent,\n recalculateFocusIndex,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.3.0\n */\nexport const DEFAULT_KEYBOARD_MOVEMENT_CONTEXT: Readonly<KeyboardMovementContext> =\n {\n config: { current: DEFAULT_KEYBOARD_MOVEMENT },\n loopable: false,\n searchable: false,\n horizontal: false,\n includeDisabled: false,\n tabIndexBehavior: undefined,\n activeDescendantId: \"\",\n focusFirst: noop,\n focusLast: noop,\n focusNext: noop,\n focusPrevious: noop,\n focusFromKey: noop,\n focusCurrent: (): undefined => {},\n updateFocusIndex: noop,\n };\n\n/**\n * @since 5.0.0\n * @internal\n */\nconst context = createContext<KeyboardMovementContext>(\n DEFAULT_KEYBOARD_MOVEMENT_CONTEXT\n);\ncontext.displayName = \"KeyboardMovement\";\nexport const { Provider: KeyboardMovementProvider } = context;\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport function useKeyboardMovementContext(): Readonly<KeyboardMovementContext> {\n return useContext(context);\n}\n\nconst returnNegative1 = (): number => -1;\n\n/**\n * Implements the custom keyboard movement behavior throughout react-md. Using\n * the \"Find References\" will be the best way to see example usage.\n *\n * @example Default Keyboard Movement for any Focusable Element\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider();\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * {children}\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @example Active Descendant Movement\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementContext,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n * import { useId } from \"react\";\n *\n * function Child(): ReactElement {\n * const id = useId()\n * const { activeDescendantId } = useKeyboardMovementContext();\n *\n * return (\n * <div\n * {...props}\n * id={id}\n * className={cnb(id === activeDescendantId && \"focused-class-name\")}\n * >\n * Some Content\n * </div>\n * );\n * }\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider({\n * loopable: true,\n * searchable: true,\n * tabIndexBehavior: \"virtual\",\n * });\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * <Child />\n * <Child />\n * <Child />\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @example Roving Tab Index\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementContext,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n * import { useId } from \"react\";\n *\n * function Child(): ReactElement {\n * const id = useId()\n * const { activeDescendantId } = useKeyboardMovementContext();\n *\n * return (\n * <div\n * {...props}\n * id={id}\n * tabIndex={id === activeDescendantId ? 0 : -1}\n * >\n * Some Content\n * </div>\n * );\n * }\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider({\n * loopable: true,\n * searchable: true,\n * tabIndexBehavior: \"roving\",\n * });\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * <Child />\n * <Child />\n * <Child />\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n * @since 6.0.0\n * @internal\n */\nexport function useKeyboardMovementProvider<E extends HTMLElement>(\n options: KeyboardMovementProviderOptions<E> = {}\n): KeyboardMovementProviderImplementation<E> {\n const {\n ref: propRef,\n onClick = noop,\n onFocus = noop,\n onKeyDown = noop,\n loopable = false,\n disabled,\n searchable = false,\n horizontal = false,\n trackTabKeys = false,\n includeDisabled = false,\n tabIndexBehavior,\n extendKeyDown = noop,\n onFocusChange = noop,\n programmatic = includeDisabled,\n incrementKeys: propIncrementKeys,\n decrementKeys: propDecrementKeys,\n jumpToFirstKeys: propJumpToFirstKeys,\n jumpToLastKeys: propJumpToLastKeys,\n getFocusableElements = defaultGetFocusableElements,\n getDefaultFocusedIndex = returnNegative1,\n isNegativeOneAllowed = false,\n } = options;\n\n const [nodeRef, nodeRefCallback] = useEnsuredRef(propRef);\n\n const isRTL = useDir().dir === \"rtl\";\n let defaults: Readonly<Required<KeyboardMovementConfiguration>>;\n if (horizontal) {\n defaults = isRTL\n ? DEFAULT_RTL_KEYBOARD_MOVEMENT\n : DEFAULT_LTR_KEYBOARD_MOVEMENT;\n } else {\n defaults = DEFAULT_KEYBOARD_MOVEMENT;\n }\n\n const incrementKeys = propIncrementKeys || defaults.incrementKeys;\n const decrementKeys = propDecrementKeys || defaults.decrementKeys;\n const jumpToFirstKeys = propJumpToFirstKeys || defaults.jumpToFirstKeys;\n const jumpToLastKeys = propJumpToLastKeys || defaults.jumpToLastKeys;\n\n const configuration: KeyboardMovementConfig = {\n incrementKeys,\n decrementKeys,\n jumpToFirstKeys,\n jumpToLastKeys,\n };\n const config = useRef(configuration);\n useIsomorphicLayoutEffect(() => {\n config.current = configuration;\n });\n\n const mode = useUserInteractionMode();\n const refocus = useRef(false);\n const currentFocusIndex = useRef(-1);\n const [activeDescendantId, setActiveDescendantId] = useState(\"\");\n\n if (process.env.NODE_ENV !== \"production\") {\n // this fixes issues during hot reloading and using the `useId()` hook\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n return () => {\n setActiveDescendantId(\"\");\n };\n }, []);\n }\n\n let tabIndex: number | undefined;\n if (tabIndexBehavior) {\n tabIndex =\n disabled || (tabIndexBehavior === \"roving\" && activeDescendantId)\n ? -1\n : 0;\n }\n\n const getFocusableElementsFromRef = useCallback(() => {\n const container = nodeRef.current;\n if (!container) {\n return [];\n }\n\n return getFocusableElements(container, programmatic);\n }, [getFocusableElements, nodeRef, programmatic]);\n const focusCurrent = useCallback(\n (focusables = getFocusableElementsFromRef()): HTMLElement | undefined => {\n const index = currentFocusIndex.current;\n if (index === -1) {\n return;\n }\n\n const focused = focusables[index];\n if (!focused) {\n return;\n }\n\n if (tabIndexBehavior) {\n focused.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n setActiveDescendantId(focused.id);\n }\n\n if (tabIndexBehavior !== \"virtual\") {\n focused.focus();\n }\n\n return focused;\n },\n [getFocusableElementsFromRef, tabIndexBehavior]\n );\n const updateFocusIndex = useCallback(\n (options: KeyboardMovementUpdateFocusIndexOptions) => {\n const {\n index,\n force,\n focusables = getFocusableElementsFromRef(),\n } = options;\n const isSameIndex = currentFocusIndex.current === index;\n if ((!force && isSameIndex) || index === -1) {\n return;\n }\n\n currentFocusIndex.current = index;\n const focused = focusCurrent(focusables);\n if (focused && !isSameIndex) {\n onFocusChange({\n index,\n element: focused,\n });\n }\n },\n [focusCurrent, getFocusableElementsFromRef, onFocusChange]\n );\n\n const focusNext = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getNextFocusableIndex({\n loopable,\n increment: true,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, loopable, updateFocusIndex]\n );\n const focusPrevious = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getNextFocusableIndex({\n loopable,\n increment: false,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, loopable, updateFocusIndex]\n );\n const focusFirst = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getFirstFocusableIndex({\n focusables,\n includeDisabled,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]\n );\n const focusLast = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getLastFocusableIndex({\n focusables,\n includeDisabled,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]\n );\n const focusFromKey = useCallback(\n (options: KeyboardFocusFromKeyOptions) => {\n const {\n key,\n force,\n reversed,\n focusables = getFocusableElementsFromRef(),\n } = options;\n if (!searchable) {\n return;\n }\n\n const index = findMatchIndex({\n value: key,\n values: focusables.map((element) =>\n getSearchText(element, !isNotFocusable(element, includeDisabled))\n ),\n startIndex: reversed ? -1 : currentFocusIndex.current,\n });\n updateFocusIndex({ index, force, focusables });\n },\n [getFocusableElementsFromRef, includeDisabled, searchable, updateFocusIndex]\n );\n\n const movementContext = useMemo<KeyboardMovementContext>(\n () => ({\n config,\n loopable,\n searchable,\n horizontal,\n focusFirst,\n focusLast,\n focusNext,\n focusPrevious,\n focusFromKey,\n focusCurrent,\n updateFocusIndex,\n includeDisabled,\n tabIndexBehavior,\n activeDescendantId,\n }),\n [\n activeDescendantId,\n focusCurrent,\n focusFirst,\n focusFromKey,\n focusLast,\n focusNext,\n focusPrevious,\n horizontal,\n includeDisabled,\n loopable,\n searchable,\n tabIndexBehavior,\n updateFocusIndex,\n ]\n );\n\n return {\n nodeRef,\n movementProps: {\n \"aria-activedescendant\":\n tabIndexBehavior === \"virtual\" ? activeDescendantId : undefined,\n ref: nodeRefCallback,\n tabIndex,\n\n // Note: This used to be on the `onFocus` event, but this causes issues in\n // Chromium browsers for drag and drop behavior\n onClick(event) {\n onClick(event);\n if (disabled) {\n return;\n }\n\n // This makes it so you can click an element with a mouse and then\n // keyboard navigate from that element instead of the last keyboard focus\n // element\n const { currentTarget, target } = event;\n if (target === currentTarget || !(target instanceof HTMLElement)) {\n return;\n }\n\n const focusables = getFocusableElements(currentTarget, programmatic);\n const focusedIndex = focusables.findIndex(\n (element) => element === target || element.contains(target)\n );\n if (focusedIndex === -1 || !focusables.length) {\n return;\n }\n\n currentFocusIndex.current = focusedIndex;\n const focused = focusables[focusedIndex];\n if (tabIndexBehavior) {\n setActiveDescendantId(focused.id);\n }\n\n // need to force focus back to the container element when using\n // aria activedescendant\n if (tabIndexBehavior === \"virtual\") {\n refocus.current = true;\n currentTarget.focus();\n }\n\n onFocusChange({\n index: focusedIndex,\n element: focused,\n });\n },\n onFocus(event) {\n onFocus(event);\n if (event.isPropagationStopped() || refocus.current) {\n refocus.current = false;\n return;\n }\n\n if (\n (mode !== \"keyboard\" && tabIndexBehavior !== \"virtual\") ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n\n const focusables = getFocusableElements(\n event.currentTarget,\n programmatic\n );\n if (!focusables.length) {\n return;\n }\n\n let defaultFocusIndex = getDefaultFocusedIndex({\n focusables,\n includeDisabled,\n });\n\n // This allows my custom `getDefaultFocusedIndex` implementations to\n // have a nice fallback without having to re-implement the \"focus\n // first\" behavior\n if (!isNegativeOneAllowed && defaultFocusIndex === -1) {\n if (tabIndexBehavior === \"virtual\") {\n // virtual keyboard navigation **must** always focus at least one element\n defaultFocusIndex = getVirtualFocusDefaultIndex({\n focusables,\n includeDisabled,\n activeDescendantId,\n });\n } else {\n defaultFocusIndex = getFirstFocusableIndex({\n focusables,\n includeDisabled,\n });\n }\n }\n\n if (defaultFocusIndex === -1) {\n return;\n }\n\n currentFocusIndex.current = defaultFocusIndex;\n const focused = focusables[defaultFocusIndex];\n if (tabIndexBehavior) {\n setActiveDescendantId(focused.id);\n }\n\n if (tabIndexBehavior !== \"virtual\") {\n focused.focus();\n } else {\n focused.scrollIntoView({ block: \"nearest\" });\n }\n\n onFocusChange({\n index: defaultFocusIndex,\n element: focused,\n });\n },\n onKeyDown(event) {\n onKeyDown(event);\n if (disabled) {\n return;\n }\n\n const { currentTarget } = event;\n\n const setFocusIndex = (\n index: number,\n focusables: readonly HTMLElement[]\n ): void => {\n event.preventDefault();\n event.stopPropagation();\n updateFocusIndex({ index, focusables });\n };\n\n extendKeyDown({\n event,\n setFocusIndex,\n currentFocusIndex,\n setActiveDescendantId,\n ...movementContext,\n });\n\n if (event.isPropagationStopped()) {\n return;\n }\n\n // TODO: Figure this part out. This is currently required for the tree\n // movement when the asterisk key is pressed. There might be other cases\n // as well.\n if (!isNegativeOneAllowed && currentFocusIndex.current === -1) {\n currentFocusIndex.current = recalculateFocusIndex({\n focusables: getFocusableElements(currentTarget, programmatic),\n includeDisabled,\n tabIndexBehavior,\n activeDescendantId,\n });\n }\n\n const { key, shiftKey } = event;\n if (\n tabIndexBehavior === \"virtual\" &&\n activeDescendantId &&\n (key === \" \" || key === \"Enter\")\n ) {\n if (key === \" \") {\n event.preventDefault();\n }\n\n const focusables = getFocusableElements(currentTarget, programmatic);\n const activeElement = focusables[currentFocusIndex.current];\n if (!activeElement || isElementDisabled(activeElement)) {\n return;\n }\n\n activeElement.click();\n return;\n }\n\n const {\n incrementKeys,\n decrementKeys,\n jumpToFirstKeys,\n jumpToLastKeys,\n } = config.current;\n\n if (searchable && isSearchableEvent(event)) {\n event.preventDefault();\n event.stopPropagation();\n focusFromKey({ key, reversed: shiftKey });\n return;\n }\n\n if (trackTabKeys && key === \"Tab\") {\n currentFocusIndex.current = getNextFocusableIndex({\n loopable,\n increment: !event.shiftKey,\n focusables: getFocusableElements(currentTarget, programmatic),\n includeDisabled,\n currentFocusIndex: currentFocusIndex.current,\n });\n return;\n }\n\n const jumpToFirst = jumpToFirstKeys.includes(key);\n const jumpToLast = !jumpToFirst && jumpToLastKeys.includes(key);\n const increment =\n !jumpToFirst && !jumpToLast && incrementKeys.includes(key);\n const decrement =\n !jumpToFirst &&\n !jumpToLast &&\n !increment &&\n decrementKeys.includes(key);\n\n if (jumpToFirst || jumpToLast || increment || decrement) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (jumpToFirst) {\n focusFirst();\n } else if (jumpToLast) {\n focusLast();\n } else if (increment) {\n focusNext();\n } else if (decrement) {\n focusPrevious();\n }\n },\n },\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n };\n}\n"],"names":["createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","getFocusableElements","defaultGetFocusableElements","useUserInteractionMode","useDir","useEnsuredRef","useIsomorphicLayoutEffect","DEFAULT_KEYBOARD_MOVEMENT","DEFAULT_LTR_KEYBOARD_MOVEMENT","DEFAULT_RTL_KEYBOARD_MOVEMENT","findMatchIndex","getFirstFocusableIndex","getLastFocusableIndex","getNextFocusableIndex","getSearchText","getVirtualFocusDefaultIndex","isElementDisabled","isNotFocusable","isSearchableEvent","recalculateFocusIndex","noop","DEFAULT_KEYBOARD_MOVEMENT_CONTEXT","config","current","loopable","searchable","horizontal","includeDisabled","tabIndexBehavior","undefined","activeDescendantId","focusFirst","focusLast","focusNext","focusPrevious","focusFromKey","focusCurrent","updateFocusIndex","context","displayName","Provider","KeyboardMovementProvider","useKeyboardMovementContext","returnNegative1","useKeyboardMovementProvider","options","ref","propRef","onClick","onFocus","onKeyDown","disabled","trackTabKeys","extendKeyDown","onFocusChange","programmatic","incrementKeys","propIncrementKeys","decrementKeys","propDecrementKeys","jumpToFirstKeys","propJumpToFirstKeys","jumpToLastKeys","propJumpToLastKeys","getDefaultFocusedIndex","isNegativeOneAllowed","nodeRef","nodeRefCallback","isRTL","dir","defaults","configuration","mode","refocus","currentFocusIndex","setActiveDescendantId","process","env","NODE_ENV","tabIndex","getFocusableElementsFromRef","container","focusables","index","focused","scrollIntoView","block","inline","id","focus","force","isSameIndex","element","increment","key","reversed","value","values","map","startIndex","movementContext","movementProps","event","currentTarget","target","HTMLElement","focusedIndex","findIndex","contains","length","isPropagationStopped","defaultFocusIndex","setFocusIndex","preventDefault","stopPropagation","shiftKey","activeElement","click","jumpToFirst","includes","jumpToLast","decrement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/movement/useKeyboardMovementProvider.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { getFocusableElements as defaultGetFocusableElements } from \"../focus/utils.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useDir } from \"../typography/WritingDirectionProvider.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect.js\";\nimport {\n DEFAULT_KEYBOARD_MOVEMENT,\n DEFAULT_LTR_KEYBOARD_MOVEMENT,\n DEFAULT_RTL_KEYBOARD_MOVEMENT,\n} from \"./constants.js\";\nimport { findMatchIndex } from \"./findMatchIndex.js\";\nimport {\n type KeyboardFocusFromKeyOptions,\n type KeyboardMovementConfig,\n type KeyboardMovementConfiguration,\n type KeyboardMovementContext,\n type KeyboardMovementProviderImplementation,\n type KeyboardMovementProviderOptions,\n type KeyboardMovementUpdateFocusIndexOptions,\n} from \"./types.js\";\nimport {\n getFirstFocusableIndex,\n getLastFocusableIndex,\n getNextFocusableIndex,\n getSearchText,\n getVirtualFocusDefaultIndex,\n isElementDisabled,\n isNotFocusable,\n isSearchableEvent,\n recalculateFocusIndex,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.3.0\n */\nexport const DEFAULT_KEYBOARD_MOVEMENT_CONTEXT: Readonly<KeyboardMovementContext> =\n {\n config: { current: DEFAULT_KEYBOARD_MOVEMENT },\n loopable: false,\n searchable: false,\n horizontal: false,\n includeDisabled: false,\n tabIndexBehavior: undefined,\n activeDescendantId: \"\",\n focusFirst: noop,\n focusLast: noop,\n focusNext: noop,\n focusPrevious: noop,\n focusFromKey: noop,\n focusCurrent: (): undefined => {},\n updateFocusIndex: noop,\n };\n\n/**\n * @since 5.0.0\n * @internal\n */\nconst context = createContext<KeyboardMovementContext>(\n DEFAULT_KEYBOARD_MOVEMENT_CONTEXT\n);\ncontext.displayName = \"KeyboardMovement\";\nexport const { Provider: KeyboardMovementProvider } = context;\n\n/**\n * @since 5.0.0\n * @internal\n */\nexport function useKeyboardMovementContext(): Readonly<KeyboardMovementContext> {\n return useContext(context);\n}\n\nconst returnNegative1 = (): number => -1;\n\n/**\n * Implements the custom keyboard movement behavior throughout react-md. Using\n * the \"Find References\" will be the best way to see example usage.\n *\n * @example Default Keyboard Movement for any Focusable Element\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider();\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * {children}\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @example Active Descendant Movement\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementContext,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n * import { useId } from \"react\";\n *\n * function Child(): ReactElement {\n * const id = useId()\n * const { activeDescendantId } = useKeyboardMovementContext();\n *\n * return (\n * <div\n * {...props}\n * id={id}\n * className={cnb(id === activeDescendantId && \"focused-class-name\")}\n * >\n * Some Content\n * </div>\n * );\n * }\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider({\n * loopable: true,\n * searchable: true,\n * tabIndexBehavior: \"virtual\",\n * });\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * <Child />\n * <Child />\n * <Child />\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @example Roving Tab Index\n * ```tsx\n * import {\n * KeyboardMovementProvider,\n * useKeyboardMovementContext,\n * useKeyboardMovementProvider,\n * } from \"@react-md/core/movement/useKeyboardMovementProvider\";\n * import type { ReactElement, ReactNode } from \"react\";\n * import { useId } from \"react\";\n *\n * function Child(): ReactElement {\n * const id = useId()\n * const { activeDescendantId } = useKeyboardMovementContext();\n *\n * return (\n * <div\n * {...props}\n * id={id}\n * tabIndex={id === activeDescendantId ? 0 : -1}\n * >\n * Some Content\n * </div>\n * );\n * }\n *\n * function Example({ children }: { children: ReactNode }): ReactElement {\n * const { movementContext, movementProps } = useKeyboardMovementProvider({\n * loopable: true,\n * searchable: true,\n * tabIndexBehavior: \"roving\",\n * });\n *\n * // any focusable element child can be focused with the arrow , home, and\n * // end keys\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <div {...movementProps}>\n * <Child />\n * <Child />\n * <Child />\n * </div>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n * @since 6.0.0\n * @internal\n */\nexport function useKeyboardMovementProvider<E extends HTMLElement>(\n options: KeyboardMovementProviderOptions<E> = {}\n): KeyboardMovementProviderImplementation<E> {\n const {\n ref: propRef,\n onClick = noop,\n onFocus = noop,\n onKeyDown = noop,\n loopable = false,\n disabled,\n searchable = false,\n horizontal = false,\n trackTabKeys = false,\n includeDisabled = false,\n tabIndexBehavior,\n extendKeyDown = noop,\n onFocusChange = noop,\n programmatic = includeDisabled,\n incrementKeys: propIncrementKeys,\n decrementKeys: propDecrementKeys,\n jumpToFirstKeys: propJumpToFirstKeys,\n jumpToLastKeys: propJumpToLastKeys,\n getFocusableElements = defaultGetFocusableElements,\n getDefaultFocusedIndex = returnNegative1,\n isNegativeOneAllowed = false,\n } = options;\n\n const [nodeRef, nodeRefCallback] = useEnsuredRef(propRef);\n\n const isRTL = useDir().dir === \"rtl\";\n let defaults: Readonly<Required<KeyboardMovementConfiguration>>;\n if (horizontal) {\n defaults = isRTL\n ? DEFAULT_RTL_KEYBOARD_MOVEMENT\n : DEFAULT_LTR_KEYBOARD_MOVEMENT;\n } else {\n defaults = DEFAULT_KEYBOARD_MOVEMENT;\n }\n\n const incrementKeys = propIncrementKeys || defaults.incrementKeys;\n const decrementKeys = propDecrementKeys || defaults.decrementKeys;\n const jumpToFirstKeys = propJumpToFirstKeys || defaults.jumpToFirstKeys;\n const jumpToLastKeys = propJumpToLastKeys || defaults.jumpToLastKeys;\n\n const configuration: KeyboardMovementConfig = {\n incrementKeys,\n decrementKeys,\n jumpToFirstKeys,\n jumpToLastKeys,\n };\n const config = useRef(configuration);\n useIsomorphicLayoutEffect(() => {\n config.current = configuration;\n });\n\n const mode = useUserInteractionMode();\n const refocus = useRef(false);\n const currentFocusIndex = useRef(-1);\n const [activeDescendantId, setActiveDescendantId] = useState(\"\");\n\n if (process.env.NODE_ENV !== \"production\") {\n // this fixes issues during hot reloading and using the `useId()` hook\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n return () => {\n setActiveDescendantId(\"\");\n };\n }, []);\n }\n\n let tabIndex: number | undefined;\n if (tabIndexBehavior) {\n tabIndex =\n disabled || (tabIndexBehavior === \"roving\" && activeDescendantId)\n ? -1\n : 0;\n }\n\n const getFocusableElementsFromRef = useCallback(() => {\n const container = nodeRef.current;\n if (!container) {\n return [];\n }\n\n return getFocusableElements(container, programmatic);\n }, [getFocusableElements, nodeRef, programmatic]);\n const focusCurrent = useCallback(\n (focusables = getFocusableElementsFromRef()): HTMLElement | undefined => {\n const index = currentFocusIndex.current;\n if (index === -1) {\n return;\n }\n\n const focused = focusables[index];\n if (!focused) {\n return;\n }\n\n if (tabIndexBehavior) {\n focused.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n setActiveDescendantId(focused.id);\n }\n\n if (tabIndexBehavior !== \"virtual\") {\n focused.focus();\n }\n\n return focused;\n },\n [getFocusableElementsFromRef, tabIndexBehavior]\n );\n const updateFocusIndex = useCallback(\n (options: KeyboardMovementUpdateFocusIndexOptions) => {\n const {\n index,\n force,\n focusables = getFocusableElementsFromRef(),\n } = options;\n const isSameIndex = currentFocusIndex.current === index;\n if ((!force && isSameIndex) || index === -1) {\n return;\n }\n\n currentFocusIndex.current = index;\n const focused = focusCurrent(focusables);\n if (focused && !isSameIndex) {\n onFocusChange({\n index,\n element: focused,\n });\n }\n },\n [focusCurrent, getFocusableElementsFromRef, onFocusChange]\n );\n\n const focusNext = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getNextFocusableIndex({\n loopable,\n increment: true,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, loopable, updateFocusIndex]\n );\n const focusPrevious = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getNextFocusableIndex({\n loopable,\n increment: false,\n focusables,\n includeDisabled: true,\n currentFocusIndex: currentFocusIndex.current,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, loopable, updateFocusIndex]\n );\n const focusFirst = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getFirstFocusableIndex({\n focusables,\n includeDisabled,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]\n );\n const focusLast = useCallback(\n (focusables = getFocusableElementsFromRef(), force = false) => {\n updateFocusIndex({\n index: getLastFocusableIndex({\n focusables,\n includeDisabled,\n }),\n force,\n focusables,\n });\n },\n [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]\n );\n const focusFromKey = useCallback(\n (options: KeyboardFocusFromKeyOptions) => {\n const {\n key,\n force,\n reversed,\n focusables = getFocusableElementsFromRef(),\n } = options;\n if (!searchable) {\n return;\n }\n\n const index = findMatchIndex({\n value: key,\n values: focusables.map((element) =>\n getSearchText(element, !isNotFocusable(element, includeDisabled))\n ),\n startIndex: reversed ? -1 : currentFocusIndex.current,\n });\n updateFocusIndex({ index, force, focusables });\n },\n [getFocusableElementsFromRef, includeDisabled, searchable, updateFocusIndex]\n );\n\n const movementContext = useMemo<KeyboardMovementContext>(\n () => ({\n config,\n loopable,\n searchable,\n horizontal,\n focusFirst,\n focusLast,\n focusNext,\n focusPrevious,\n focusFromKey,\n focusCurrent,\n updateFocusIndex,\n includeDisabled,\n tabIndexBehavior,\n activeDescendantId,\n }),\n [\n activeDescendantId,\n focusCurrent,\n focusFirst,\n focusFromKey,\n focusLast,\n focusNext,\n focusPrevious,\n horizontal,\n includeDisabled,\n loopable,\n searchable,\n tabIndexBehavior,\n updateFocusIndex,\n ]\n );\n\n return {\n nodeRef,\n movementProps: {\n \"aria-activedescendant\":\n tabIndexBehavior === \"virtual\" ? activeDescendantId : undefined,\n ref: nodeRefCallback,\n tabIndex,\n\n // Note: This used to be on the `onFocus` event, but this causes issues in\n // Chromium browsers for drag and drop behavior\n onClick(event) {\n onClick(event);\n if (disabled) {\n return;\n }\n\n // This makes it so you can click an element with a mouse and then\n // keyboard navigate from that element instead of the last keyboard focus\n // element\n const { currentTarget, target } = event;\n if (target === currentTarget || !(target instanceof HTMLElement)) {\n return;\n }\n\n const focusables = getFocusableElements(currentTarget, programmatic);\n const focusedIndex = focusables.findIndex(\n (element) => element === target || element.contains(target)\n );\n if (focusedIndex === -1 || focusables.length === 0) {\n return;\n }\n\n currentFocusIndex.current = focusedIndex;\n const focused = focusables[focusedIndex];\n if (tabIndexBehavior) {\n setActiveDescendantId(focused.id);\n }\n\n // need to force focus back to the container element when using\n // aria activedescendant\n if (tabIndexBehavior === \"virtual\") {\n refocus.current = true;\n currentTarget.focus();\n }\n\n onFocusChange({\n index: focusedIndex,\n element: focused,\n });\n },\n onFocus(event) {\n onFocus(event);\n if (event.isPropagationStopped() || refocus.current) {\n refocus.current = false;\n return;\n }\n\n if (\n (mode !== \"keyboard\" && tabIndexBehavior !== \"virtual\") ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n\n const focusables = getFocusableElements(\n event.currentTarget,\n programmatic\n );\n if (focusables.length === 0) {\n return;\n }\n\n let defaultFocusIndex = getDefaultFocusedIndex({\n focusables,\n includeDisabled,\n });\n\n // This allows my custom `getDefaultFocusedIndex` implementations to\n // have a nice fallback without having to re-implement the \"focus\n // first\" behavior\n if (!isNegativeOneAllowed && defaultFocusIndex === -1) {\n if (tabIndexBehavior === \"virtual\") {\n // virtual keyboard navigation **must** always focus at least one element\n defaultFocusIndex = getVirtualFocusDefaultIndex({\n focusables,\n includeDisabled,\n activeDescendantId,\n });\n } else {\n defaultFocusIndex = getFirstFocusableIndex({\n focusables,\n includeDisabled,\n });\n }\n }\n\n if (defaultFocusIndex === -1) {\n return;\n }\n\n currentFocusIndex.current = defaultFocusIndex;\n const focused = focusables[defaultFocusIndex];\n if (tabIndexBehavior) {\n setActiveDescendantId(focused.id);\n }\n\n if (tabIndexBehavior !== \"virtual\") {\n focused.focus();\n } else {\n focused.scrollIntoView({ block: \"nearest\" });\n }\n\n onFocusChange({\n index: defaultFocusIndex,\n element: focused,\n });\n },\n onKeyDown(event) {\n onKeyDown(event);\n if (disabled) {\n return;\n }\n\n const { currentTarget } = event;\n\n const setFocusIndex = (\n index: number,\n focusables: readonly HTMLElement[]\n ): void => {\n event.preventDefault();\n event.stopPropagation();\n updateFocusIndex({ index, focusables });\n };\n\n extendKeyDown({\n event,\n setFocusIndex,\n currentFocusIndex,\n setActiveDescendantId,\n ...movementContext,\n });\n\n if (event.isPropagationStopped()) {\n return;\n }\n\n // TODO: Figure this part out. This is currently required for the tree\n // movement when the asterisk key is pressed. There might be other cases\n // as well.\n if (!isNegativeOneAllowed && currentFocusIndex.current === -1) {\n currentFocusIndex.current = recalculateFocusIndex({\n focusables: getFocusableElements(currentTarget, programmatic),\n includeDisabled,\n tabIndexBehavior,\n activeDescendantId,\n });\n }\n\n const { key, shiftKey } = event;\n if (\n tabIndexBehavior === \"virtual\" &&\n activeDescendantId &&\n (key === \" \" || key === \"Enter\")\n ) {\n if (key === \" \") {\n event.preventDefault();\n }\n\n const focusables = getFocusableElements(currentTarget, programmatic);\n const activeElement = focusables[currentFocusIndex.current];\n if (!activeElement || isElementDisabled(activeElement)) {\n return;\n }\n\n activeElement.click();\n return;\n }\n\n const {\n incrementKeys,\n decrementKeys,\n jumpToFirstKeys,\n jumpToLastKeys,\n } = config.current;\n\n if (searchable && isSearchableEvent(event)) {\n event.preventDefault();\n event.stopPropagation();\n focusFromKey({ key, reversed: shiftKey });\n return;\n }\n\n if (trackTabKeys && key === \"Tab\") {\n currentFocusIndex.current = getNextFocusableIndex({\n loopable,\n increment: !event.shiftKey,\n focusables: getFocusableElements(currentTarget, programmatic),\n includeDisabled,\n currentFocusIndex: currentFocusIndex.current,\n });\n return;\n }\n\n const jumpToFirst = jumpToFirstKeys.includes(key);\n const jumpToLast = !jumpToFirst && jumpToLastKeys.includes(key);\n const increment =\n !jumpToFirst && !jumpToLast && incrementKeys.includes(key);\n const decrement =\n !jumpToFirst &&\n !jumpToLast &&\n !increment &&\n decrementKeys.includes(key);\n\n if (jumpToFirst || jumpToLast || increment || decrement) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (jumpToFirst) {\n focusFirst();\n } else if (jumpToLast) {\n focusLast();\n } else if (increment) {\n focusNext();\n } else if (decrement) {\n focusPrevious();\n }\n },\n },\n movementContext,\n currentFocusIndex,\n activeDescendantId,\n setActiveDescendantId,\n };\n}\n"],"names":["createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","getFocusableElements","defaultGetFocusableElements","useUserInteractionMode","useDir","useEnsuredRef","useIsomorphicLayoutEffect","DEFAULT_KEYBOARD_MOVEMENT","DEFAULT_LTR_KEYBOARD_MOVEMENT","DEFAULT_RTL_KEYBOARD_MOVEMENT","findMatchIndex","getFirstFocusableIndex","getLastFocusableIndex","getNextFocusableIndex","getSearchText","getVirtualFocusDefaultIndex","isElementDisabled","isNotFocusable","isSearchableEvent","recalculateFocusIndex","noop","DEFAULT_KEYBOARD_MOVEMENT_CONTEXT","config","current","loopable","searchable","horizontal","includeDisabled","tabIndexBehavior","undefined","activeDescendantId","focusFirst","focusLast","focusNext","focusPrevious","focusFromKey","focusCurrent","updateFocusIndex","context","displayName","Provider","KeyboardMovementProvider","useKeyboardMovementContext","returnNegative1","useKeyboardMovementProvider","options","ref","propRef","onClick","onFocus","onKeyDown","disabled","trackTabKeys","extendKeyDown","onFocusChange","programmatic","incrementKeys","propIncrementKeys","decrementKeys","propDecrementKeys","jumpToFirstKeys","propJumpToFirstKeys","jumpToLastKeys","propJumpToLastKeys","getDefaultFocusedIndex","isNegativeOneAllowed","nodeRef","nodeRefCallback","isRTL","dir","defaults","configuration","mode","refocus","currentFocusIndex","setActiveDescendantId","process","env","NODE_ENV","tabIndex","getFocusableElementsFromRef","container","focusables","index","focused","scrollIntoView","block","inline","id","focus","force","isSameIndex","element","increment","key","reversed","value","values","map","startIndex","movementContext","movementProps","event","currentTarget","target","HTMLElement","focusedIndex","findIndex","contains","length","isPropagationStopped","defaultFocusIndex","setFocusIndex","preventDefault","stopPropagation","shiftKey","activeElement","click","jumpToFirst","includes","jumpToLast","decrement"],"mappings":"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"}
|
package/dist/movement/utils.js
CHANGED
|
@@ -20,7 +20,7 @@ import { loop } from "../utils/loop.js";
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/ export const getVirtualFocusDefaultIndex = (options)=>{
|
|
22
22
|
const { focusables, includeDisabled, activeDescendantId } = options;
|
|
23
|
-
if (
|
|
23
|
+
if (focusables.length === 0 || !activeDescendantId && includeDisabled) {
|
|
24
24
|
return 0;
|
|
25
25
|
}
|
|
26
26
|
const activeIndex = focusables.findIndex((element)=>{
|
|
@@ -36,7 +36,7 @@ import { loop } from "../utils/loop.js";
|
|
|
36
36
|
* @internal
|
|
37
37
|
*/ export const getFirstFocusableIndex = (options)=>{
|
|
38
38
|
const { focusables, includeDisabled } = options;
|
|
39
|
-
if (
|
|
39
|
+
if (focusables.length === 0) {
|
|
40
40
|
return -1;
|
|
41
41
|
}
|
|
42
42
|
let firstIndex = 0;
|
|
@@ -53,7 +53,7 @@ import { loop } from "../utils/loop.js";
|
|
|
53
53
|
* @internal
|
|
54
54
|
*/ export const getLastFocusableIndex = (options)=>{
|
|
55
55
|
const { focusables, includeDisabled } = options;
|
|
56
|
-
if (
|
|
56
|
+
if (focusables.length === 0) {
|
|
57
57
|
return -1;
|
|
58
58
|
}
|
|
59
59
|
let lastIndex = focusables.length - 1;
|
|
@@ -70,7 +70,7 @@ import { loop } from "../utils/loop.js";
|
|
|
70
70
|
* @internal
|
|
71
71
|
*/ export const getNextFocusableIndex = (options)=>{
|
|
72
72
|
const { loopable, increment, focusables, includeDisabled, currentFocusIndex } = options;
|
|
73
|
-
if (
|
|
73
|
+
if (focusables.length === 0) {
|
|
74
74
|
return currentFocusIndex;
|
|
75
75
|
}
|
|
76
76
|
const min = getFirstFocusableIndex({
|
|
@@ -109,10 +109,11 @@ import { loop } from "../utils/loop.js";
|
|
|
109
109
|
return "";
|
|
110
110
|
}
|
|
111
111
|
const cloned = element.cloneNode(true);
|
|
112
|
-
cloned.querySelectorAll(// Note: do not include DISPLAY_NONE_CLASS since it is presentational only
|
|
113
|
-
".rmd-icon--font,[aria-hidden=true],[hidden],[role=presentation]")
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
const invisibleElements = cloned.querySelectorAll(// Note: do not include DISPLAY_NONE_CLASS since it is presentational only
|
|
113
|
+
".rmd-icon--font,[aria-hidden=true],[hidden],[role=presentation]");
|
|
114
|
+
for (const element of invisibleElements){
|
|
115
|
+
element.remove();
|
|
116
|
+
}
|
|
116
117
|
// Note: It would be good to use `cloned.innerText` (maybe?) at some point,
|
|
117
118
|
// but it returns `undefined` in jsdom. It also does cause a reflow, so maybe
|
|
118
119
|
// this is fine?
|
|
@@ -135,8 +136,9 @@ import { loop } from "../utils/loop.js";
|
|
|
135
136
|
activeDescendantId
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
// do type-casting since the types don't matter much here
|
|
140
|
+
const activeElement = document.activeElement;
|
|
141
|
+
return focusables.indexOf(activeElement);
|
|
140
142
|
}
|
|
141
143
|
/**
|
|
142
144
|
* Checks if a keyboard event can trigger a search through focusable elements
|