Transfer list
FreeChoose a subset from a long list: tick items and move them across, and they slide into the other side from where they came.
pnpm dlx shadcn@latest add https://caliperui.site/r/transfer-list.jsonColumns6
In the export3
When to use #
Use it for
- Permissions, columns to show, fields to export.
- Building a list in a chosen order.
Skip it when
- A few options; use checkboxes or a multi-select.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/transfer-list.json
Adds its 6 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { useState } from "react" import { TransferList } from "@/components/ui/transfer-list" const fields = [ { id: "date", label: "Date", description: "Invoice date" }, { id: "number", label: "Number", description: "INV-2041" }, { id: "customer", label: "Customer", description: "Company name" }, { id: "net", label: "Net amount", description: "Before tax" }, { id: "tax", label: "Tax", description: "VAT or sales tax" }, { id: "total", label: "Total", description: "Net plus tax" }, { id: "currency", label: "Currency", description: "ISO code" }, { id: "status", label: "Status", description: "Paid, due, overdue" }, { id: "owner", label: "Owner", description: "Account owner" }, ]; export function TransferListDemo() { const [chosen, setChosen] = useState(["date", "number", "total"]); return <TransferList className="w-full max-w-2xl" items={fields} chosen={chosen} onChosenChange={setChosen} availableLabel="Columns" chosenLabel="In the export" searchLabel="Search columns" />; }
API reference #
TransferList
component
Accessibility #
It exposes group and status semantics, with aria-labelledby, aria-label and aria-hidden kept in step with state. Changes that matter are announced through a live region.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.