rmnr
DocsTourSlicesBest PracticeAgentsInstall

Command Palette

Search for a command to run...

New

Slice · AI prompt

File Explorer — Tree + CRUD + Preview + Properties

Backend-agnostic file manager: directory tree sidebar, breadcrumb nav, grid/list views, full CRUD.

Resource detail View source
Copy this prompt into Claude / Codex / Cursor
file-explorer.prompt.mdmarkdown
# Install `file-explorer` — File Explorer — Tree + CRUD + Preview + Properties

> Backend-agnostic file manager: directory tree sidebar, breadcrumb nav, grid/list views, full CRUD.

📚 Knowledge base : https://resource.rahmanef.com/llms.txt
📦 Slice detail   : https://resource.rahmanef.com/slices/file-explorer
🧠 JSON catalog   : https://resource.rahmanef.com/api/knowledge?slice=file-explorer
🔗 Source         : https://github.com/rahmanef63/resource-site/tree/main/frontend/slices/file-explorer

## 1. Install

```bash
npx rahman-resources add file-explorer
# alias: npx rr add file-explorer
```

The CLI copies `frontend/slices/file-explorer/` into your project + augments `.env.example` + installs npm deps automatically. Run it from your project root.

## 2. What it ships

- npm: `lucide-react`
- shadcn primitives: `button`, `input`, `scroll-area`, `separator`, `dropdown-menu`, `sheet`, `dialog`

## 3. Wire it up

Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. The slice is self-contained — imports only @/components/ui/* + @/lib/utils (cn). The filesystem backend is injected; nothing is hardcoded.

STEP 1 — Install. `npx rr add file-explorer`. Ensure `@/features/file-explorer` resolves in tsconfig paths and Tailwind's content globs scan the slice folder.

STEP 2 — shadcn + npm. `npx shadcn@latest add button input scroll-area separator dropdown-menu sheet`. npm: lucide-react.

STEP 3 — Mount it. Drop it in with NO adapter prop — it falls back to the backend configured in lib/backend.ts (the writable in-memory mock by default), so it works out of the box with realistic seed data and full CRUD:
```tsx
"use client";
import { FileExplorer } from "@/features/file-explorer";
export default function Page() {
  return (
    <div className="h-dvh">
      <FileExplorer rootLabel="Files" onOpenFile={(path) => console.log("open", path)} />
    </div>
  );
}
```

STEP 4 — The backend switch (ONE file). Go to a real filesystem without touching any component: edit `slices/file-explorer/lib/backend.ts` and set `FILE_EXPLORER_BACKEND = "mock" | "live" | "convex"` (or set env `NEXT_PUBLIC_FILE_EXPLORER_BACKEND`). "live" = REST host fs (os-vps /api/v1/fs shape, base via NEXT_PUBLIC_FILES_API_URL — see adapter/live.ts). "convex" = self-hosted Convex fs functions, PREPARED but inert until you wire your generated client + api in the switch (see adapter/convex.ts; the slice imports nothing from @convex so the build stays green even without Convex). You can still pass `adapter={…}` to override per-instance.

STEP 5 — Custom adapter. Implement FileExplorerAdapter: { mode: "live"|"mock"|"readonly", list(path), mkdir(path), remove(path), move(from,to), copy(from,to), upload(dest,files), usage(), rawUrl(path), write?(path,content) }. `list` returns { path, entries:[{name,kind,size,ext?}], roots?, parent? }. Set mode:"readonly" to show an inline notice instead of mutating. `rawUrl(path)` returns a bytes URL for image thumbnails (return "" to fall back to icons).

The container owns the box — render <FileExplorer> inside something with a height (h-dvh / h-full). It self-provides its adapter context; no extra provider needed.

## Rules of engagement

- shadcn-only UI primitives. No raw `<button>` / `<dialog>` / native date or file inputs.
- 200-line hard cap per source file (extract neighbours when over).
- All Convex queries hit an index (`.withIndex(...)`); never bare `.collect()`.
- Public mutations/queries declare `args:` validators + authz.
- Full ruleset: https://resource.rahmanef.com/best-practice

The agent will fetch /llms.txt for the full ruleset and use /api/knowledge for the JSON catalog.