# Header With Search Toolbar

> List view page header with a title, primary action, and a toolbar of search input, status and sort selects, and a list or grid view toggle.

A shadcn/ui block from the [@7ovr](https://7ovr.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/7ovr/page-header-5).

- Page, with a live preview: https://shadcn.exchange/r/7ovr/page-header-5
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/7ovr/page-header-5-light-22a0180ecb58a947.png
- Registry item: https://7ovr.com/r/page-header-5.json
- Categories: page-header
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://7ovr.com/r/page-header-5.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `@base-ui/react`
- Registry items: `button`, `input`, `select`, `separator`

## Files

### `registry/blocks/page-header/5/page-header-block.tsx`

```tsx
"use client"

import { useState } from "react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { IconPlaceholder } from "@/components/icons/icon-placeholder"

export default function PageHeaderBlock() {
  const [view, setView] = useState<"grid" | "list">("list")

  return (
    <section className="w-full bg-background px-6 py-10 text-foreground">
      <div className="mx-auto w-full max-w-4xl">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
          <div className="flex flex-col gap-1">
            <h1 className="font-heading text-2xl font-bold tracking-tight">
              Projects
            </h1>
            <p className="text-sm text-muted-foreground">
              Manage and track every project across your workspace.
            </p>
          </div>
          <Button className="w-full sm:w-auto">
            <IconPlaceholder
              lucide="Plus"
              tabler="IconPlus"
              hugeicons="Add01Icon"
              phosphor="Plus"
              remixicon="RiAddLine"
              data-icon="inline-start"
              aria-hidden="true"
            />
            New project
          </Button>
        </div>

        <Separator className="my-5" />

        <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div className="relative w-full sm:max-w-xs">
            <IconPlaceholder
              lucide="Search"
              tabler="IconSearch"
              hugeicons="SearchIcon"
              phosphor="MagnifyingGlass"
              remixicon="RiSearchLine"
              className="pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
              aria-hidden="true"
            />
            <Input
              type="search"
              placeholder="Search projects..."
              className="pl-8"
              aria-label="Search projects"
            />
          </div>

          <div className="flex items-center gap-2">
            <Select defaultValue="Active">
              <SelectTrigger className="w-32" aria-label="Filter by status">
                <SelectValue />
              </SelectTrigger>
              <SelectContent alignItemWithTrigger={false}>
                <SelectItem value="All">All</SelectItem>
                <SelectItem value="Active">Active</SelectItem>
                <SelectItem value="Archived">Archived</SelectItem>
              </SelectContent>
            </Select>
            <Select defaultValue="Most recent">
              <SelectTrigger className="w-36" aria-label="Sort by">
                <SelectValue />
              </SelectTrigger>
              <SelectContent alignItemWithTrigger={false}>
                <SelectItem value="Most recent">Most recent</SelectItem>
                <SelectItem value="Name">Name</SelectItem>
                <SelectItem value="Owner">Owner</SelectItem>
              </SelectContent>
            </Select>
            <div className="flex overflow-hidden rounded-lg border border-border">
              <button
                type="button"
                aria-label="List view"
                aria-pressed={view === "list"}
                onClick={() => setView("list")}
                className={cn(
                  "flex size-8 items-center justify-center transition-colors",
                  view === "list"
                    ? "bg-foreground text-background"
                    : "text-muted-foreground hover:bg-muted/60"
                )}
              >
                <IconPlaceholder
                  lucide="List"
                  tabler="IconList"
                  hugeicons="LeftToRightListBulletIcon"
                  phosphor="ListBullets"
                  remixicon="RiListUnordered"
                  className="size-4"
                  aria-hidden="true"
                />
              </button>
              <button
                type="button"
                aria-label="Grid view"
                aria-pressed={view === "grid"}
                onClick={() => setView("grid")}
                className={cn(
                  "flex size-8 items-center justify-center border-l border-border transition-colors",
                  view === "grid"
                    ? "bg-foreground text-background"
                    : "text-muted-foreground hover:bg-muted/60"
                )}
              >
                <IconPlaceholder
                  lucide="Grid"
                  tabler="IconLayoutGrid"
                  hugeicons="GridIcon"
                  phosphor="GridFour"
                  remixicon="RiGridFill"
                  className="size-4"
                  aria-hidden="true"
                />
              </button>
            </div>
          </div>
        </div>
      </div>
    </section>
  )
}
```
