# V combobox 19

> Sprint selector with status badge and date range per item

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

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

## Install

```bash
npx shadcn@latest add https://ui.cnippet.dev/r/v-combobox-19.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/combobox`

## Files

### `registry/default/variants/v-combobox-19.tsx`

```tsx
"use client";

import { ChevronsUpDownIcon } from "lucide-react";
import { useState } from "react";
import { Badge } from "@/registry/default/ui/badge";
import { Button } from "@/registry/default/ui/button";
import {
  Combobox,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
  ComboboxPopup,
  ComboboxTrigger,
  ComboboxValue,
} from "@/registry/default/ui/combobox";

interface Sprint {
  label: string;
  value: string;
  status: "active" | "upcoming" | "completed";
  dates: string;
}

const sprints: Sprint[] = [
  { dates: "Jun 2–15", label: "Sprint 24", status: "active", value: "s24" },
  { dates: "Jun 16–29", label: "Sprint 25", status: "upcoming", value: "s25" },
  {
    dates: "Jun 30–Jul 13",
    label: "Sprint 26",
    status: "upcoming",
    value: "s26",
  },
  {
    dates: "May 19–Jun 1",
    label: "Sprint 23",
    status: "completed",
    value: "s23",
  },
  { dates: "May 5–18", label: "Sprint 22", status: "completed", value: "s22" },
];

const statusVariant: Record<
  Sprint["status"],
  "success" | "info" | "secondary"
> = {
  active: "success",
  completed: "secondary",
  upcoming: "info",
};

export default function Particle() {
  const [value, setValue] = useState<Sprint | null>(sprints[0] ?? null);

  return (
    <Combobox
      items={sprints}
      onValueChange={(v) => setValue(v as Sprint | null)}
      value={value}
    >
      <ComboboxTrigger
        render={
          <Button
            className="w-full max-w-xs justify-between font-normal"
            variant="outline"
          />
        }
      >
        <ComboboxValue placeholder="Select sprint..." />
        <ChevronsUpDownIcon className="-me-1!" />
      </ComboboxTrigger>
      <ComboboxPopup className="w-64">
        <ComboboxInput placeholder="Search sprints..." showTrigger={false} />
        <ComboboxEmpty>No sprints found.</ComboboxEmpty>
        <ComboboxList>
          {(sprint: Sprint) => (
            <ComboboxItem
              className="**:data-check:ms-auto"
              key={sprint.value}
              value={sprint}
            >
              <div className="flex flex-1 items-center justify-between gap-2">
                <span className="text-sm">{sprint.label}</span>
                <div className="flex items-center gap-2">
                  <span className="text-muted-foreground text-xs">
                    {sprint.dates}
                  </span>
                  <Badge size="sm" variant={statusVariant[sprint.status]}>
                    {sprint.status}
                  </Badge>
                </div>
              </div>
            </ComboboxItem>
          )}
        </ComboboxList>
      </ComboboxPopup>
    </Combobox>
  );
}
```
