@procore/core-react
Version:
React library of Procore Design Guidelines
693 lines (685 loc) • 30 kB
JavaScript
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 = ["options", "expanded", "selected", "selectionLimit", "getRoot", "getChildren", "getIcon", "getLabel", "getParentId", "getType", "isExpandable", "isSelectable", "multiple", "onSelect", "onCollapse", "onExpand", "rowRenderer", "maxVisibleNodes", "visibleHeight", "autoExpandParent", "innerElementType", "outerElementType", "onKeyDown", "children"],
_excluded2 = ["nodes", "rowRenderer", "highlight", "isTreeFocused"],
_excluded3 = ["node", "getIcon", "getLabel", "handleExpansion", "handleSelection", "selectionLimit", "isFileLimitReached", "shouldShowTooltip", "isMouseOver", "treeContainer"],
_excluded4 = ["children", "isSelected"],
_excluded5 = ["children", "isHighlighted", "isSelected", "isSelectable", "isExpandable", "isFileLimitReached", "level"];
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(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : 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 _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _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(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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(r) { if (Array.isArray(r)) return r; }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import { ChevronRight, File, Folder } from '@procore/core-icons/dist';
import React from 'react';
import { areEqual, FixedSizeList } from 'react-window';
import styled from 'styled-components';
import { Button } from '../Button/Button';
import { Spinner } from '../Spinner/Spinner';
import { Tooltip } from '../Tooltip';
import { useI18nContext } from '../_hooks/I18n';
import { useIntersectionObserver } from '../_hooks/IntersectionObserver';
import { useResizeObserver } from '../_hooks/ResizeObserver';
import { useTimer } from '../_hooks/Timer';
import { useVisibility } from '../_hooks/Visibility';
import { parseFilename } from '../_utils/filename';
import { mergeRefs } from '../_utils/mergeRefs';
import { useTree } from './Tree.hooks';
import { StyledChevronPlaceholder, StyledFilenameCaption, StyledIconContainer, StyledTree, StyledTreeRowContainer, StyledTreeRowContent, StyledTreeRowWrapper } from './Tree.styles';
var spacing = 32;
var rootSpacing = 24;
var defaultRowHeight = 36;
// Selected nodes have a bold text, and browsers occasionally miscalculate scrollWidth by one pixel down.
// That situations might cause an issue when we get a second horizontal scrollbar.
// This padding serves as compensation to prevent the described issue.
var rowRightPadding = 12;
// For most of browsers it usually varies between 12px and 20px.
// To avoid tricky cross-browser calculations of scrollbar width. The maximum width is used.
var scrollbarWidth = 20;
function getPadding(level) {
return rootSpacing + level * spacing;
}
var intersectionThresholds = Array.from({
length: 101
}).map(function (_, index) {
return index / 100;
});
var TreeInnerElement = /*#__PURE__*/React.forwardRef(function (props, ref) {
return /*#__PURE__*/React.createElement("div", _extends({
role: "presentation",
ref: ref
}, props));
});
var TreeOuterElement = /*#__PURE__*/React.forwardRef(function (props, ref) {
return /*#__PURE__*/React.createElement("div", _extends({
role: "presentation",
ref: ref
}, props));
});
var tooltipDelay = 300;
function getTreeItemId(nodeId) {
return "treeitem-".concat(nodeId);
}
// TODO refactor this to not be upper snake case
export var UNSAFE_treeRootNodeId = 'ROOT_ID';
var defaultIsExpandable = function defaultIsExpandable(node) {
return defaultGetType(node) === 'branch';
};
var defaultIsSelectable = function defaultIsSelectable(node) {
return node.type === 'leaf';
};
var defaultGetType = function defaultGetType(node) {
return node.type;
};
var defaultGetParentId = function defaultGetParentId(node) {
return node.parentId;
};
var defaultGetLabel = function defaultGetLabel(node) {
return node.name;
};
function noop() {}
export function isRootNode(parentId) {
var rootValues = [UNSAFE_treeRootNodeId, null, undefined];
return rootValues.includes(parentId);
}
/**
The tree allows users to navigate between folder / file directories,
and optionally select those files.
@since 10.19.0
@see [Storybook](https://stories.core.procore.com/?path=/story/core-react_demos-tree--demo)
@see [Design Guidelines](https://design.procore.com/tree)
*/
export var Tree = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
var options = _ref.options,
_ref$expanded = _ref.expanded,
expanded = _ref$expanded === void 0 ? [] : _ref$expanded,
_ref$selected = _ref.selected,
selected = _ref$selected === void 0 ? [] : _ref$selected,
_ref$selectionLimit = _ref.selectionLimit,
selectionLimit = _ref$selectionLimit === void 0 ? Infinity : _ref$selectionLimit,
getRoot_ = _ref.getRoot,
getChildren_ = _ref.getChildren,
getIconBase = _ref.getIcon,
_ref$getLabel = _ref.getLabel,
getLabel = _ref$getLabel === void 0 ? defaultGetLabel : _ref$getLabel,
_ref$getParentId = _ref.getParentId,
getParentId_ = _ref$getParentId === void 0 ? defaultGetParentId : _ref$getParentId,
_ref$getType = _ref.getType,
getType = _ref$getType === void 0 ? defaultGetType : _ref$getType,
_ref$isExpandable = _ref.isExpandable,
isExpandable = _ref$isExpandable === void 0 ? defaultIsExpandable : _ref$isExpandable,
_ref$isSelectable = _ref.isSelectable,
isSelectable = _ref$isSelectable === void 0 ? defaultIsSelectable : _ref$isSelectable,
_ref$multiple = _ref.multiple,
multiple = _ref$multiple === void 0 ? true : _ref$multiple,
_ref$onSelect = _ref.onSelect,
onSelect = _ref$onSelect === void 0 ? noop : _ref$onSelect,
_ref$onCollapse = _ref.onCollapse,
onCollapse = _ref$onCollapse === void 0 ? noop : _ref$onCollapse,
_ref$onExpand = _ref.onExpand,
onExpand = _ref$onExpand === void 0 ? function () {
return Promise.resolve();
} : _ref$onExpand,
rowRendererBase = _ref.rowRenderer,
_ref$maxVisibleNodes = _ref.maxVisibleNodes,
maxVisibleNodes = _ref$maxVisibleNodes === void 0 ? Infinity : _ref$maxVisibleNodes,
visibleHeight = _ref.visibleHeight,
_ref$autoExpandParent = _ref.autoExpandParent,
autoExpandParent = _ref$autoExpandParent === void 0 ? true : _ref$autoExpandParent,
innerElementType = _ref.innerElementType,
outerElementType = _ref.outerElementType,
onKeyDown = _ref.onKeyDown,
children = _ref.children,
props = _objectWithoutProperties(_ref, _excluded);
var rowHeight = defaultRowHeight;
var wrapperRef = React.useRef(null);
var listRef = React.useRef(null);
var listInnerRef = React.useRef(null);
var listOuterRefRef = React.useRef(null);
var _React$useState = React.useState(0),
_React$useState2 = _slicedToArray(_React$useState, 2),
contentMaxWidth = _React$useState2[0],
setContentMaxWidth = _React$useState2[1];
var getParentId = React.useMemo(function () {
return getParentId_;
}, []);
var defaultGetRoot = React.useCallback(function (nodes) {
return nodes.filter(function (node) {
return isRootNode(getParentId(node));
});
}, [getParentId]);
var getRoot = React.useMemo(function () {
return getRoot_ || defaultGetRoot;
}, [defaultGetRoot]);
var rootNodes = React.useMemo(function () {
var roots = getRoot(options);
return Array.isArray(roots) ? roots : [roots];
}, [getRoot, options]);
React.useEffect(function () {
if (!rootNodes.length) {
console.warn('Tree must have at least one root node. Look up `Tree#getParentId` for details.');
}
}, [rootNodes]);
var _React$useState3 = React.useState(false),
_React$useState4 = _slicedToArray(_React$useState3, 2),
isTreeFocused = _React$useState4[0],
setIsTreeFocused = _React$useState4[1];
var _React$useState5 = React.useState({
width: 0,
height: 0
}),
_React$useState6 = _slicedToArray(_React$useState5, 2),
containerSize = _React$useState6[0],
setContainerSize = _React$useState6[1];
var handleContainerResize = React.useCallback(function (entries) {
if (entries[0]) {
var _ref2 = entries[0].target,
height = _ref2.clientHeight,
width = _ref2.clientWidth;
setContainerSize({
width: width,
height: height
});
}
}, [setContainerSize]);
var setResizeObserverTarget = useResizeObserver(handleContainerResize);
var defaultGetChildren = React.useCallback(function (node) {
return Array.isArray(options) ? options.filter(function (childNode) {
return getParentId(childNode) === node.id;
}) : [];
}, [getParentId, options]);
var getChildren = getChildren_ || defaultGetChildren;
var _useTree = useTree({
rootNodes: rootNodes,
expanded: expanded,
selected: selected,
selectionLimit: selectionLimit,
multiple: multiple,
autoExpandParent: autoExpandParent,
onSelect: onSelect,
onCollapse: onCollapse,
onExpand: onExpand,
getChildren: getChildren,
getParentId: getParentId
}),
nodes = _useTree.nodes,
isExpanded = _useTree.isExpanded,
isSelected = _useTree.isSelected,
isLoading = _useTree.isLoading,
highlightedNode = _useTree.highlightedNode,
isNodeHighlighted = _useTree.isHighlighted,
highlight = _useTree.highlight,
handleSelection = _useTree.handleSelection,
handleExpansion = _useTree.handleExpansion,
_setExpanded = _useTree.setExpanded,
_setSelected = _useTree.setSelected,
isFileLimitReached = _useTree.isFileLimitReached,
listNavigation = _useTree.listNavigation;
var setSelected = React.useCallback(function (selected) {
var nodes = Array.isArray(selected) ? selected : [selected];
_setSelected(new Set(nodes.map(function (node) {
return node.id;
})));
}, [_setSelected]);
var setExpanded = React.useCallback(function (expanded) {
var nodes = Array.isArray(expanded) ? expanded : [expanded];
_setExpanded(new Set(nodes.map(function (node) {
return node.id;
})));
}, [_setExpanded]);
React.useImperativeHandle(ref, function () {
return {
rootEl: wrapperRef.current,
setSelected: setSelected,
setExpanded: setExpanded,
toggleSelected: function toggleSelected(node) {
return handleSelection(node);
},
toggleExpanded: function toggleExpanded(node) {
return handleExpansion(node);
}
};
});
var defaultGetIcon = React.useCallback(function (node) {
var isFolder = getType(node) === 'branch';
return isFolder ? /*#__PURE__*/React.createElement(Folder, {
role: "img",
"aria-label": "Folder",
"aria-hidden": false
}) : /*#__PURE__*/React.createElement(File, {
role: "img",
"aria-label": "File",
"aria-hidden": false
});
}, [getType]);
var getIcon = getIconBase || defaultGetIcon;
var isHighlighted = React.useCallback(function (node) {
return isTreeFocused && isNodeHighlighted(node);
}, [isNodeHighlighted, isTreeFocused]);
var handleAccessibility = function handleAccessibility(e) {
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
var key = e.key;
switch (key) {
case 'Enter':
e.preventDefault();
isSelectable(highlightedNode) && handleSelection(highlightedNode);
break;
case 'Space Bar':
case ' ':
e.preventDefault();
isExpandable(highlightedNode) && handleExpansion(highlightedNode);
break;
case 'Tab':
if (e.shiftKey) {
if (listNavigation.index > 0) {
e.preventDefault();
listNavigation.decrement();
}
} else {
if (listNavigation.index < nodes.length - 1) {
e.preventDefault();
listNavigation.increment();
}
}
break;
case 'ArrowLeft':
case 'Left':
e.preventDefault();
if (isExpandable(highlightedNode) && isExpanded(highlightedNode)) {
handleExpansion(highlightedNode);
} else {
var parentId = getParentId(highlightedNode);
if (!isRootNode(parentId)) {
var parentNode = nodes.find(function (node) {
return node.id === parentId;
});
if (parentNode) {
highlight(parentNode);
}
}
}
break;
case 'ArrowRight':
case 'Right':
e.preventDefault();
if (isExpandable(highlightedNode) && !isExpanded(highlightedNode)) {
handleExpansion(highlightedNode);
} else if (isExpandable(highlightedNode) && isExpanded(highlightedNode)) {
listNavigation.increment();
}
break;
case 'ArrowDown':
case 'Down':
e.preventDefault();
listNavigation.increment();
break;
case 'ArrowUp':
case 'Up':
e.preventDefault();
listNavigation.decrement();
break;
}
};
React.useEffect(function () {
if (isTreeFocused) {
var _listRef$current;
(_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : _listRef$current.scrollToItem(listNavigation.index);
}
}, [isTreeFocused, listNavigation.index]);
var defaultRowRenderer = React.useCallback(function (props) {
return /*#__PURE__*/React.createElement(TreeRow, props);
}, []);
React.useEffect(function () {
var _listInnerRef$current;
var rowContentSizes = [];
var childNodes = Array.from(((_listInnerRef$current = listInnerRef.current) === null || _listInnerRef$current === void 0 ? void 0 : _listInnerRef$current.childNodes) || []);
childNodes.forEach(function (child) {
var rowContent = child.querySelector('[data-row-content]');
if (rowContent) {
var _dataset$padding;
var leftPadding = (_dataset$padding = child.dataset.padding) !== null && _dataset$padding !== void 0 ? _dataset$padding : '0';
rowContentSizes.push(rowContent.scrollWidth + parseInt(leftPadding, 10) + rowRightPadding);
}
});
var maxSizeRowContent = Math.max.apply(Math, rowContentSizes) + scrollbarWidth;
setContentMaxWidth(maxSizeRowContent);
});
var rowRenderer = rowRendererBase || defaultRowRenderer;
var itemData = React.useMemo(function () {
return {
nodes: nodes,
getIcon: getIcon,
getLabel: getLabel,
getType: getType,
isExpandable: isExpandable,
isSelectable: isSelectable,
isExpanded: isExpanded,
isSelected: isSelected,
isLoading: isLoading,
highlight: highlight,
isHighlighted: isHighlighted,
handleSelection: handleSelection,
handleExpansion: handleExpansion,
rowRenderer: rowRenderer,
isFileLimitReached: isFileLimitReached,
selectionLimit: selectionLimit,
isTreeFocused: isTreeFocused,
treeContainer: wrapperRef.current
};
}, [getIcon, getLabel, getType, handleExpansion, handleSelection, highlight, isExpandable, isExpanded, isFileLimitReached, isHighlighted, isLoading, isSelectable, isSelected, isTreeFocused, nodes, rowRenderer, selectionLimit]);
if (!rootNodes) {
console.error('Tree must have a valid root node');
return null;
}
return /*#__PURE__*/React.createElement(StyledTree, _extends({}, props, {
ref: mergeRefs(wrapperRef, setResizeObserverTarget),
role: "tree",
"aria-multiselectable": multiple,
"aria-activedescendant": highlightedNode ? getTreeItemId(highlightedNode.id) : undefined,
tabIndex: 0,
onFocus: function onFocus() {
return setIsTreeFocused(true);
},
onBlur: function onBlur() {
return setIsTreeFocused(false);
},
onKeyDown: handleAccessibility
}), /*#__PURE__*/React.createElement(FixedSizeList, {
className: "size-list",
ref: listRef,
height: visibleHeight || Math.min(nodes.length * rowHeight, rowHeight * maxVisibleNodes),
innerRef: listInnerRef,
outerRef: listOuterRefRef,
itemCount: nodes.length,
itemSize: rowHeight,
innerElementType: innerElementType !== null && innerElementType !== void 0 ? innerElementType : TreeInnerElement,
outerElementType: outerElementType !== null && outerElementType !== void 0 ? outerElementType : TreeOuterElement,
itemData: itemData,
width: Math.max(contentMaxWidth, containerSize.width)
}, TreeNode));
});
var TreeNode = /*#__PURE__*/React.memo(function (_ref3) {
var _ref3$data = _ref3.data,
nodes = _ref3$data.nodes,
rowRenderer = _ref3$data.rowRenderer,
highlight = _ref3$data.highlight,
isTreeFocused = _ref3$data.isTreeFocused,
props = _objectWithoutProperties(_ref3$data, _excluded2),
index = _ref3.index,
style = _ref3.style;
var node = nodes[index];
var isHighlighted = props.isHighlighted(node);
var _React$useState7 = React.useState(false),
_React$useState8 = _slicedToArray(_React$useState7, 2),
isMouseOver = _React$useState8[0],
setMouseOver = _React$useState8[1];
var timer = useTimer({});
var _useVisibility = useVisibility({}),
shouldShowTooltip = _useVisibility.isVisible,
showTooltip = _useVisibility.show,
hideTooltip = _useVisibility.hide;
React.useEffect(function () {
if (isHighlighted && !shouldShowTooltip) {
timer.setTimer(showTooltip, tooltipDelay);
}
return function () {
if (isTreeFocused && !isHighlighted && shouldShowTooltip) {
hideTooltip();
}
};
});
var onMouseEnter = function onMouseEnter() {
setMouseOver(true);
if (!shouldShowTooltip) {
timer.setTimer(showTooltip, tooltipDelay);
}
highlight(node);
};
var onMouseLeave = function onMouseLeave() {
setMouseOver(false);
timer.cancel();
hideTooltip();
};
var nodeIsExpandable = props.isExpandable(node);
var nodeIsSelectable = props.isSelectable(node);
var nodeIsExpanded = props.isExpanded(node);
var nodeIsSelected = props.isSelected(node);
return /*#__PURE__*/React.createElement(StyledTreeRowWrapper, {
id: getTreeItemId(node.id),
role: "treeitem",
"aria-level": node.level + 1,
"aria-setsize": node.setSize,
"aria-posinset": node.posInSet,
"aria-expanded": nodeIsExpandable ? nodeIsExpanded : undefined,
"aria-selected": nodeIsSelectable ? nodeIsSelected : undefined,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
style: style,
"data-padding": getPadding(node.level)
}, rowRenderer(_objectSpread({
node: node,
shouldShowTooltip: shouldShowTooltip,
isMouseOver: isMouseOver
}, props)));
}, areEqual);
var TreeRow = function TreeRow(_ref4) {
var node = _ref4.node,
getIcon = _ref4.getIcon,
getLabel = _ref4.getLabel,
handleExpansion = _ref4.handleExpansion,
handleSelection = _ref4.handleSelection,
selectionLimit = _ref4.selectionLimit,
isFileLimitReached = _ref4.isFileLimitReached,
shouldShowTooltip = _ref4.shouldShowTooltip,
isMouseOver = _ref4.isMouseOver,
treeContainer = _ref4.treeContainer,
props = _objectWithoutProperties(_ref4, _excluded3);
var chevronButtonRef = React.useRef(null);
var isSelected = props.isSelected(node);
var isSelectable = props.isSelectable(node);
var isExpandable = props.isExpandable(node);
var isExpanded = props.isExpanded(node);
var isLoading = props.isLoading(node);
var isHighlighted = props.isHighlighted(node);
var nodeType = props.getType(node);
var rowLabel = getLabel(node);
var onChevronClick = React.useCallback(function (event) {
event.stopPropagation();
handleExpansion(node);
}, [handleExpansion, node]);
var onClick = React.useCallback(function (event) {
var _chevronButtonRef$cur;
// Chevron button handles its own event
if ((_chevronButtonRef$cur = chevronButtonRef.current) !== null && _chevronButtonRef$cur !== void 0 && _chevronButtonRef$cur.contains(event.target)) {
return;
}
if (isSelectable) {
handleSelection(node);
} else if (isExpandable) {
handleExpansion(node);
}
}, [handleExpansion, handleSelection, isExpandable, isSelectable, node]);
var onMouseDown = React.useCallback(function (e) {
e.preventDefault();
treeContainer.focus();
}, [treeContainer]);
return /*#__PURE__*/React.createElement(TreeRowContainer, {
level: node.level,
onClick: onClick,
onMouseDown: onMouseDown,
isSelected: isSelected,
isSelectable: isSelectable,
isExpandable: isExpandable,
isHighlighted: isHighlighted,
isFileLimitReached: isFileLimitReached,
"data-qa": "core-tree-row-container"
}, /*#__PURE__*/React.createElement(StyledTreeRowContent, {
"data-row-content": true
}, /*#__PURE__*/React.createElement(TreeRowChevron, {
ref: chevronButtonRef,
isExpandable: isExpandable,
isExpanded: isExpanded,
onClick: onChevronClick
}), /*#__PURE__*/React.createElement(TreeRowIcon, {
isLoading: isLoading,
isSelected: isSelected,
icon: getIcon(node)
}), /*#__PURE__*/React.createElement(TreeRowTooltip, {
isSelected: isSelected,
isSelectable: isSelectable,
isHighlighted: isHighlighted,
selectionLimit: selectionLimit,
isFileLimitReached: isFileLimitReached,
shouldShowTooltip: shouldShowTooltip,
isMouseOver: isMouseOver,
fileName: rowLabel,
nodeType: nodeType,
treeContainer: treeContainer
}, /*#__PURE__*/React.createElement(TreeRowName, {
value: rowLabel
}))));
};
var IconContainer = function IconContainer(_ref5) {
var children = _ref5.children,
isSelected = _ref5.isSelected,
props = _objectWithoutProperties(_ref5, _excluded4);
return /*#__PURE__*/React.createElement(StyledIconContainer, _extends({
$isSelected: isSelected
}, props), children);
};
var StyledChevronIcon = /*#__PURE__*/styled(ChevronRight).withConfig({
displayName: "StyledChevronIcon",
componentId: "core-12_44_0__sc-f25ekl-0"
})(["transform:rotate(", "deg);transition:transform 150ms ease-out;"], function (_ref6) {
var $isExpanded = _ref6.$isExpanded;
return $isExpanded ? 90 : 0;
});
var TreeRowChevron = /*#__PURE__*/React.forwardRef(function (_ref7, ref) {
var isExpanded = _ref7.isExpanded,
isExpandable = _ref7.isExpandable,
onClick = _ref7.onClick;
var I18n = useI18nContext();
if (!isExpandable) {
return /*#__PURE__*/React.createElement(StyledChevronPlaceholder, null);
}
return /*#__PURE__*/React.createElement(Button, {
ref: ref,
variant: "tertiary",
size: "sm",
icon: /*#__PURE__*/React.createElement(StyledChevronIcon, {
$isExpanded: isExpanded
}),
onClick: onClick,
tabIndex: -1,
"aria-label": I18n.t(isExpanded ? 'core.tree.collapse' : 'core.tree.expand')
});
});
var TreeRowIcon = function TreeRowIcon(_ref8) {
var isSelected = _ref8.isSelected,
isLoading = _ref8.isLoading,
icon = _ref8.icon;
return /*#__PURE__*/React.createElement(IconContainer, {
isSelected: isSelected,
marginLeft: "sm",
marginRight: "sm"
}, isLoading ? /*#__PURE__*/React.createElement(Spinner, {
size: "sm"
}) : icon);
};
var TreeRowName = function TreeRowName(_ref9) {
var value = _ref9.value;
return /*#__PURE__*/React.createElement(StyledFilenameCaption, null, value);
};
var getSelectionLimitMessage = function getSelectionLimitMessage(selectionLimit) {
return {
key: 'selectionLimit',
options: {
count: selectionLimit
}
};
};
var getUnsupportedFileTypeMessage = function getUnsupportedFileTypeMessage(fileName) {
var _parseFilename = parseFilename(fileName),
extension = _parseFilename.extension,
isFilename = _parseFilename.isFilename;
var key = isFilename ? 'specific' : 'unspecific';
return {
key: "unsupportedFileType.".concat(key),
options: {
fileType: ".".concat(extension.toUpperCase())
}
};
};
var TreeRowTooltip = function TreeRowTooltip(_ref0) {
var children = _ref0.children,
isFocused = _ref0.isHighlighted,
isFileLimitReached = _ref0.isFileLimitReached,
isSelectable = _ref0.isSelectable,
isSelected = _ref0.isSelected,
nodeType = _ref0.nodeType,
selectionLimit = _ref0.selectionLimit,
shouldShowTooltip = _ref0.shouldShowTooltip,
isMouseOver = _ref0.isMouseOver,
fileName = _ref0.fileName,
treeContainer = _ref0.treeContainer;
var I18n = useI18nContext();
var rowRef = React.useRef(null);
var isUserInteracting = isFocused || isMouseOver;
var isTooltipVisible = isUserInteracting && shouldShowTooltip && !isSelected;
var isFile = nodeType === 'leaf';
var _React$useState9 = React.useState(false),
_React$useState0 = _slicedToArray(_React$useState9, 2),
isCropped = _React$useState0[0],
setCropped = _React$useState0[1];
var registerRowEl = useIntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.rootBounds && entry.rootBounds.left - entry.boundingClientRect.left >= 0) {
setCropped(true);
return;
}
setCropped(false);
});
}, {
root: treeContainer,
rootMargin: '0px',
threshold: intersectionThresholds
});
var selectionLimitMessage = getSelectionLimitMessage(selectionLimit);
var unsupportedFileTypeMessage = getUnsupportedFileTypeMessage(fileName);
var message = isSelectable ? isFileLimitReached && selectionLimitMessage : isFile && unsupportedFileTypeMessage;
var trigger = isTooltipVisible && !isCropped && message ? 'always' : 'none';
return /*#__PURE__*/React.createElement(Tooltip, {
trigger: trigger,
overlay: message ? I18n.t("core.tree.".concat(message.key), message.options) : null,
placement: "top-left"
}, /*#__PURE__*/React.createElement("div", {
ref: mergeRefs(rowRef, registerRowEl)
}, children));
};
var TreeRowContainer = function TreeRowContainer(_ref1) {
var children = _ref1.children,
isHighlighted = _ref1.isHighlighted,
isSelected = _ref1.isSelected,
isSelectable = _ref1.isSelectable,
isExpandable = _ref1.isExpandable,
isFileLimitReached = _ref1.isFileLimitReached,
level = _ref1.level,
props = _objectWithoutProperties(_ref1, _excluded5);
return /*#__PURE__*/React.createElement(StyledTreeRowContainer, _extends({
$isSelectable: isSelectable && (isFileLimitReached && isSelected || !isFileLimitReached) || isExpandable,
$isHighlighted: isHighlighted,
$isSelected: isSelected,
style: {
paddingLeft: getPadding(level)
}
}, props), children);
};
//# sourceMappingURL=Tree.js.map