TransferList

Move items between two lists
Import

Usage

Frameworks
Libraries
import { useState } from 'react';
import { TransferList, TransferListData } from '@mantine/core';
const initialValues: TransferListData = [
[
{ value: 'react', label: 'React' },
{ value: 'ng', label: 'Angular' },
{ value: 'next', label: 'Next.js' },
{ value: 'blitz', label: 'Blitz.js' },
{ value: 'gatsby', label: 'Gatsby.js' },
{ value: 'vue', label: 'Vue' },
{ value: 'jq', label: 'jQuery' },
],
[
{ value: 'sv', label: 'Svelte' },
{ value: 'rw', label: 'Redwood' },
{ value: 'np', label: 'NumPy' },
{ value: 'dj', label: 'Django' },
{ value: 'fl', label: 'Flask' },
],
];
function Demo() {
const [data, setData] = useState<TransferListData>(initialValues);
return (
<TransferList
value={data}
onChange={setData}
searchPlaceholder="Search..."
nothingFound="Nothing here"
titles={['Frameworks', 'Libraries']}
breakpoint="sm"
/>
);
}

Native scrollbars

By default, TransferList uses ScrollArea to render list. If you want to use native scrollbars instead, set div as a list component:

Frameworks
Libraries
<TransferList listHeight={100} listComponent="div" {/* ...other props */} />

Custom item component

To customize item appearance, replace default item component:

  • Add additional props to data
  • Build a component which will consume your data object
  • Provide custom component via itemComponent prop
  • Customize search with filter function
Employees to hire
Employees to fire
No one here
import { useState } from 'react';
import {
Checkbox,
Group,
Avatar,
Text,
TransferList,
TransferListData,
TransferListItemComponent,
TransferListItemComponentProps,
} from '@mantine/core';
const mockdata = [
{
value: 'bender',
image: 'https://img.icons8.com/clouds/256/000000/futurama-bender.png',
label: 'Bender Bending Rodríguez',
description: 'Fascinated with cooking, though has no sense of taste',
},
{
value: 'carol',
image: 'https://img.icons8.com/clouds/256/000000/futurama-mom.png',
label: 'Carol Miller',
description: 'One of the richest people on Earth',
},
// ...other items
];
const ItemComponent: TransferListItemComponent = ({
data,
selected,
}: TransferListItemComponentProps) => (
<Group noWrap>
<Avatar src={data.image} radius="xl" size="lg" />
<div style={{ flex: 1 }}>
<Text size="sm" weight={500}>
{data.label}
</Text>
<Text size="xs" color="dimmed" weight={400}>
{data.description}
</Text>
</div>
<Checkbox checked={selected} onChange={() => {}} tabIndex={-1} sx={{ pointerEvents: 'none' }} />
</Group>
);
function Demo() {
const [data, setData] = useState<TransferListData>([mockdata, []]);
return (
<TransferList
value={data}
onChange={setData}
searchPlaceholder="Search employees..."
nothingFound="No one here"
titles={['Employees to hire', 'Employees to fire']}
listHeight={300}
breakpoint="sm"
itemComponent={ItemComponent}
filter={(query, item) =>
item.label.toLowerCase().includes(query.toLowerCase().trim()) ||
item.description.toLowerCase().includes(query.toLowerCase().trim())
}
/>
);
}

Initial selection

Set initial selected items with initialSelection prop. Value should be a tuple of two arrays which contain values from data:

Frameworks
Libraries
<TransferList initialSelection={[['react', 'ng'], []]} />

Controlled search

You can optionally control the search inputs by providing searchValues and onSearch props. searchValues should be a tuple of two strings, one for each list:

Left search: --- / Right search: ---
Frameworks
Libraries
import { useState } from 'react'
import { TransferList, Stack, Text } from '@mantine/core';
function Demo() {
const [search, setSearch] = useState(['', '']);
return (
<Stack>
<Text>
<Text component="span" weight="bold">Left search: </Text>
{search[0] || '---'}
{' / '}
<Text component="span" weight="bold">Right search: </Text>
{search[1] || '---'}
</Text>
<TransferList
searchValues={search}
onSearch={setSearch}
{/* ...other props */}
/>
</Stack>
);
}

Transferring only found items

By default, TransferList transfers all items when you click the transferAll button.

By setting the transferAllMatchingFilter prop to true, TransferList will only transfer the items that match the current filter.

Frameworks
Libraries
<TransferList transferAllMatchingFilter />

Empty search VS empty list

You can specify a placeholder prop, which will be used in place of the nothingFound when a list is completely empty, and no query is set.

Frameworks
Libraries
function Demo() {
return (
<TransferList
nothingFound="Nothing found"
placeholder="No item left"
{/* ...other props */}
/>
);
}

Custom wording for each list

placeholder, nothingFound and searchPlaceholder props can take a tuple of values instead of a single value to customize each list independently.

Frameworks
Libraries
function Demo() {
return (
<TransferList
searchPlaceholder={['Search item to add...', 'Search item to remove...']}
nothingFound={['Cannot find item to add', 'Cannot find item to remove']}
placeholder={['No item left to add', 'No item left to remove']}
{/* ...other props */}
/>
);
}

Grouping items

import { useState } from 'react';
import { TransferList, TransferListData } from '@mantine/core';
const initialValues: TransferListData = [
[
{ value: 'react', label: 'React', group: 'Frameworks' },
{ value: 'ng', label: 'Angular', group: 'Frameworks' },
{ value: 'next', label: 'Next.js', group: 'Frameworks' },
{ value: 'jq', label: 'jQuery', group: 'Frameworks' },
{ value: 'sv', label: 'Svelte', group: 'Libraries' },
{ value: 'dj', label: 'Django', group: 'Libraries' },
{ value: 'fl', label: 'Flask', group: 'Libraries' },
],
[
{ value: 'blitz', label: 'Blitz.js', group: 'Frameworks' },
{ value: 'gatsby', label: 'Gatsby.js', group: 'Frameworks' },
{ value: 'vue', label: 'Vue', group: 'Frameworks' },
{ value: 'rw', label: 'Redwood', group: 'Libraries' },
{ value: 'np', label: 'NumPy', group: 'Libraries' },
],
];
function Demo() {
const [data, setData] = useState<TransferListData>(initialValues);
return (
<TransferList
value={data}
onChange={setData}
searchPlaceholder="Search..."
nothingFound="Nothing here"
/>
);
}

Custom control icons

Frameworks
Libraries
import {
IconFilePlus,
IconFolderPlus,
IconFileMinus,
IconFolderMinus,
} from '@tabler/icons-react';
import { TransferList } from '@mantine/core';
function Demo() {
return (
<TransferList
transferIcon={({ reversed }) => (reversed ? <IconFileMinus /> : <IconFilePlus />)}
transferAllIcon={({ reversed }) => (reversed ? <IconFolderMinus /> : <IconFolderPlus />)}
{/* ...other props */}
/>
)
}

Responsive styles

Set breakpoint prop to specify at which breakpoint TransferList will collapse to 1 column:

// -> breakpoint from theme.breakpoints: value is theme.breakpoints.sm
<TransferList breakpoint="sm" />
// -> breakpoint in rem: value is 40rem
<TransferList breakpoint={640} />

TransferList component props

NameTypeDescription
breakpoint
number | "xs" | "sm" | "md" | "lg" | "xl"
Breakpoint at which list will collapse to single column layout
filter
(query: string, item: TransferListItem) => boolean
Function to filter search results
initialSelection
Selection
Initial items selection
itemComponent
TransferListItemComponent
Custom item component
limit
number
Limit amount of items showed at a time
listComponent
any
Change list component, can be used to add custom scrollbars
listHeight
number
List items height
nothingFound
ReactNode | [ReactNode, ReactNode]
Nothing found message
onChange *
(value: TransferListData) => void
Called when value changes
onSearch
(value: [string, string]) => void
Called when one of the search queries changes
placeholder
ReactNode | [ReactNode, ReactNode]
Displayed when a list is empty and there is no search query
radius
number | "xs" | "sm" | "md" | "lg" | "xl"
Key of theme.radius or any valid CSS value to set border-radius, theme.defaultRadius by default
searchPlaceholder
string | [string, string]
Search fields placeholder
searchValues
[string, string]
Controlled search queries
showTransferAll
boolean
Whether to hide the transfer all button
titles
[string, string]
Lists titles
transferAllIcon
FunctionComponent<{ reversed: boolean; }>
Change icon used for the transfer all control
transferAllMatchingFilter
boolean
Whether to transfer only items matching {@link filter} when clicking the transfer all control
transferIcon
FunctionComponent<{ reversed: boolean; }>
Change icon used for the transfer selected control
value *
TransferListData
Current value

TransferList component Styles API

NameStatic selectorDescription
transferList.mantine-TransferList-transferListOne of list
transferListTitle.mantine-TransferList-transferListTitleTitle
transferListBody.mantine-TransferList-transferListBodyContains header and items list
transferListHeader.mantine-TransferList-transferListHeaderContains search and controls
transferListItems.mantine-TransferList-transferListItemsItems container
transferListItem.mantine-TransferList-transferListItemList item
transferListItemHovered.mantine-TransferList-transferListItemHoveredList item modifier with hovered state
transferListSearch.mantine-TransferList-transferListSearchSearch field
transferListControl.mantine-TransferList-transferListControlControls to move items
separator.mantine-TransferList-separatorDivider wrapper
separatorLabel.mantine-TransferList-separatorLabelSeparator Label