# V toolbar 4

> Data table toolbar with search input, filter controls, and add row

A shadcn/ui block from the [@cnippet](https://ui.cnippet.dev/) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/cnippet/v-toolbar-4).

- Page, with a live preview: https://shadcn.exchange/r/cnippet/v-toolbar-4
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/cnippet/v-toolbar-4-light-e34052da03effd52.png
- Registry item: https://ui.cnippet.dev/r/v-toolbar-4.json
- Categories: toolbar
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.cnippet.dev/r/v-toolbar-4.json
```

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

## Dependencies

- Registry items: `@cnippet/toolbar`

## Files

### `registry/default/variants/v-toolbar-4.tsx`

```tsx
"use client";

import {
  Columns3Icon,
  DownloadIcon,
  FilterIcon,
  PlusIcon,
  SearchIcon,
  TrashIcon,
} from "lucide-react";
import { useState } from "react";
import { Button } from "@/registry/default/ui/button";
import {
  Toolbar,
  ToolbarButton,
  ToolbarGroup,
  ToolbarInput,
  ToolbarSeparator,
} from "@/registry/default/ui/toolbar";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/registry/default/ui/tooltip";

const iconActions = [
  { icon: FilterIcon, label: "Filter rows" },
  { icon: Columns3Icon, label: "Manage columns" },
  { icon: DownloadIcon, label: "Export CSV" },
  { icon: TrashIcon, label: "Delete selected" },
] as const;

export function Pattern() {
  const [query, setQuery] = useState("");

  return (
    <TooltipProvider>
      <Toolbar className="w-full max-w-lg">
        <ToolbarGroup className="flex-1">
          <div className="relative flex items-center">
            <SearchIcon className="pointer-events-none absolute left-2 size-3.5 text-muted-foreground" />
            <ToolbarInput
              className="h-7 w-full rounded-md border bg-transparent py-1 pr-2 pl-7 text-xs outline-none placeholder:text-muted-foreground focus:ring-1 focus:ring-ring"
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search rows…"
              value={query}
            />
          </div>
        </ToolbarGroup>

        <ToolbarSeparator />

        <ToolbarGroup>
          {iconActions.map(({ icon: Icon, label }) => (
            <Tooltip key={label}>
              <TooltipTrigger
                render={
                  <ToolbarButton
                    aria-label={label}
                    render={<Button size="icon" variant="ghost" />}
                  >
                    <Icon />
                  </ToolbarButton>
                }
              />
              <TooltipContent>{label}</TooltipContent>
            </Tooltip>
          ))}
        </ToolbarGroup>

        <ToolbarSeparator />

        <ToolbarGroup>
          <ToolbarButton render={<Button size="sm" />}>
            <PlusIcon className="size-3.5" />
            Add row
          </ToolbarButton>
        </ToolbarGroup>
      </Toolbar>
    </TooltipProvider>
  );
}
```
