UNPKG

@mui/x-charts

Version:

The community edition of MUI X Charts components.

109 lines (107 loc) 4.01 kB
'use client'; import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; import { selectorChartDefaultizedSeries } from "../../corePlugins/useChartSeries/useChartSeries.selectors.mjs"; import { selectorChartSeriesConfig } from "../../corePlugins/useChartSeriesConfig/index.mjs"; export const useChartKeyboardNavigation = ({ params, store, instance }) => { const { chartsLayerContainerRef } = instance; React.useEffect(() => { const element = chartsLayerContainerRef.current; if (!element || params.disableKeyboardNavigation) { return undefined; } function removeFocus(event) { const root = event.currentTarget; const next = event.relatedTarget; // Avoid removing focus if we know it is moving to another children in the chart. // This avoid extra computation ot remove/add focus at each keyboard pressed when navigating in the chart. if (root && next instanceof Node && !root.contains(next)) { if (store.state.keyboardNavigation.isFocused) { store.set('keyboardNavigation', _extends({}, store.state.keyboardNavigation, { isFocused: false })); } } } function restoreFocus() { if (!store.state.keyboardNavigation.isFocused) { store.update(_extends({}, store.state.highlight && { highlight: _extends({}, store.state.highlight, { lastUpdate: 'keyboard' }) }, store.state.interaction && { interaction: _extends({}, store.state.interaction, { lastUpdate: 'keyboard' }) }, { keyboardNavigation: _extends({}, store.state.keyboardNavigation, { isFocused: true }) })); } } function keyboardHandler(event) { let newFocusedItem = store.state.keyboardNavigation.item; const seriesConfig = selectorChartSeriesConfig(store.state); let seriesType = newFocusedItem?.type; if (!seriesType) { seriesType = Object.keys(selectorChartDefaultizedSeries(store.state)).find(key => seriesConfig[key] !== undefined); if (seriesType === undefined) { return; } } const calculateFocusedItem = seriesConfig[seriesType]?.keyboardFocusHandler?.(event); if (!calculateFocusedItem) { return; } newFocusedItem = calculateFocusedItem(newFocusedItem, store.state); if (newFocusedItem !== store.state.keyboardNavigation.item) { event.preventDefault(); store.update(_extends({}, store.state.highlight && { highlight: _extends({}, store.state.highlight, { lastUpdate: 'keyboard' }) }, store.state.interaction && { interaction: _extends({}, store.state.interaction, { lastUpdate: 'keyboard' }) }, { keyboardNavigation: _extends({}, store.state.keyboardNavigation, { item: newFocusedItem }) })); } } element.addEventListener('keydown', keyboardHandler); element.addEventListener('focusout', removeFocus); element.addEventListener('focusin', restoreFocus); return () => { element.removeEventListener('keydown', keyboardHandler); element.removeEventListener('focusout', removeFocus); element.removeEventListener('focusin', restoreFocus); }; }, [chartsLayerContainerRef, params.disableKeyboardNavigation, store]); useEnhancedEffect(() => { store.set('keyboardNavigation', _extends({}, store.state.keyboardNavigation, { enabled: !params.disableKeyboardNavigation })); }, [store, params.disableKeyboardNavigation]); return {}; }; useChartKeyboardNavigation.getInitialState = params => ({ keyboardNavigation: { item: null, isFocused: false, enabled: !params.disableKeyboardNavigation } }); useChartKeyboardNavigation.params = { disableKeyboardNavigation: true };