Introducing PrimeReact v11-alpha 🎉Discover Now

usePickList

A headless hook that manages two lists with transfer, reorder, and optional drag-and-drop between them.

New York
Rome
London
Istanbul
Paris
basic-demo

Usage#

import { usePickList } from '@primereact/headless/picklist';
 
const pickList = usePickList({
    source,
    target,
    selection,
    draggable: true,
    onChange: (e) => {
        setSource(e.source);
        setTarget(e.target);
    }
});
 
return (
    <div {...pickList.rootProps}>
        <div {...pickList.sourceListProps}>
            {pickList.state.source.map((item, i) => (
                <div key={i} {...pickList.getOptionProps(item, i, 'source')}>
                    {item.name}
                </div>
            ))}
        </div>
        <div>
            <button {...pickList.moveToTargetProps}>→</button>
            <button {...pickList.moveAllToTargetProps}>⇉</button>
            <button {...pickList.moveToSourceProps}>←</button>
            <button {...pickList.moveAllToSourceProps}>⇇</button>
        </div>
        <div {...pickList.targetListProps}>
            {pickList.state.target.map((item, i) => (
                <div key={i} {...pickList.getOptionProps(item, i, 'target')}>
                    {item.name}
                </div>
            ))}
        </div>
    </div>
);

usePickList manages two lists with transfer and reorder operations. Pair it with Listbox for built-in selection and keyboard navigation.

Features#

  • Returns spread-ready prop objects for both source and target lists
  • Transfer operations: moveToTarget, moveToSource, moveAllToTarget, moveAllToSource
  • Per-side reorder controls: sourcePrevProps, sourceNextProps, sourceFirstProps, sourceLastProps (same for target)
  • Built-in drag-and-drop with draggable prop (within and across lists)
  • Clone or empty placeholder modes during drag
  • Per-option props via getOptionProps with side awareness

Behavior#

Basic Transfer#

Pass source, target, and onChange to manage two lists. Use transfer methods to move selected items between lists.

const [source, setSource] = React.useState(['A', 'B', 'C']);
const [target, setTarget] = React.useState([]);
const [selection, setSelection] = React.useState([]);
 
const pickList = usePickList({
    source,
    target,
    selection,
    onChange: (e) => {
        setSource(e.source);
        setTarget(e.target);
    },
    onSelectionChange: (e) => setSelection(e.value)
});

Drag and Drop#

Set draggable to enable drag-and-drop reordering within lists and transferring across lists.

const pickList = usePickList({
    source,
    target,
    draggable: true,
    onChange: (e) => {
        setSource(e.source);
        setTarget(e.target);
    }
});

Placeholder#

Set placeholder to "clone" to show a visual copy of the dragged item in its original position. Default is "empty" which preserves height only.

const pickList = usePickList({
    source,
    target,
    draggable: true,
    placeholder: 'clone',
    onChange: (e) => {
        setSource(e.source);
        setTarget(e.target);
    }
});

Style the placeholder with [data-sortable-placeholder] attribute.

Disabled#

Set disabled to prevent all interactions.

const pickList = usePickList({ source, target, disabled: true });

Custom Styling with Data Attributes#

Every prop object includes data-scope and data-part attributes for CSS targeting.

[data-scope='picklist'][data-part='root'] {
    display: flex;
    gap: 1rem;
}
 
[data-scope='picklist'][data-part='source-list'],
[data-scope='picklist'][data-part='target-list'] {
    min-height: 200px;
}
 
[data-sortable-placeholder] {
    opacity: 0.4;
}

Option Attributes#

AttributeValue
data-selectedPresent when the item is selected
data-sortable-itemPresent on every sortable item
data-sortable-containerContainer id for the sortable group
data-draggingPresent on the item being dragged
data-droppingPresent briefly during the drop animation
data-sortable-placeholderPresent on the placeholder clone left behind during drag

API#

usePickList#