UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

272 lines (271 loc) 7.78 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); Object.defineProperty(exports, 'TreeNode', { enumerable: true, get: function () { return TreeNode; }, }); const _interop_require_default = require('@swc/helpers/_/_interop_require_default'); const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard'); const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react')); const _index = require('../../utils/index.js'); const _classnames = /*#__PURE__*/ _interop_require_default._( require('classnames'), ); const _TreeNodeExpander = require('./TreeNodeExpander.js'); const _TreeContext = require('./TreeContext.js'); const TreeNode = _react.forwardRef((props, forwardedRef) => { let { nodeId, nodeProps = {}, label, labelProps = {}, sublabel, sublabelProps = {}, children, className, icon, iconProps = {}, hasSubNodes = false, isDisabled = false, isExpanded = false, isSelected = false, onSelected, onExpanded, checkbox, checkboxProps = {}, subTreeProps = {}, contentProps = {}, titleProps = {}, expanderProps = {}, expander, ...rest } = props; let { nodeDepth, subNodeIds = [], parentNodeId, scrollToParent, groupSize, indexInGroup, } = (0, _TreeContext.useTreeContext)(); let { virtualizer, onVirtualizerChange } = _react.useContext(_TreeContext.VirtualizedTreeContext) ?? {}; let [isFocused, setIsFocused] = _react.useState(false); let nodeRef = _react.useRef(null); let onKeyDown = (event) => { if (event.altKey) return; let isNodeFocused = nodeRef.current === nodeRef.current?.ownerDocument.activeElement; switch (event.key) { case 'ArrowLeft': { event.preventDefault(); if (isNodeFocused) { if (isExpanded) { onExpanded(nodeId, false); onVirtualizerChange?.(virtualizer); break; } if (parentNodeId) scrollToParent?.(); break; } let focusableElements = (0, _index.getFocusableElements)( nodeRef.current, ); let currentIndex = focusableElements.indexOf( nodeRef.current?.ownerDocument.activeElement, ); if (0 === currentIndex) nodeRef.current?.focus(); else focusableElements[currentIndex - 1]?.focus(); break; } case 'ArrowRight': { event.preventDefault(); let focusableElements = (0, _index.getFocusableElements)( nodeRef.current, ); if (isNodeFocused) { if (!isExpanded && hasSubNodes) { onExpanded(nodeId, true); onVirtualizerChange?.(virtualizer); break; } focusableElements[0]?.focus(); break; } let currentIndex = focusableElements.indexOf( nodeRef.current?.ownerDocument.activeElement, ); if (currentIndex < focusableElements.length - 1) focusableElements[currentIndex + 1].focus(); break; } case ' ': case 'Spacebar': case 'Enter': if (event.target !== nodeRef.current) break; event.preventDefault(); if (!isDisabled) onSelected?.(nodeId, !isSelected); break; default: break; } }; let onExpanderClick = _react.useCallback( (event) => { onExpanded(nodeId, !isExpanded); onVirtualizerChange?.(virtualizer); event.stopPropagation(); }, [isExpanded, nodeId, onExpanded, onVirtualizerChange, virtualizer], ); return _react.createElement( _index.Box, { as: 'div', role: 'treeitem', className: (0, _classnames.default)('iui-tree-item', className), 'aria-expanded': hasSubNodes ? isExpanded : void 0, 'aria-disabled': isDisabled, 'aria-selected': isSelected, 'aria-level': nodeDepth + 1, 'aria-setsize': groupSize, 'aria-posinset': indexInGroup + 1, tabIndex: -1, ...rest, id: nodeId, ref: (0, _index.useMergedRefs)(nodeRef, forwardedRef), onFocus: (0, _index.mergeEventHandlers)(props.onFocus, (e) => { setIsFocused(true); e.stopPropagation(); }), onBlur: (0, _index.mergeEventHandlers)(props.onBlur, () => { setIsFocused(false); }), onKeyDown: (0, _index.mergeEventHandlers)(props.onKeyDown, onKeyDown), }, _react.createElement( _index.Box, { as: 'div', style: { '--level': nodeDepth, }, onClick: () => !isDisabled && onSelected?.(nodeId, !isSelected), ...nodeProps, className: (0, _classnames.default)( 'iui-tree-node', { 'iui-active': isSelected, 'iui-disabled': isDisabled, }, nodeProps?.className, ), }, checkbox && _react.createElement( _index.Box, { as: 'div', ...checkboxProps, className: (0, _classnames.default)( 'iui-tree-node-checkbox', checkboxProps?.className, ), }, _react.isValidElement(checkbox) ? _react.cloneElement(checkbox, { tabIndex: isFocused ? 0 : -1, }) : checkbox, ), _react.createElement( _index.Box, { as: 'div', ...contentProps, className: (0, _classnames.default)( 'iui-tree-node-content', contentProps?.className, ), }, hasSubNodes && expander, hasSubNodes && !expander && _react.createElement(_TreeNodeExpander.TreeNodeExpander, { isExpanded: isExpanded, disabled: isDisabled, onClick: onExpanderClick, tabIndex: isFocused ? 0 : -1, ...expanderProps, }), icon && _react.createElement( _index.Box, { as: 'span', 'aria-hidden': true, ...iconProps, className: (0, _classnames.default)( 'iui-tree-node-content-icon', iconProps?.className, ), }, icon, ), _react.createElement( _index.Box, { as: 'div', ...labelProps, className: (0, _classnames.default)( 'iui-tree-node-content-label', labelProps?.className, ), }, _react.createElement( _index.Box, { as: 'div', ...titleProps, className: (0, _classnames.default)( 'iui-tree-node-content-title', titleProps?.className, ), }, label, ), sublabel && _react.createElement( _index.Box, { as: 'div', ...sublabelProps, className: (0, _classnames.default)( 'iui-tree-node-content-caption', sublabelProps?.className, ), }, sublabel, ), ), children, ), ), hasSubNodes && _react.createElement(_index.Box, { as: 'div', role: 'group', 'aria-owns': subNodeIds.join(' '), ...subTreeProps, className: (0, _classnames.default)( 'iui-sub-tree', subTreeProps?.className, ), }), ); }); if ('development' === process.env.NODE_ENV) TreeNode.displayName = 'TreeNode';