@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
237 lines (236 loc) • 8.09 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const React = require("react");
const styles = require("@mui/material/styles");
const utils = require("@mui/material/utils");
const utils$1 = require("../utils.cjs");
function _interopNamespace(e) {
if (e && e.__esModule) return e;
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
if (e) {
for (const k in e) {
if (k !== "default") {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
function isPrintableCharacter(string) {
return string && string.length === 1 && string.match(/\S/);
}
function findNextFirstChar(firstChars, startIndex, char) {
for (let i = startIndex; i < firstChars.length; i += 1) {
if (char === firstChars[i]) {
return i;
}
}
return -1;
}
const useTreeViewKeyboardNavigation = ({ instance, params, state }) => {
const theme = styles.useTheme();
const isRtl = theme.direction === "rtl";
const firstCharMap = React__namespace.useRef({});
const mapFirstChar = utils.useEventCallback((nodeId, firstChar) => {
firstCharMap.current[nodeId] = firstChar;
return () => {
const newMap = { ...firstCharMap.current };
delete newMap[nodeId];
firstCharMap.current = newMap;
};
});
utils$1.populateInstance(instance, {
mapFirstChar
});
const handleNextArrow = (event) => {
if (state.focusedNodeId != null && instance.isNodeExpandable(state.focusedNodeId)) {
if (instance.isNodeExpanded(state.focusedNodeId)) {
instance.focusNode(event, utils$1.getNextNode(instance, state.focusedNodeId));
} else if (!instance.isNodeDisabled(state.focusedNodeId)) {
instance.toggleNodeExpansion(event, state.focusedNodeId);
}
}
return true;
};
const handlePreviousArrow = (event) => {
if (state.focusedNodeId == null) {
return false;
}
if (instance.isNodeExpanded(state.focusedNodeId) && !instance.isNodeDisabled(state.focusedNodeId)) {
instance.toggleNodeExpansion(event, state.focusedNodeId);
return true;
}
const parent = instance.getNode(state.focusedNodeId).parentId;
if (parent) {
instance.focusNode(event, parent);
return true;
}
return false;
};
const focusByFirstCharacter = (event, nodeId, firstChar) => {
let start;
let index;
const lowercaseChar = firstChar.toLowerCase();
const firstCharIds = [];
const firstChars = [];
Object.keys(firstCharMap.current).forEach((mapNodeId) => {
const map = instance.getNode(mapNodeId);
const visible = map.parentId ? instance.isNodeExpanded(map.parentId) : true;
const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isNodeDisabled(mapNodeId);
if (visible && !shouldBeSkipped) {
firstCharIds.push(mapNodeId);
firstChars.push(firstCharMap.current[mapNodeId]);
}
});
start = firstCharIds.indexOf(nodeId) + 1;
if (start >= firstCharIds.length) {
start = 0;
}
index = findNextFirstChar(firstChars, start, lowercaseChar);
if (index === -1) {
index = findNextFirstChar(firstChars, 0, lowercaseChar);
}
if (index > -1) {
instance.focusNode(event, firstCharIds[index]);
}
};
const selectNextNode = (event, id) => {
if (!instance.isNodeDisabled(utils$1.getNextNode(instance, id))) {
instance.selectRange(
event,
{
end: utils$1.getNextNode(instance, id),
current: id
},
true
);
}
};
const selectPreviousNode = (event, nodeId) => {
if (!instance.isNodeDisabled(utils$1.getPreviousNode(instance, nodeId))) {
instance.selectRange(
event,
{
end: utils$1.getPreviousNode(instance, nodeId),
current: nodeId
},
true
);
}
};
const createHandleKeyDown = (otherHandlers) => (event) => {
otherHandlers.onKeyDown?.(event);
let flag = false;
const { key } = event;
if (event.altKey || event.currentTarget !== event.target || state.focusedNodeId == null) {
return;
}
const ctrlPressed = event.ctrlKey || event.metaKey;
switch (key) {
case " ":
if (!params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
flag = true;
if (params.multiSelect && event.shiftKey) {
instance.selectRange(event, { end: state.focusedNodeId });
} else if (params.multiSelect) {
instance.selectNode(event, state.focusedNodeId, true);
} else {
instance.selectNode(event, state.focusedNodeId);
}
}
event.stopPropagation();
break;
case "Enter":
if (!instance.isNodeDisabled(state.focusedNodeId)) {
if (instance.isNodeExpandable(state.focusedNodeId)) {
instance.toggleNodeExpansion(event, state.focusedNodeId);
flag = true;
} else if (!params.disableSelection) {
flag = true;
if (params.multiSelect) {
instance.selectNode(event, state.focusedNodeId, true);
} else {
instance.selectNode(event, state.focusedNodeId);
}
}
}
event.stopPropagation();
break;
case "ArrowDown":
if (params.multiSelect && event.shiftKey && !params.disableSelection) {
selectNextNode(event, state.focusedNodeId);
}
instance.focusNode(event, utils$1.getNextNode(instance, state.focusedNodeId));
flag = true;
break;
case "ArrowUp":
if (params.multiSelect && event.shiftKey && !params.disableSelection) {
selectPreviousNode(event, state.focusedNodeId);
}
instance.focusNode(
event,
utils$1.getPreviousNode(instance, state.focusedNodeId)
);
flag = true;
break;
case "ArrowRight":
if (isRtl) {
flag = handlePreviousArrow(event);
} else {
flag = handleNextArrow(event);
}
break;
case "ArrowLeft":
if (isRtl) {
flag = handleNextArrow(event);
} else {
flag = handlePreviousArrow(event);
}
break;
case "Home":
if (params.multiSelect && ctrlPressed && event.shiftKey && !params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
instance.rangeSelectToFirst(event, state.focusedNodeId);
}
instance.focusNode(event, utils$1.getFirstNode(instance));
flag = true;
break;
case "End":
if (params.multiSelect && ctrlPressed && event.shiftKey && !params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
instance.rangeSelectToLast(event, state.focusedNodeId);
}
instance.focusNode(event, utils$1.getLastNode(instance));
flag = true;
break;
default:
if (key === "*") {
instance.expandAllSiblings(event, state.focusedNodeId);
flag = true;
} else if (params.multiSelect && ctrlPressed && key.toLowerCase() === "a" && !params.disableSelection) {
instance.selectRange(event, {
start: utils$1.getFirstNode(instance),
end: utils$1.getLastNode(instance)
});
flag = true;
} else if (!ctrlPressed && !event.shiftKey && isPrintableCharacter(key)) {
focusByFirstCharacter(event, state.focusedNodeId, key);
flag = true;
}
}
if (flag) {
event.preventDefault();
event.stopPropagation();
}
};
return {
getRootProps: (otherHandlers) => ({
onKeyDown: createHandleKeyDown(otherHandlers)
})
};
};
exports.useTreeViewKeyboardNavigation = useTreeViewKeyboardNavigation;