# Projects Page

> A whole projects page for an app: the left rail beside one set of projects shown as a board, a list, or a timeline. On narrow screens the rail moves into a menu.

- Name: `projects-page`
- Status: beta
- Categories: dashboard, projects, page
- Files: the install writes `projects-page.tsx`, and any part files named `projects-page-*.tsx`, to your `components` alias, `@/components` by default. Edit them freely. They are yours.
- npm packages: `lucide-react`. The install adds them.
- Other registry items: `@arbokui/project-views`, `@arbokui/rail`, `@arbokui/sheet`, `@arbokui/button`, `@arbokui/tooltip`. The install adds them.
- Gallery: https://arbokui.com/templates/projects-page
- Registry item: https://arbokui.com/r/projects-page.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the template. It also adds every component it uses:

   ```bash
   npx shadcn@latest add @arbokui/projects-page
   ```

## Use it for

- The projects screen of an app. Render it as the whole page, from your app's page file.
- Pass the rail's places in \`rail\` and the projects in \`projectViews\`. Each takes the props of its own part.
- Mark the place you're in with the rail's \`active\` or \`defaultActive\`. The rail beside the page and the one in the menu stay in step.
- Render one Toaster on the page, so moving or removing a project can offer Undo.
- Set \`embedded\` when you show the page inside another page, like a gallery, so it has no second main.

## Avoid it for

- The rail's \`onSearch\` here. The rail draws twice, beside the page and in the menu, so its shortcut would listen twice. Put search in a Command Menu instead.
- A hero, a tagline, or a feature grid on top. An app screen leads with the work.

## Props

- `rail`: `RailProps`. Required. The Rail's props: the app's name, the places, and Settings. Below 40rem the rail moves into a menu, and its header sits beside the menu button.
- `projectViews`: `ProjectViewsProps`. Required. The Project Views block's props: the projects, the stages, today, and the view to start on.
- `menuLabel`: `string`. Default `"Menu"`. Names the menu button and the menu on narrow screens.
- `embedded`: `boolean`. Default `false`. Renders the content in a div, not a main, for a preview inside another page.
- `className`: `string`. Extra classes on the page. Later classes win.

## Accessibility

- The content sits in one main, unless embedded is set.
- On narrow screens the menu button has its label as its name and its tooltip, and the menu opens as a dialog named by the same label. Choosing a place closes it.
- The rail and the projects keep their own keyboard and screen reader behavior.

## Examples

### Projects beside the app's rail

```tsx
<ProjectsPage
  rail={{
    header: <span className="px-2 font-(--type-weight-strong)">Workspace</span>,
    groups: [{ items: [{ id: "home", label: "Overview", icon: "house" }, { id: "projects", label: "Projects", icon: "file-text" }] }],
    defaultActive: "projects",
    footer: { id: "settings", label: "Settings", icon: "settings" },
  }}
  projectViews={{
    today: "2026-10-30",
    defaultProjects: [
      { id: "help", name: "Help center", stage: "review", start: "2026-10-12", due: "2026-10-31" },
      { id: "payments", name: "Payments page", stage: "doing", start: "2026-10-19", due: "2026-11-06" },
    ],
  }}
/>
```

### A narrow-screen menu with its own name

```tsx
<ProjectsPage
  menuLabel="Places"
  rail={{
    groups: [{ items: [{ id: "home", label: "Overview", icon: "house" }, { id: "projects", label: "Projects", icon: "file-text" }] }],
    defaultActive: "projects",
  }}
  projectViews={{ today: "2026-10-30" }}
/>
```
