({
virtualNode,
onToggle,
selectedNodeId,
}: {
virtualNode: VirtualNode<JsonTreeViewNode>;
selectedNodeId?: string;
onToggle?: (node: JsonTreeViewNode, e: MouseEvent) => void;
})
| 114 | } |
| 115 | |
| 116 | function TreeViewNode({ |
| 117 | virtualNode, |
| 118 | onToggle, |
| 119 | selectedNodeId, |
| 120 | }: { |
| 121 | virtualNode: VirtualNode<JsonTreeViewNode>; |
| 122 | selectedNodeId?: string; |
| 123 | onToggle?: (node: JsonTreeViewNode, e: MouseEvent) => void; |
| 124 | }) { |
| 125 | const { node, virtualItem, depth } = virtualNode; |
| 126 | |
| 127 | const indentClassName = computeTreeNodePaddingClass(depth); |
| 128 | |
| 129 | const isSelected = selectedNodeId === node.id; |
| 130 | |
| 131 | return ( |
| 132 | <div |
| 133 | style={{ |
| 134 | position: "absolute", |
| 135 | top: 0, |
| 136 | left: 0, |
| 137 | width: "100%", |
| 138 | height: `${virtualNode.size}px`, |
| 139 | transform: `translateY(${virtualNode.start}px)`, |
| 140 | }} |
| 141 | key={virtualNode.node.id} |
| 142 | {...virtualNode.getItemProps()} |
| 143 | > |
| 144 | <div |
| 145 | className={`h-full flex pl-5 rounded-sm select-none ${ |
| 146 | isSelected |
| 147 | ? "bg-indigo-700" |
| 148 | : virtualItem.index % 2 |
| 149 | ? "dark:bg-slate-900" |
| 150 | : "bg-slate-100 bg-opacity-90 dark:bg-slate-800 dark:bg-opacity-30" |
| 151 | }`} |
| 152 | > |
| 153 | <div className={`pl-2 w-2/6 items-center flex`}> |
| 154 | {node.children && node.children.length > 0 && ( |
| 155 | <span |
| 156 | onClick={(e) => { |
| 157 | if (onToggle) { |
| 158 | e.preventDefault(); |
| 159 | onToggle(node, e.nativeEvent); |
| 160 | } |
| 161 | }} |
| 162 | > |
| 163 | {virtualNode.isCollapsed ? ( |
| 164 | <ChevronRightIcon |
| 165 | className={`w-4 h-4 mr-1 -ml-5 ${ |
| 166 | isSelected |
| 167 | ? "text-slate-100" |
| 168 | : "text-slate-600 dark:text-slate-100" |
| 169 | }`} |
| 170 | /> |
| 171 | ) : ( |
| 172 | <ChevronDownIcon |
| 173 | className={`w-4 h-4 mr-1 -ml-5 ${ |
nothing calls this directly
no test coverage detected