@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 8.49 kB
Source Map (JSON)
{"version":3,"file":"TreeNode.mjs","names":["isExpandable","Checkbox"],"sources":["../../../src/base-ui/Tree/TreeNode.tsx"],"sourcesContent":["'use client';\n\nimport { Collapsible } from '@base-ui/react/collapsible';\nimport { cx } from 'antd-style';\nimport { ChevronRight, File, Folder } from 'lucide-react';\nimport { type CSSProperties, memo, type MouseEvent } from 'react';\n\nimport { Checkbox } from '@/base-ui/Checkbox';\nimport { controlHeight } from '@/base-ui/controlSize';\nimport Icon from '@/Icon';\n\nimport { useTreeContext } from './context';\nimport { styles } from './style';\nimport type { TreeDataNode } from './type';\nimport { hasChildren as isExpandable } from './utils';\n\ninterface TreeNodeProps {\n depth: number;\n isLast: boolean;\n node: TreeDataNode;\n trail: boolean[];\n}\n\nconst ARC = 6;\nconst SWITCHER_CENTER = 11.5;\n\nconst guidePath = (\n depth: number,\n isLast: boolean,\n trail: boolean[],\n indent: number,\n height: number,\n) => {\n const cx = (i: number) => i * indent + SWITCHER_CENTER;\n let d = '';\n trail.forEach((more, i) => {\n if (more && i > 0) d += `M${cx(i)} 0V${height}`;\n });\n const x = cx(depth - 1);\n const y = height / 2;\n const elbow = `M${x} ${y - ARC}A${ARC} ${ARC} 0 0 0 ${x + ARC} ${y}H${x + indent - 2}`;\n d += isLast\n ? `M${x} 0V${y - ARC}${elbow.slice(elbow.indexOf('A'))}`\n : `M${x} 0V${height}${elbow}`;\n return d;\n};\n\nconst TreeNode = memo<TreeNodeProps>(({ node, depth, isLast, trail }) => {\n const ctx = useTreeContext();\n const expandable = isExpandable(node);\n const expanded = expandable && ctx.expanded.has(node.key);\n const disabled = ctx.disabled || !!node.disabled;\n const checkable = ctx.checkable && node.checkable !== false;\n const checkState = ctx.checked.has(node.key)\n ? 'checked'\n : ctx.halfChecked.has(node.key)\n ? 'mixed'\n : 'unchecked';\n const rowHeight =\n typeof ctx.styles.node?.height === 'number' ? ctx.styles.node.height : controlHeight[ctx.size];\n\n const switcherIcon =\n typeof ctx.switcherIcon === 'function'\n ? ctx.switcherIcon({ expanded, node })\n : (ctx.switcherIcon ?? <Icon icon={ChevronRight} size={14} />);\n\n const rowStyle: CSSProperties = {\n height: rowHeight,\n paddingInlineStart: depth * ctx.indent,\n ...ctx.styles.node,\n };\n\n const select = (event: MouseEvent) => ctx.toggleSelect(node, event);\n\n return (\n <>\n <div\n data-scope-item\n aria-disabled={disabled || undefined}\n aria-expanded={expandable ? expanded : undefined}\n aria-level={depth + 1}\n aria-selected={ctx.selected.has(node.key)}\n data-id={node.key}\n role=\"treeitem\"\n style={rowStyle}\n tabIndex={ctx.activeKey === node.key ? 0 : -1}\n aria-checked={\n checkable ? (checkState === 'mixed' ? 'mixed' : checkState === 'checked') : undefined\n }\n className={cx(\n styles.node,\n ctx.blockNode && styles.nodeBlock,\n disabled && styles.nodeDisabled,\n ctx.classNames.node,\n )}\n onClick={ctx.blockNode ? select : undefined}\n onContextMenu={(event) => ctx.onRightClick(event, node)}\n onFocus={() => ctx.setActiveKey(node.key)}\n >\n {ctx.showLine && depth > 0 && (\n <svg\n aria-hidden\n className={cx(styles.guide, ctx.classNames.guide)}\n height={rowHeight}\n style={ctx.styles.guide}\n width={depth * ctx.indent}\n >\n <path d={guidePath(depth, isLast, trail, ctx.indent, rowHeight)} />\n </svg>\n )}\n <button\n aria-hidden\n style={ctx.styles.switcher}\n tabIndex={-1}\n type=\"button\"\n className={cx(\n styles.switcher,\n !expandable && styles.switcherLeaf,\n ctx.classNames.switcher,\n )}\n onClick={(event) => {\n event.stopPropagation();\n ctx.toggleExpand(node);\n }}\n >\n {switcherIcon}\n </button>\n {checkable && (\n <Checkbox\n checked={checkState === 'checked'}\n className={styles.checkbox}\n disabled={disabled}\n indeterminate={checkState === 'mixed'}\n onChange={() => ctx.toggleCheck(node)}\n onClick={(event) => event.stopPropagation()}\n />\n )}\n {ctx.showIcon && (\n <span className={styles.icon}>\n {node.icon ?? <Icon icon={expandable ? Folder : File} size={16} />}\n </span>\n )}\n <span\n style={ctx.styles.title}\n className={cx(\n styles.title,\n ctx.blockNode ? styles.titleBlock : styles.titleInline,\n ctx.classNames.title,\n )}\n onClick={ctx.blockNode ? undefined : select}\n >\n {ctx.titleRender ? ctx.titleRender(node) : node.title}\n </span>\n </div>\n {expandable && (\n <Collapsible.Root open={expanded}>\n <Collapsible.Panel className={styles.panel}>\n {node.children!.map((child, i) => (\n <TreeNode\n depth={depth + 1}\n isLast={i === node.children!.length - 1}\n key={child.key}\n node={child}\n trail={[...trail, !isLast]}\n />\n ))}\n </Collapsible.Panel>\n </Collapsible.Root>\n )}\n </>\n );\n});\n\nTreeNode.displayName = 'TreeNode';\n\nexport default TreeNode;\n"],"mappings":"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"}