Collapsible File Tree
A recursive, data-driven tree of folders and files with expand/collapse toggles.
3 個のフレームワーク初級
A file tree whose rows reveal add, rename and delete buttons on hover and focus.
<!-- Per-row actions are hidden by opacity, not display, so they stay in the tab
order and reveal on keyboard focus (group-focus-within) as well as hover.
Each button has a real aria-label. -->
<nav class="w-full max-w-sm rounded-xl border border-gray-200 bg-white p-2 text-sm text-gray-700 dark:border-gray-800 dark:bg-gray-950 dark:text-gray-300">
<ul role="tree" aria-label="Project files" class="space-y-0.5">
<li role="treeitem">
<div class="group flex min-w-0 items-center gap-1.5 rounded-md px-2 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-900">
<span class="w-3.5 shrink-0"></span>
<svg viewBox="0 0 16 16" fill="currentColor" class="h-4 w-4 shrink-0 text-gray-400" aria-hidden="true"><path d="M4 1.5h4.6L13 5.9V14a.5.5 0 0 1-.5.5h-8A.5.5 0 0 1 4 14V2a.5.5 0 0 1 .5-.5z"/></svg>
<span class="truncate">main.ts</span>
<span class="ml-auto flex shrink-0 items-center gap-0.5 pl-1">
<button type="button" aria-label="Rename main.ts" class="rounded p-1 text-gray-400 opacity-0 hover:bg-gray-200 hover:text-gray-700 focus-visible:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-gray-800"><svg viewBox="0 0 16 16" fill="currentColor" class="h-3.5 w-3.5" aria-hidden="true"><path d="M11.5 1.5 14.5 4.5 6 13H3v-3zM10.4 2.6 12 4.2"/></svg></button>
<button type="button" aria-label="Delete main.ts" class="rounded p-1 text-gray-400 opacity-0 hover:bg-gray-200 hover:text-gray-700 focus-visible:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-gray-800"><svg viewBox="0 0 16 16" fill="currentColor" class="h-3.5 w-3.5" aria-hidden="true"><path d="M6 2h4l.5 1H13v1.5H3V3h2.5zM4 5h8l-.6 8.5A1 1 0 0 1 10.4 14.5H5.6a1 1 0 0 1-1-1z"/></svg></button>
</span>
</div>
</li>
</ul>
</nav>| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
nodes必須 | TreeNode[] | - | Nodes |
label | string | 'Project files' | 読み込み中に読み上げられるアクセシブルなラベル。 |
onAction | (action: TreeAction, path: string) => void | - | On action |
Each row carries an action rail wired to an `onAction(action, path)` callback. The buttons are hidden with opacity rather than display, so they stay in the tab order and reveal on keyboard focus via `group-focus-within` as well as on hover - a hover-only menu is unreachable by keyboard.