diff options
| author | adamelmore <[email protected]> | 2026-01-25 21:57:30 -0600 |
|---|---|---|
| committer | adamelmore <[email protected]> | 2026-01-26 11:07:51 -0600 |
| commit | ebeed03115b61f812c56c66785a09be61be35468 (patch) | |
| tree | 8838b6a7a3533c9783e6f7bdd03e1b1795fa8a2a /packages/app/src/components | |
| parent | d9eed4c6cacf59089e6b6d6101deff58c7bd5040 (diff) | |
| download | opencode-ebeed03115b61f812c56c66785a09be61be35468.tar.gz opencode-ebeed03115b61f812c56c66785a09be61be35468.zip | |
wip(app): file tree mode
Diffstat (limited to 'packages/app/src/components')
| -rw-r--r-- | packages/app/src/components/file-tree.tsx | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/packages/app/src/components/file-tree.tsx b/packages/app/src/components/file-tree.tsx index 791b33b4a..ac435095d 100644 --- a/packages/app/src/components/file-tree.tsx +++ b/packages/app/src/components/file-tree.tsx @@ -2,7 +2,16 @@ import { useFile } from "@/context/file" import { Collapsible } from "@opencode-ai/ui/collapsible" import { FileIcon } from "@opencode-ai/ui/file-icon" import { Tooltip } from "@opencode-ai/ui/tooltip" -import { createEffect, For, Match, splitProps, Switch, type ComponentProps, type ParentProps } from "solid-js" +import { + createEffect, + createMemo, + For, + Match, + splitProps, + Switch, + type ComponentProps, + type ParentProps, +} from "solid-js" import { Dynamic } from "solid-js/web" import type { FileNode } from "@opencode-ai/sdk/v2" @@ -11,15 +20,45 @@ export default function FileTree(props: { class?: string nodeClass?: string level?: number + allowed?: readonly string[] onFileClick?: (file: FileNode) => void }) { const file = useFile() const level = props.level ?? 0 + const filter = createMemo(() => { + const allowed = props.allowed + if (!allowed) return + + const files = new Set(allowed) + const dirs = new Set<string>() + + for (const item of allowed) { + const parts = item.split("/") + const parents = parts.slice(0, -1) + for (const [idx] of parents.entries()) { + const dir = parents.slice(0, idx + 1).join("/") + if (dir) dirs.add(dir) + } + } + + return { files, dirs } + }) + createEffect(() => { void file.tree.list(props.path) }) + const nodes = createMemo(() => { + const nodes = file.tree.children(props.path) + const current = filter() + if (!current) return nodes + return nodes.filter((node) => { + if (node.type === "file") return current.files.has(node.path) + return current.dirs.has(node.path) + }) + }) + const Node = ( p: ParentProps & ComponentProps<"div"> & @@ -81,7 +120,7 @@ export default function FileTree(props: { return ( <div class={`flex flex-col ${props.class ?? ""}`}> - <For each={file.tree.children(props.path)}> + <For each={nodes()}> {(node) => { const expanded = () => file.tree.state(node.path)?.expanded ?? false return ( @@ -102,7 +141,12 @@ export default function FileTree(props: { </Node> </Collapsible.Trigger> <Collapsible.Content> - <FileTree path={node.path} level={level + 1} onFileClick={props.onFileClick} /> + <FileTree + path={node.path} + level={level + 1} + allowed={props.allowed} + onFileClick={props.onFileClick} + /> </Collapsible.Content> </Collapsible> </Match> |
