import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import * as React from 'react';
import clsx from 'clsx';
import PropTypes from 'prop-types';
import { styled, useTheme, useThemeProps } from '@mui/material/styles';
import { unstable_composeClasses as composeClasses } from '@mui/base';
import { useControlled, useForkRef, ownerDocument, unstable_useId as useId } from '@mui/material/utils';
import TreeViewContext from './TreeViewContext';
import { DescendantProvider } from './descendants';
import { getTreeViewUtilityClass } from './treeViewClasses';
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 = [];
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, ["children", "className", "defaultCollapseIcon", "defaultEndIcon", "defaultExpanded", "defaultExpandIcon", "defaultParentIcon", "defaultSelected", "disabledItemsFocusable", "disableSelection", "expanded", "id", "multiSelect", "onBlur", "onFocus", "onKeyDown", "onNodeFocus", "onNodeSelect", "onNodeToggle", "selected"]);

  var theme = useTheme();
  var isRtl = theme.direction === 'rtl';

  var ownerState = _extends({}, 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),
      focusedNodeId = _React$useState[0],
      setFocusedNodeId = _React$useState[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
   */


  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 = _extends({}, 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 = _extends({}, 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, {
    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, _extends({
        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
      }))
    })
  });
});
process.env.NODE_ENV !== "production" ? 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])
} : void 0;
export default TreeView;