@mui/x-charts
Version:
The community edition of MUI X Charts components.
117 lines (115 loc) • 4.63 kB
JavaScript
;
'use client';
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useChartKeyboardNavigation = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
var _useChartSeries = require("../../corePlugins/useChartSeries/useChartSeries.selectors");
var _useChartSeriesConfig = require("../../corePlugins/useChartSeriesConfig");
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', (0, _extends2.default)({}, store.state.keyboardNavigation, {
isFocused: false
}));
}
}
}
function restoreFocus() {
if (!store.state.keyboardNavigation.isFocused) {
store.update((0, _extends2.default)({}, store.state.highlight && {
highlight: (0, _extends2.default)({}, store.state.highlight, {
lastUpdate: 'keyboard'
})
}, store.state.interaction && {
interaction: (0, _extends2.default)({}, store.state.interaction, {
lastUpdate: 'keyboard'
})
}, {
keyboardNavigation: (0, _extends2.default)({}, store.state.keyboardNavigation, {
isFocused: true
})
}));
}
}
function keyboardHandler(event) {
let newFocusedItem = store.state.keyboardNavigation.item;
const seriesConfig = (0, _useChartSeriesConfig.selectorChartSeriesConfig)(store.state);
let seriesType = newFocusedItem?.type;
if (!seriesType) {
seriesType = Object.keys((0, _useChartSeries.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((0, _extends2.default)({}, store.state.highlight && {
highlight: (0, _extends2.default)({}, store.state.highlight, {
lastUpdate: 'keyboard'
})
}, store.state.interaction && {
interaction: (0, _extends2.default)({}, store.state.interaction, {
lastUpdate: 'keyboard'
})
}, {
keyboardNavigation: (0, _extends2.default)({}, 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]);
(0, _useEnhancedEffect.default)(() => {
store.set('keyboardNavigation', (0, _extends2.default)({}, store.state.keyboardNavigation, {
enabled: !params.disableKeyboardNavigation
}));
}, [store, params.disableKeyboardNavigation]);
return {};
};
exports.useChartKeyboardNavigation = useChartKeyboardNavigation;
useChartKeyboardNavigation.getInitialState = params => ({
keyboardNavigation: {
item: null,
isFocused: false,
enabled: !params.disableKeyboardNavigation
}
});
useChartKeyboardNavigation.params = {
disableKeyboardNavigation: true
};