import { useSignal } from '@preact/signals' import clsx from 'clsx' import { useEffect, useState } from 'preact/hooks' export const EXAMPLE_TREE = { type: 'root', children: [ { type: 'folder', name: 'bin/', children: [ { type: 'file', name: 'a.out', }, ], }, { type: 'file', name: 'main.c', }, { type: 'file', name: 'data.csv', }, ], } const flattenTree = (node, depth = 0, path = []) => { if (node.type === 'root') { return node.children.flatMap(entry => flattenTree(entry, depth, [])) } if (node.type === 'folder') return [ { depth, type: 'folder', name: node.name, path: path.join('/') + '/', }, ...node.children.flatMap(entry => flattenTree(entry, depth + 1, [...path, node.name])), ] if (node.type === 'file') { return [ { depth, type: 'file', name: node.name, path: path.join('/'), }, ] } throw new Error(`invalid node type "${node?.type ?? ''}"`) } const TreeViewNode = ({ listDir, actionOpenFile, node, depth, path }) => { if (node.type === 'root') { const [children, setChildren] = useState([]) useEffect(async () => { setChildren(await listDir(path)) }, []) return children.flatMap(entry => ( )) } if (node.type === 'folder') { const [collapsed, setCollapsed] = useState(true) const [children, setChildren] = useState([]) useEffect(async () => { setChildren(collapsed ? [] : await listDir(path)) }, [collapsed]) return ( <>
setCollapsed(c => !c)} >
folder
{node.name}/
{!collapsed && children.flatMap(entry => ( ))} ) } if (node.type === 'file') { return (
{ console.log('open', path) actionOpenFile?.(path) }} >
description
{node.name}
) } } const ICONS = { ['folder']: 'folder', ['file']: 'description', } export const TreeView = ({ listDir, actionOpenFile, rootPath }) => { return (
) }