UNPKG

rsuite

Version:

A suite of react components

140 lines (138 loc) 3.89 kB
'use client'; import _extends from "@babel/runtime/helpers/esm/extends"; import React, { useMemo } from 'react'; import TreeNodeToggle from "./TreeNodeToggle.js"; import Box from "../internals/Box/index.js"; import { forwardRef, mergeRefs, stringifyReactNode, mergeStyles } from "../internals/utils/index.js"; import { useFocusVirtualListItem, useStyles, useCustom, useEventCallback } from "../internals/hooks/index.js"; import { useTreeContextProps } from "../internals/Tree/TreeProvider.js"; import { indentTreeNode } from "./utils/index.js"; /** * Props for the TreeNode component. */ const TreeNode = forwardRef((props, ref) => { const { as, label, layer, active, loading, nodeData, className, classPrefix = 'tree-node', disabled, visible = true, draggable, expanded, focus, style, hasChildren, dragging, dragStatus, onSelect, onDragStart, onDragOver, onDragEnter, onDragLeave, onDragEnd, onDrop, onExpand, ...rest } = props; const { rtl } = useCustom(); const { renderTreeNode, virtualized } = useTreeContextProps(); const { prefix, merge, withPrefix } = useStyles(classPrefix); const labelStr = useMemo(() => stringifyReactNode(label), [label]); const handleExpand = useEventCallback(event => { // Stop propagation when using custom loading icon event?.nativeEvent?.stopImmediatePropagation?.(); event.stopPropagation(); onExpand?.(nodeData, expanded); }); const handleSelect = useEventCallback(event => { if (disabled) { return; } onSelect?.(nodeData, event); }); const handleDragStart = useEventCallback(event => { onDragStart?.(nodeData, event); }); const handleDragEnter = useEventCallback(event => { event.preventDefault(); event.stopPropagation(); onDragEnter?.(nodeData, event); }); const handleDragOver = useEventCallback(event => { event.preventDefault(); event.stopPropagation(); onDragOver?.(nodeData, event); }); const handleDragLeave = useEventCallback(event => { event.stopPropagation(); onDragLeave?.(nodeData, event); }); const handleDragEnd = useEventCallback(event => { event.stopPropagation(); onDragEnd?.(nodeData, event); }); const handleDrop = useEventCallback(event => { event.preventDefault(); event.stopPropagation(); onDrop?.(nodeData, event); }); const classes = merge(className, withPrefix({ disabled, active, 'text-muted': disabled, focus })); const treeItemRef = useFocusVirtualListItem(focus); const styles = virtualized ? mergeStyles(style, indentTreeNode(rtl, layer - 1)) : style; return visible ? /*#__PURE__*/React.createElement(Box, _extends({ as: as, role: "treeitem", ref: mergeRefs(treeItemRef, ref), tabIndex: -1, "aria-expanded": expanded, "aria-label": labelStr, "aria-level": layer, "aria-disabled": disabled, "aria-selected": active, "data-layer": layer, "data-key": nodeData?.refKey || '', title: labelStr, className: classes, style: styles, draggable: draggable, onClick: handleSelect, onDragStart: handleDragStart, onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDragEnd: handleDragEnd, onDrop: handleDrop }, rest), /*#__PURE__*/React.createElement(TreeNodeToggle, { "aria-label": (expanded ? 'Collapse' : 'Expand') + ` ${labelStr}`, data: nodeData, loading: loading, expanded: expanded, hasChildren: hasChildren, onClick: handleExpand }), /*#__PURE__*/React.createElement("span", { className: prefix('label', dragStatus, { dragging }) }, renderTreeNode ? renderTreeNode(nodeData) : label)) : null; }); TreeNode.displayName = 'TreeNode'; export default TreeNode;