UNPKG

mui-component

Version:

some custom mui components

915 lines (893 loc) 33.8 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var _excluded = ["children", "className", "defaultCollapseIcon", "defaultEndIcon", "defaultExpanded", "defaultExpandIcon", "defaultParentIcon", "defaultSelected", "disabledItemsFocusable", "disableSelection", "expanded", "id", "multiSelect", "onBlur", "onFocus", "onKeyDown", "onNodeFocus", "onNodeSelect", "onNodeToggle", "selected"]; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } //@ts-nocheck /* eslint-disable jsdoc/require-param-type */ /* eslint-disable jsdoc/require-param-description */ import React from "react"; import clsx from "classnames"; import PropTypes from "prop-types"; import { styled, useTheme, useThemeProps } from "@mui/material/styles"; import { useControlled, useForkRef, ownerDocument } from "@mui/material/utils"; import { useId } from "@iimm/react-shared"; import TreeViewContext from "./TreeViewContext"; import { DescendantProvider } from "./descendants"; import { getTreeViewUtilityClass } from "./treeViewClasses"; import { composeClasses } from "../mui-utils"; import { jsx as _jsx } from "react/jsx-runtime"; var useUtilityClasses = function useUtilityClasses(ownerState) { var classes = ownerState.classes; var slots = { root: ["root"] }; return composeClasses(slots, getTreeViewUtilityClass, classes); }; var TreeViewRoot = styled("ul", { name: "MuiTreeView", slot: "Root", overridesResolver: function overridesResolver(props, styles) { return styles.root; } })({ padding: 0, margin: 0, listStyle: "none", outline: 0 }); function isPrintableCharacter(string) { return string && string.length === 1 && string.match(/\S/); } function findNextFirstChar(firstChars, startIndex, char) { for (var i = startIndex; i < firstChars.length; i += 1) { if (char === firstChars[i]) { return i; } } return -1; } function noopSelection() { return false; } var defaultDefaultExpanded = []; var defaultDefaultSelected = []; export var TreeView = /*#__PURE__*/React.forwardRef(function TreeView(inProps, ref) { var props = useThemeProps({ props: inProps, name: "MuiTreeView" }); var children = props.children, className = props.className, defaultCollapseIcon = props.defaultCollapseIcon, defaultEndIcon = props.defaultEndIcon, _props$defaultExpande = props.defaultExpanded, defaultExpanded = _props$defaultExpande === void 0 ? defaultDefaultExpanded : _props$defaultExpande, defaultExpandIcon = props.defaultExpandIcon, defaultParentIcon = props.defaultParentIcon, _props$defaultSelecte = props.defaultSelected, defaultSelected = _props$defaultSelecte === void 0 ? defaultDefaultSelected : _props$defaultSelecte, _props$disabledItemsF = props.disabledItemsFocusable, disabledItemsFocusable = _props$disabledItemsF === void 0 ? false : _props$disabledItemsF, _props$disableSelecti = props.disableSelection, disableSelection = _props$disableSelecti === void 0 ? false : _props$disableSelecti, expandedProp = props.expanded, idProp = props.id, _props$multiSelect = props.multiSelect, multiSelect = _props$multiSelect === void 0 ? false : _props$multiSelect, onBlur = props.onBlur, onFocus = props.onFocus, onKeyDown = props.onKeyDown, onNodeFocus = props.onNodeFocus, onNodeSelect = props.onNodeSelect, onNodeToggle = props.onNodeToggle, selectedProp = props.selected, other = _objectWithoutProperties(props, _excluded); var theme = useTheme(); var isRtl = theme.direction === "rtl"; var ownerState = _objectSpread(_objectSpread({}, props), {}, { defaultExpanded: defaultExpanded, defaultSelected: defaultSelected, disabledItemsFocusable: disabledItemsFocusable, disableSelection: disableSelection, multiSelect: multiSelect }); var classes = useUtilityClasses(ownerState); var treeId = useId(idProp); var treeRef = React.useRef(null); var handleRef = useForkRef(treeRef, ref); var _React$useState = React.useState(null), _React$useState2 = _slicedToArray(_React$useState, 2), focusedNodeId = _React$useState2[0], setFocusedNodeId = _React$useState2[1]; var nodeMap = React.useRef({}); var firstCharMap = React.useRef({}); var _useControlled = useControlled({ controlled: expandedProp, default: defaultExpanded, name: "TreeView", state: "expanded" }), _useControlled2 = _slicedToArray(_useControlled, 2), expanded = _useControlled2[0], setExpandedState = _useControlled2[1]; var _useControlled3 = useControlled({ controlled: selectedProp, default: defaultSelected, name: "TreeView", state: "selected" }), _useControlled4 = _slicedToArray(_useControlled3, 2), selected = _useControlled4[0], setSelectedState = _useControlled4[1]; /* * Status Helpers */ var isExpanded = React.useCallback(function (id) { return Array.isArray(expanded) ? expanded.indexOf(id) !== -1 : false; }, [expanded]); var isExpandable = React.useCallback(function (id) { return nodeMap.current[id] && nodeMap.current[id].expandable; }, []); var isSelected = React.useCallback(function (id) { return Array.isArray(selected) ? selected.indexOf(id) !== -1 : selected === id; }, [selected]); var isDisabled = React.useCallback(function (id) { var node = nodeMap.current[id]; // This can be called before the node has been added to the node map. if (!node) { return false; } if (node.disabled) { return true; } while (node.parentId != null) { node = nodeMap.current[node.parentId]; if (node.disabled) { return true; } } return false; }, []); var isFocused = function isFocused(id) { return focusedNodeId === id; }; /* * Child Helpers */ // Using Object.keys -> .map to mimic Object.values we should replace with Object.values() once we stop IE11 support. var getChildrenIds = function getChildrenIds(id) { return Object.keys(nodeMap.current).map(function (key) { return nodeMap.current[key]; }).filter(function (node) { return node.parentId === id; }).sort(function (a, b) { return a.index - b.index; }).map(function (child) { return child.id; }); }; var getNavigableChildrenIds = function getNavigableChildrenIds(id) { var childrenIds = getChildrenIds(id); if (!disabledItemsFocusable) { childrenIds = childrenIds.filter(function (node) { return !isDisabled(node); }); } return childrenIds; }; /* * Node Helpers */ var getNextNode = function getNextNode(id) { // If expanded get first child if (isExpanded(id) && getNavigableChildrenIds(id).length > 0) { return getNavigableChildrenIds(id)[0]; } var node = nodeMap.current[id]; while (node != null) { // Try to get next sibling var siblings = getNavigableChildrenIds(node.parentId); var nextSibling = siblings[siblings.indexOf(node.id) + 1]; if (nextSibling) { return nextSibling; } // If the sibling does not exist, go up a level to the parent and try again. node = nodeMap.current[node.parentId]; } return null; }; var getPreviousNode = function getPreviousNode(id) { var node = nodeMap.current[id]; var siblings = getNavigableChildrenIds(node.parentId); var nodeIndex = siblings.indexOf(id); if (nodeIndex === 0) { return node.parentId; } var currentNode = siblings[nodeIndex - 1]; while (isExpanded(currentNode) && getNavigableChildrenIds(currentNode).length > 0) { currentNode = getNavigableChildrenIds(currentNode).pop(); } return currentNode; }; var getLastNode = function getLastNode() { var lastNode = getNavigableChildrenIds(null).pop(); while (isExpanded(lastNode)) { lastNode = getNavigableChildrenIds(lastNode).pop(); } return lastNode; }; var getFirstNode = function getFirstNode() { return getNavigableChildrenIds(null)[0]; }; var getParent = function getParent(id) { return nodeMap.current[id].parentId; }; /** * This is used to determine the start and end of a selection range so * we can get the nodes between the two border nodes. * * It finds the nodes' common ancestor using * a naive implementation of a lowest common ancestor algorithm * (https://en.wikipedia.org/wiki/Lowest_common_ancestor). * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB * so we can compare their indexes to work out which node comes first in a depth first search. * (https://en.wikipedia.org/wiki/Depth-first_search) * * Another way to put it is which node is shallower in a trémaux tree * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree * @param nodeAId * @param nodeBId */ var findOrderInTremauxTree = function findOrderInTremauxTree(nodeAId, nodeBId) { if (nodeAId === nodeBId) { return [nodeAId, nodeBId]; } var nodeA = nodeMap.current[nodeAId]; var nodeB = nodeMap.current[nodeBId]; if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) { return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id]; } var aFamily = [nodeA.id]; var bFamily = [nodeB.id]; var aAncestor = nodeA.parentId; var bAncestor = nodeB.parentId; var aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1; var bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1; var continueA = true; var continueB = true; while (!bAncestorIsCommon && !aAncestorIsCommon) { if (continueA) { aFamily.push(aAncestor); aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1; continueA = aAncestor !== null; if (!aAncestorIsCommon && continueA) { aAncestor = nodeMap.current[aAncestor].parentId; } } if (continueB && !aAncestorIsCommon) { bFamily.push(bAncestor); bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1; continueB = bAncestor !== null; if (!bAncestorIsCommon && continueB) { bAncestor = nodeMap.current[bAncestor].parentId; } } } var commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor; var ancestorFamily = getChildrenIds(commonAncestor); var aSide = aFamily[aFamily.indexOf(commonAncestor) - 1]; var bSide = bFamily[bFamily.indexOf(commonAncestor) - 1]; return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId]; }; var getNodesInRange = function getNodesInRange(nodeA, nodeB) { var _findOrderInTremauxTr = findOrderInTremauxTree(nodeA, nodeB), _findOrderInTremauxTr2 = _slicedToArray(_findOrderInTremauxTr, 2), first = _findOrderInTremauxTr2[0], last = _findOrderInTremauxTr2[1]; var nodes = [first]; var current = first; while (current !== last) { current = getNextNode(current); nodes.push(current); } return nodes; }; /* * Focus Helpers */ var focus = function focus(event, id) { if (id) { setFocusedNodeId(id); if (onNodeFocus) { onNodeFocus(event, id); } } }; var focusNextNode = function focusNextNode(event, id) { return focus(event, getNextNode(id)); }; var focusPreviousNode = function focusPreviousNode(event, id) { return focus(event, getPreviousNode(id)); }; var focusFirstNode = function focusFirstNode(event) { return focus(event, getFirstNode()); }; var focusLastNode = function focusLastNode(event) { return focus(event, getLastNode()); }; var focusByFirstCharacter = function focusByFirstCharacter(event, id, char) { var start; var index; var lowercaseChar = char.toLowerCase(); var firstCharIds = []; var firstChars = []; // This really only works since the ids are strings Object.keys(firstCharMap.current).forEach(function (nodeId) { var firstChar = firstCharMap.current[nodeId]; var map = nodeMap.current[nodeId]; var visible = map.parentId ? isExpanded(map.parentId) : true; var shouldBeSkipped = disabledItemsFocusable ? false : isDisabled(nodeId); if (visible && !shouldBeSkipped) { firstCharIds.push(nodeId); firstChars.push(firstChar); } }); // Get start index for search based on position of currentItem start = firstCharIds.indexOf(id) + 1; if (start >= firstCharIds.length) { start = 0; } // Check remaining slots in the menu index = findNextFirstChar(firstChars, start, lowercaseChar); // If not found in remaining slots, check from beginning if (index === -1) { index = findNextFirstChar(firstChars, 0, lowercaseChar); } // If match was found... if (index > -1) { focus(event, firstCharIds[index]); } }; /* * Expansion Helpers */ var toggleExpansion = function toggleExpansion(event) { var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : focusedNodeId; var newExpanded; if (expanded.indexOf(value) !== -1) { newExpanded = expanded.filter(function (id) { return id !== value; }); } else { newExpanded = [value].concat(expanded); } if (onNodeToggle) { onNodeToggle(event, newExpanded); } setExpandedState(newExpanded); }; var expandAllSiblings = function expandAllSiblings(event, id) { var map = nodeMap.current[id]; var siblings = getChildrenIds(map.parentId); var diff = siblings.filter(function (child) { return isExpandable(child) && !isExpanded(child); }); var newExpanded = expanded.concat(diff); if (diff.length > 0) { setExpandedState(newExpanded); if (onNodeToggle) { onNodeToggle(event, newExpanded); } } }; /* * Selection Helpers */ var lastSelectedNode = React.useRef(null); var lastSelectionWasRange = React.useRef(false); var currentRangeSelection = React.useRef([]); var handleRangeArrowSelect = function handleRangeArrowSelect(event, nodes) { var base = selected.slice(); var start = nodes.start, next = nodes.next, current = nodes.current; if (!next || !current) { return; } if (currentRangeSelection.current.indexOf(current) === -1) { currentRangeSelection.current = []; } if (lastSelectionWasRange.current) { if (currentRangeSelection.current.indexOf(next) !== -1) { base = base.filter(function (id) { return id === start || id !== current; }); currentRangeSelection.current = currentRangeSelection.current.filter(function (id) { return id === start || id !== current; }); } else { base.push(next); currentRangeSelection.current.push(next); } } else { base.push(next); currentRangeSelection.current.push(current, next); } if (onNodeSelect) { onNodeSelect(event, base); } setSelectedState(base); }; var handleRangeSelect = function handleRangeSelect(event, nodes) { var base = selected.slice(); var start = nodes.start, end = nodes.end; // If last selection was a range selection ignore nodes that were selected. if (lastSelectionWasRange.current) { base = base.filter(function (id) { return currentRangeSelection.current.indexOf(id) === -1; }); } var range = getNodesInRange(start, end); range = range.filter(function (node) { return !isDisabled(node); }); currentRangeSelection.current = range; var newSelected = base.concat(range); newSelected = newSelected.filter(function (id, i) { return newSelected.indexOf(id) === i; }); if (onNodeSelect) { onNodeSelect(event, newSelected); } setSelectedState(newSelected); }; var handleMultipleSelect = function handleMultipleSelect(event, value) { var newSelected; if (selected.indexOf(value) !== -1) { newSelected = selected.filter(function (id) { return id !== value; }); } else { newSelected = [value].concat(selected); } if (onNodeSelect) { onNodeSelect(event, newSelected); } setSelectedState(newSelected); }; var handleSingleSelect = function handleSingleSelect(event, value) { var newSelected = multiSelect ? [value] : value; if (onNodeSelect) { onNodeSelect(event, newSelected); } setSelectedState(newSelected); }; var selectNode = function selectNode(event, id) { var multiple = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (id) { if (multiple) { handleMultipleSelect(event, id); } else { handleSingleSelect(event, id); } lastSelectedNode.current = id; lastSelectionWasRange.current = false; currentRangeSelection.current = []; return true; } return false; }; var selectRange = function selectRange(event, nodes) { var stacked = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var _nodes$start = nodes.start, start = _nodes$start === void 0 ? lastSelectedNode.current : _nodes$start, end = nodes.end, current = nodes.current; if (stacked) { handleRangeArrowSelect(event, { start: start, next: end, current: current }); } else if (start != null && end != null) { handleRangeSelect(event, { start: start, end: end }); } lastSelectionWasRange.current = true; }; var rangeSelectToFirst = function rangeSelectToFirst(event, id) { if (!lastSelectedNode.current) { lastSelectedNode.current = id; } var start = lastSelectionWasRange.current ? lastSelectedNode.current : id; selectRange(event, { start: start, end: getFirstNode() }); }; var rangeSelectToLast = function rangeSelectToLast(event, id) { if (!lastSelectedNode.current) { lastSelectedNode.current = id; } var start = lastSelectionWasRange.current ? lastSelectedNode.current : id; selectRange(event, { start: start, end: getLastNode() }); }; var selectNextNode = function selectNextNode(event, id) { if (!isDisabled(getNextNode(id))) { selectRange(event, { end: getNextNode(id), current: id }, true); } }; var selectPreviousNode = function selectPreviousNode(event, id) { if (!isDisabled(getPreviousNode(id))) { selectRange(event, { end: getPreviousNode(id), current: id }, true); } }; var selectAllNodes = function selectAllNodes(event) { selectRange(event, { start: getFirstNode(), end: getLastNode() }); }; /* * Mapping Helpers */ var registerNode = React.useCallback(function (node) { var id = node.id, index = node.index, parentId = node.parentId, expandable = node.expandable, idAttribute = node.idAttribute, disabled = node.disabled; nodeMap.current[id] = { id: id, index: index, parentId: parentId, expandable: expandable, idAttribute: idAttribute, disabled: disabled }; }, []); var unregisterNode = React.useCallback(function (id) { var newMap = _objectSpread({}, nodeMap.current); delete newMap[id]; nodeMap.current = newMap; setFocusedNodeId(function (oldFocusedNodeId) { if (oldFocusedNodeId === id && treeRef.current === ownerDocument(treeRef.current).activeElement) { return getChildrenIds(null)[0]; } return oldFocusedNodeId; }); }, []); var mapFirstChar = React.useCallback(function (id, firstChar) { firstCharMap.current[id] = firstChar; }, []); var unMapFirstChar = React.useCallback(function (id) { var newMap = _objectSpread({}, firstCharMap.current); delete newMap[id]; firstCharMap.current = newMap; }, []); /** * Event handlers and Navigation */ var handleNextArrow = function handleNextArrow(event) { if (isExpandable(focusedNodeId)) { if (isExpanded(focusedNodeId)) { focusNextNode(event, focusedNodeId); } else if (!isDisabled(focusedNodeId)) { toggleExpansion(event); } } return true; }; var handlePreviousArrow = function handlePreviousArrow(event) { if (isExpanded(focusedNodeId) && !isDisabled(focusedNodeId)) { toggleExpansion(event, focusedNodeId); return true; } var parent = getParent(focusedNodeId); if (parent) { focus(event, parent); return true; } return false; }; var handleKeyDown = function handleKeyDown(event) { var flag = false; var key = event.key; // If the tree is empty there will be no focused node if (event.altKey || event.currentTarget !== event.target || !focusedNodeId) { return; } var ctrlPressed = event.ctrlKey || event.metaKey; switch (key) { case " ": if (!disableSelection && !isDisabled(focusedNodeId)) { if (multiSelect && event.shiftKey) { selectRange(event, { end: focusedNodeId }); flag = true; } else if (multiSelect) { flag = selectNode(event, focusedNodeId, true); } else { flag = selectNode(event, focusedNodeId); } } event.stopPropagation(); break; case "Enter": if (!isDisabled(focusedNodeId)) { if (isExpandable(focusedNodeId)) { toggleExpansion(event); flag = true; } else if (multiSelect) { flag = selectNode(event, focusedNodeId, true); } else { flag = selectNode(event, focusedNodeId); } } event.stopPropagation(); break; case "ArrowDown": if (multiSelect && event.shiftKey && !disableSelection) { selectNextNode(event, focusedNodeId); } focusNextNode(event, focusedNodeId); flag = true; break; case "ArrowUp": if (multiSelect && event.shiftKey && !disableSelection) { selectPreviousNode(event, focusedNodeId); } focusPreviousNode(event, 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 (multiSelect && ctrlPressed && event.shiftKey && !disableSelection && !isDisabled(focusedNodeId)) { rangeSelectToFirst(event, focusedNodeId); } focusFirstNode(event); flag = true; break; case "End": if (multiSelect && ctrlPressed && event.shiftKey && !disableSelection && !isDisabled(focusedNodeId)) { rangeSelectToLast(event, focusedNodeId); } focusLastNode(event); flag = true; break; default: if (key === "*") { expandAllSiblings(event, focusedNodeId); flag = true; } else if (multiSelect && ctrlPressed && key.toLowerCase() === "a" && !disableSelection) { selectAllNodes(event); flag = true; } else if (!ctrlPressed && !event.shiftKey && isPrintableCharacter(key)) { focusByFirstCharacter(event, focusedNodeId, key); flag = true; } } if (flag) { event.preventDefault(); event.stopPropagation(); } if (onKeyDown) { onKeyDown(event); } }; var handleFocus = function handleFocus(event) { // if the event bubbled (which is React specific) we don't want to steal focus if (event.target === event.currentTarget) { var firstSelected = Array.isArray(selected) ? selected[0] : selected; focus(event, firstSelected || getNavigableChildrenIds(null)[0]); } if (onFocus) { onFocus(event); } }; var handleBlur = function handleBlur(event) { setFocusedNodeId(null); if (onBlur) { onBlur(event); } }; var activeDescendant = nodeMap.current[focusedNodeId] ? nodeMap.current[focusedNodeId].idAttribute : null; return /*#__PURE__*/_jsx(TreeViewContext.Provider, { // TODO: fix this lint error // eslint-disable-next-line react/jsx-no-constructed-context-values value: { icons: { defaultCollapseIcon: defaultCollapseIcon, defaultExpandIcon: defaultExpandIcon, defaultParentIcon: defaultParentIcon, defaultEndIcon: defaultEndIcon }, focus: focus, toggleExpansion: toggleExpansion, isExpanded: isExpanded, isExpandable: isExpandable, isFocused: isFocused, isSelected: isSelected, isDisabled: isDisabled, selectNode: disableSelection ? noopSelection : selectNode, selectRange: disableSelection ? noopSelection : selectRange, multiSelect: multiSelect, disabledItemsFocusable: disabledItemsFocusable, mapFirstChar: mapFirstChar, unMapFirstChar: unMapFirstChar, registerNode: registerNode, unregisterNode: unregisterNode, treeId: treeId }, children: /*#__PURE__*/_jsx(DescendantProvider, { children: /*#__PURE__*/_jsx(TreeViewRoot, _objectSpread(_objectSpread({ role: "tree", id: treeId, "aria-activedescendant": activeDescendant, "aria-multiselectable": multiSelect, className: clsx(classes.root, className), ref: handleRef, tabIndex: 0, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, ownerState: ownerState }, other), {}, { children: children })) }) }); }); TreeView.displayName = "MuiTreeView"; TreeView.propTypes /* remove-proptypes */ = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- /** * The content of the component. */ children: PropTypes.node, /** * Override or extend the styles applied to the component. */ classes: PropTypes.object, /** * @ignore */ className: PropTypes.string, /** * The default icon used to collapse the node. */ defaultCollapseIcon: PropTypes.node, /** * The default icon displayed next to a end node. This is applied to all * tree nodes and can be overridden by the TreeItem `icon` prop. */ defaultEndIcon: PropTypes.node, /** * Expanded node ids. (Uncontrolled) * @default [] */ defaultExpanded: PropTypes.arrayOf(PropTypes.string), /** * The default icon used to expand the node. */ defaultExpandIcon: PropTypes.node, /** * The default icon displayed next to a parent node. This is applied to all * parent nodes and can be overridden by the TreeItem `icon` prop. */ defaultParentIcon: PropTypes.node, /** * Selected node ids. (Uncontrolled) * When `multiSelect` is true this takes an array of strings; when false (default) a string. * @default [] */ defaultSelected: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.string]), /** * If `true`, will allow focus on disabled items. * @default false */ disabledItemsFocusable: PropTypes.bool, /** * If `true` selection is disabled. * @default false */ disableSelection: PropTypes.bool, /** * Expanded node ids. (Controlled) */ expanded: PropTypes.arrayOf(PropTypes.string), /** * This prop is used to help implement the accessibility logic. * If you don't provide this prop. It falls back to a randomly generated id. */ id: PropTypes.string, /** * If true `ctrl` and `shift` will trigger multiselect. * @default false */ multiSelect: PropTypes.bool, /** * @ignore */ onBlur: PropTypes.func, /** * @ignore */ onFocus: PropTypes.func, /** * @ignore */ onKeyDown: PropTypes.func, /** * Callback fired when tree items are focused. * * @param {React.SyntheticEvent} event The event source of the callback **Warning**: This is a generic event not a focus event. * @param {string} value of the focused node. */ onNodeFocus: PropTypes.func, /** * Callback fired when tree items are selected/unselected. * * @param {React.SyntheticEvent} event The event source of the callback * @param {string[] | string} nodeIds Ids of the selected nodes. When `multiSelect` is true * this is an array of strings; when false (default) a string. */ onNodeSelect: PropTypes.func, /** * Callback fired when tree items are expanded/collapsed. * * @param {React.SyntheticEvent} event The event source of the callback. * @param {array} nodeIds The ids of the expanded nodes. */ onNodeToggle: PropTypes.func, /** * Selected node ids. (Controlled) * When `multiSelect` is true this takes an array of strings; when false (default) a string. */ selected: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.string]), /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]) };