Skip to content

Components

TransferList

Move items between two sets with the keyboard: the ids on the right are the whole value, so a form saves one array.

Examples

Examples

Two panes, one value

`value` is the right-hand set. Name both panes: `sourceLabel` and `targetLabel` are the names a screen-reader user navigates by.

Available fields

  • volumeBase units
  • returnsLog return
  • volatility20d realised
  • regimeClassified state

Selected fields

  • symbolTicker
  • priceClose, adjusted

symbol, price

Dense panes

Set `height` to the dense end when the list sits inside a panel or a settings row; 240 px is the default that keeps both panes scannable.

Available

  • writeEdit the spec and save revisions
  • publishPublish a revision
  • adminChange members and policies

Granted

  • readSee the run and its artifacts
  • runQueue a backtest

Uncontrolled, with a starting set

With `onValueChange` omitted the component keeps its own selection; `defaultValue` decides where it starts.

Available

  • publishPublish a revision
  • adminChange members and policies

Granted

  • readSee the run and its artifacts
  • writeEdit the spec and save revisions
  • runQueue a backtest

Usage

import { TransferList } from "@luc/ui";
<TransferList items={columns} value={chosen} onValueChange={setChosen} />

Items are `{ id, label, description? }` and the value is an array of ids, so the selection survives a re-render that rebuilds the item objects.

API

Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.

Exported symbols
ExportKindSignature
TransferList7 documented props({ items, value, defaultValue, onValueChange, sourceLabel, targetLabel, height, className, ...props }: TransferListProps) => import("@types/react").JSX.Element

TransferList props

Type: TransferListProps

Values the compiler reads from the declaration.

TransferList props
PropTypeDefaultNotes
defaultValue?readonly string[] | undefined—
height?number | undefined—Pane height in pixels. Default 240.
itemsreadonly TransferItem[]—
onValueChange?((ids: string[]) => void) | undefined—
sourceLabel?string | undefined—
targetLabel?string | undefined—
value?readonly string[] | undefined—Ids on the right-hand side.

Guidelines

Do

  • Use it when the order or the membership of a set is the value — column sets, watchlists, permissions.
  • Name both panes with `sourceLabel` and `targetLabel`: they are the landmark names a screen-reader user navigates by.
  • Set `height` to the dense end when the list sits inside a panel; 240 px is the default that keeps both panes scannable.

Don't

  • Use a transfer list where a multi-select would do: two panes cost vertical space that a dropdown does not.
  • Rely on drag and drop — this component moves items with buttons and the keyboard.
  • Change the `items` prop identity on every render; the panes derive from it and the selection is keyed by id.

Accessibility

Both panes are labelled lists and every move is a real button, so the whole interaction is reachable by keyboard and announced — the buttons carry the item's name, not just an arrow glyph.

Usage

import { TransferList } from "@luc/ui";
<TransferList items={columns} value={chosen} onValueChange={setChosen} />

Guidelines

Do

  • Use it when the order or the membership of a set is the value — column sets, watchlists, permissions.
  • Name both panes with `sourceLabel` and `targetLabel`: they are the landmark names a screen-reader user navigates by.
  • Set `height` to the dense end when the list sits inside a panel; 240 px is the default that keeps both panes scannable.

Don't

  • Use a transfer list where a multi-select would do: two panes cost vertical space that a dropdown does not.
  • Rely on drag and drop — this component moves items with buttons and the keyboard.
  • Change the `items` prop identity on every render; the panes derive from it and the selection is keyed by id.

Accessibility

Both panes are labelled lists and every move is a real button, so the whole interaction is reachable by keyboard and announced — the buttons carry the item's name, not just an arrow glyph.

Luc UI v1.0TransferListdark theme