TransferList

Two lists, and the buttons that move the checked items from one to the other.

Two lists, and the buttons that move the checked items from one to the other. Each list is a list of rows whose checkbox is the row - one tab stop, the label toggles it - so keys, assistive technology and the platform's checkboxes work as they always do.

Every name is yours - the lists' titles and the four buttons' - so it carries no language of its own.

import { TransferList } from '@soroush.tech/design-system/TransferList'

;<TransferList
  items={[
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'date', label: 'Date', disabled: true },
  ]}
  value={chosen}
  onChange={setChosen}
  leftLabel="Choices"
  rightLabel="Chosen"
  moveRightLabel="Move the checked items right"
  moveLeftLabel="Move the checked items left"
/>

Examples

Default

Choices
Chosen
const args: Partial<TransferListProps> = {
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<TransferList key={JSON.stringify(args.defaultValue)} {...args} />

Move All

Choices
Chosen
const args: Partial<TransferListProps> = {
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  shouldShowMoveAll: true,
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<TransferList
  key={JSON.stringify(args.defaultValue)}
  moveAllRightLabel="Move all right"
  moveAllLeftLabel="Move all left"
  {...args}
/>

Select All

Choices0/3
Chosen0/1
const args: Partial<TransferListProps> = {
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  hasSelectAll: true,
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<TransferList key={JSON.stringify(args.defaultValue)} {...args} />

Controlled Value

Choices
Chosen
On the right: cherry
const args: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<Controlled {...args} />

Disabled Item

Choices0/3
Chosen0/0
const args: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
  shouldShowMoveAll: true,
  hasSelectAll: true,
}

<TransferList
  {...args}
  moveAllRightLabel="Move all right"
  moveAllLeftLabel="Move all left"
  items={[
    { value: 'locked', label: 'Locked', disabled: true },
    { value: 'free', label: 'Free' },
    { value: 'other', label: 'Other' },
  ]}
/>

Sizes

Choices
Chosen
Choices
Chosen
Choices
Chosen
const args: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<Flex gap={3}>
  {(['sm', 'md', 'lg'] as const).map((size) => (
    <TransferList key={size} {...args} size={size} />
  ))}
</Flex>

States

Choices
Chosen
Choices
Chosen
const args: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<Flex gap={3}>
  <TransferList {...args} error />
  <TransferList {...args} disabled />
</Flex>

In Form Control

Choices
Chosen

Choose any.

const { error, disabled, size, color, items, ...args }: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<FormControl error={error} disabled={disabled} size={size} color={color}>
  <FormLabel>Fruit</FormLabel>
  <TransferList
    items={items}
    leftLabel={args.leftLabel}
    rightLabel={args.rightLabel}
    moveRightLabel={args.moveRightLabel}
    moveLeftLabel={args.moveLeftLabel}
  />
  <FormHelperText>{error ? 'Choose at least one.' : 'Choose any.'}</FormHelperText>
</FormControl>

Right To Left

Choices
Chosen
const args: Partial<TransferListProps> = {
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<View dir="rtl">
  <TransferList {...args} />
</View>

Customized

Choices0/4
Chosen0/0
const args: Partial<TransferListProps> = {
  items: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date', disabled: true }],
  defaultValue: ['cherry'],
  leftLabel: 'Choices',
  rightLabel: 'Chosen',
  moveRightLabel: 'Move right',
  moveLeftLabel: 'Move left',
}

<ThemeProvider theme={customized}>
  <TransferList
    items={args.items}
    leftLabel={args.leftLabel}
    rightLabel={args.rightLabel}
    moveRightLabel={args.moveRightLabel}
    moveLeftLabel={args.moveLeftLabel}
  />
</ThemeProvider>