Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

react-dual-listbox

jakezatecky60.2kMIT6.0.3TypeScript support: definitely-typed

A feature-rich dual listbox for React.

react, dual-listbox, duallistbox, listbox, list box, list builder, listswap

readme

react-dual-listbox

npm Build Status GitHub license

A feature-rich dual listbox for React.

Demo

Usage

Installation

Install the library using your favorite dependency manager:

yarn add react-dual-listbox

Using npm:

npm install react-dual-listbox --save

Note – This library makes use of Font Awesome styles and expects them to be loaded in the browser.

Include CSS

The library's styles are available through one of the following files:

  • node_modules/react-dual-listbox/lib/react-dual-listbox.css
  • node_modules/react-dual-listbox/src/scss/react-dual-listbox.scss

Either include one of these files in your stylesheets or utilize a CSS loader:

import 'react-dual-listbox/lib/react-dual-listbox.css';

Render Component

The DualListBox is a controlled component. You must update the selected property in conjunction with the onChange handler if you want the selected values to change.

Here is a minimal rendering of the component:

import React, { useState } from 'react';
import DualListBox from 'react-dual-listbox';
import 'react-dual-listbox/lib/react-dual-listbox.css';

const options = [
    { value: 'one', label: 'Option One' },
    { value: 'two', label: 'Option Two' },
];

function Widget() {
    const [selected, setSelected] = useState([]);

    return (
        <DualListBox
            options={options}
            selected={selected}
            onChange={(newValue) => setSelected(newValue)}
        />
    );
}

Optgroups

This component also supports traditional <optgroup> elements through the use of the options key:

const options = [
    {
        label: 'Earth',
        options: [
            { value: 'luna', label: 'Moon' },
        ],
    },
    {
        label: 'Mars',
        options: [
            { value: 'phobos', label: 'Phobos' },
            { value: 'deimos', label: 'Deimos' },
        ],
    },
    {
        label: 'Jupiter',
        options: [
            { value: 'io', label: 'Io' },
            { value: 'europa', label: 'Europa' },
            { value: 'ganymede', label: 'Ganymede' },
            { value: 'callisto', label: 'Callisto' },
        ],
    },
];

return <DualListBox options={options} />;

Disabling the Component or Options

Pass in the disabled property to disable the entire component. Alternatively, individual options may be disabled on a per-item basis:

const options = [
    {
        label: 'Mars',
        disabled: true,
        options: [
            { value: 'phobos', label: 'Phobos' },
            { value: 'deimos', label: 'Deimos' },
        ],
    },
    {
        label: 'Jupiter',
        options: [
            { value: 'io', label: 'Io' },
            { value: 'europa', label: 'Europa', disabled: true },
            { value: 'ganymede', label: 'Ganymede' },
            { value: 'callisto', label: 'Callisto' },
        ],
    },
];

return <DualListBox options={options} />;

Filtering

You can enable filtering of available and selected options by merely passing in the canFilter property:

<DualListBox canFilter options={options} />

Optionally, you can also override the default filtering function:

<DualListBox
    canFilter
    filterCallback={(option, filterInput, { getOptionLabel }) => {
        if (filterInput === '') {
            return true;
        }

        return (new RegExp(filterInput, 'i')).test(getOptionLabel(option));
    }}
    options={options}
/>

In addition, you may control the filter text state, rather than leaving it up to the component:

<DualListBox
    canFilter
    filter={{
        available: 'europa',
        selected: '',
    }}
    options={options}
    onFilterChange={(filter) => {
        console.log(filter);
    }}
/>

Action/Button Alignment

By default, the component arranges the action buttons to the center. Another option is to align these actions to be above their respective lists:

<DualListBox alignActions="top" options={options} />

Preserve Select Ordering

By default, react-dual-listbox will order any selected items according to the order of the options property. There may be times in which you wish to preserve the selection order instead. In this case, you can add the preserveSelectOrder property.

Note – Enabling this option hides <optgroup> associations in the selected listbox.

<DualListBox options={options} preserveSelectOrder />

To allow users to re-arrange their selections after moving items to the right, you may also pass in the showOrderButtons property.

Restrict Available Options

Sometimes, it may be desirable to restrict what options are available for selection. For example, you may have a control above the dual listbox that allows a user to search for a planet in the solar system. After selecting a planet, you restrict the available options to the moons of that planet. Use the available property in that case.

// Let's restrict ourselves to the Jovian moons
const available = ['io', 'europa', 'ganymede', 'callisto'];

return <DualListBox options={options} available={available} />;

Changing the Default Icons

By default, react-dual-listbox uses Font Awesome for the various icons that appear in the component. To change the defaults, simply pass in the icons property to override the defaults:

<DualListBox
    ...
    icons={{
        moveLeft: <span className="fa fa-chevron-left" />,
        moveAllLeft: [
            <span key={0} className="fa fa-chevron-left" />,
            <span key={1} className="fa fa-chevron-left" />,
        ],
        moveRight: <span className="fa fa-chevron-right" />,
        moveAllRight: [
            <span key={0} className="fa fa-chevron-right" />,
            <span key={1} className="fa fa-chevron-right" />,
        ],
        moveDown: <span className="fa fa-chevron-down" />,
        moveUp: <span className="fa fa-chevron-up" />,
        moveTop: <span className="fa fa-double-angle-up" />,
        moveBottom: <span className="fa fa-double-angle-down" />,
    }}
/>

Alternatively, set the iconsClass property and define the icons in CSS.

Additional onChange Details

At times, it may be useful to know which options the user highlighted before triggering a change or which control group was responsible for the change. In these cases, you can pass additional parameters to the onChange function:

const onChange = (selected, selection, controlKey) => {
    console.log('The user highlighted these options', selection);
    console.log('The following control triggered these changes', controlKey);
};

All Properties

Property Type Description Default
options array Required. Specifies the list of options that may exist on either side of the dual list box.
onChange function Required. The handler called when the selected options change: function(selected, selection, controlKey) {}.
alignActions string A value specifying whether to align the action buttons to the 'top' or 'middle'. middle
allowDuplicates bool If true, duplicate options will be allowed in the selected list box. false
available array A subset of the options array to optionally filter the available list box. undefined
availableRef function A React function ref to the "available" list box. null
canFilter bool If true, search boxes will appear above both list boxes, allowing the user to filter the results. false
className string An optional className to apply to the root node. null
disabled bool If true, both "available" and "selected" list boxes will be disabled. false
filter object A key-value map of { available: [value], selected: [value] } to control the filter values (defaults to uncontrolled). null
filterCallback function The filter function to run on a given option and input string: function(option, filterInput) {}. See Filtering. () => { ... }
getOptionLabel function The function to resolve the label from an option. Defaults to option => option.label. () => { ... }
getOptionValue function The function to resolve the value from an option. Defaults to option => option.value. () => { ... }
htmlDir string The directionality of the component's elements. Set to 'rtl' if using a right-to-left language. 'ltr'
icons object A key-value pairing of action icons and their React nodes. See Changing the Default Icons for further info. { ... }
iconsClass string A value specifying which overarching icon class to use. Built-in support for fa5, fa6, and native icons. 'fa6'
id string An HTML ID prefix for the various sub elements. null
lang object A key-value pairing of localized text. See src/js/lang/default.js for a list of keys. { ... }
moveKeys array A list of keyboard keys that will trigger a toggle of the highlighted options. [' ', 'Enter']
name string A value for the name attribute on the hidden <input /> element. This is potentially useful for form submissions. null
onFilterChange function A handler called when a filter input changes. Paired with filter when wanting to control the filter values. null
preserveSelectOrder bool If true, the order in which the available options are selected are preserved when the items are moved to the right. false
required bool If true, this component will require selected to be non-empty to pass a form validation false
selected array A list of the selected options appearing in the rightmost list box. []
selectedRef function A React function ref to the "selected" list box. null
showHeaderLabels bool If true, labels above both the available and selected list boxes will appear. These labels derive from lang. false
showNoOptionsText bool If true, text will appear in place of the available/selected list boxes when no options are present. false
showOrderButtons bool If true, a set of up/down buttons will appear near the selected list box to allow the user to re-arrange the items. false
simpleValue bool If true, the selected value passed in onChange is an array of string values. Otherwise, it is an array of options. true

Option Properties

Property Type Description
label string Required. The text label for the given option. Use getOptionLabel to set a different key.
value mixed Required. The text or numeric value for the given option. Use getOptionValue to set a different key.
disabled bool If true, disables the option from selection.
title string Adds the HTML title attribute to the option.

changelog

Changelog

6.0.3 (2023-02-24)

Fixed

  • Fix issue with move all buttons ignoring filters (#268)

6.0.2 (2023-02-06)

Fixed

  • Add SSR-safe check for the Element type

6.0.1 (2023-12-13)

Fixed

  • Fix type validation for selected prop when using integers (#258)

6.0.0 (2023-12-06)

This new version includes a variety of breaking changes. Please review them before upgrading.

Added

  • Add getOptionLabel and getOptionValue properties to allow for custom keys beyond label and value (#208)
  • Add LazyFilterExample.jsx to demonstrate lazy loading for the options property by user search

Changed

  • Breaking: onChange property: the second argument now returns objects with label, index, and value, instead of just values (#230)
  • Breaking: icons property:
    • Will now merge any missing keys with the default icons
    • Rename moveLeft, moveAllLeft, moveRight, and moveAllRight to moveToAvailable, moveAllToAvailable, moveToSelected, and moveAllToSelected
  • Breaking: iconsClass property: now defaults to 'fa6'
  • Breaking: id property: no longer defaults to a random UUID when null and no longer used for some child components
  • Breaking: lang property:
    • Will now merge any missing keys with the default language
    • Rename moveLeft, moveAllLeft, moveRight, and moveAllRight to moveToAvailable, moveAllToAvailable, moveToSelected, and moveAllToSelected
    • Split filterPlaceholder into availableFilterPlaceholder and selectedFilterPlaceholder
  • Breaking: options property: no longer has PropTypes validation for label and value (#208)
  • Breaking: Rename *-right and *-left classes to *-to-selected and *-to-available
  • Improve accessibility of required error
  • Change filter input to type="search" (#247)

Removed

  • Breaking: Drop support for Less.js styles
  • Breaking: Drop support for React before v16.8
  • Breaking: Remove rdl-sr-only class
  • Drop usage of deprecated defaultProps (#248)

Fixed

  • Fix positioning of action buttons relative to the list boxes
  • Prevent situation where double-clicking an optgroup moved any selected options under it

icons and lang Migration Guide

The keys moveLeft, moveAllLeft, moveRight, and moveAllRight are now moveToAvailable, moveAllToAvailable, moveToSelected, and moveAllToSelected in all instances. Refer to the table below to rename any affected icons or lang keys:

Old Key Name New Key Name
moveLeft moveToAvailable
moveAllLeft moveAllToAvailable
moveRight moveToSelected
moveAllRight moveAllToSelected

Other

v5.0.2 (2023-02-08)

Bug Fixes

  • [#217]: Fix issue where re-arrangement of an element would cause it to lose its selection status
  • Make Chrome and Firefox have the same styles when an input is active

v5.0.1 (2023-01-26)

Bug Fixes

  • Fix issues with loading stylesheets due to exports conflicts
  • Fix default imports (you can still import ./src/index.js provided you have a Babel loader)

v5.0.0 (2023-01-26)

Breaking Changes

  • No longer minify bundled JavaScript (up to users to do so)

Bug Fixes

  • [#215]: Fix issue where the control height would not scale with parent

v4.0.0 (2022-12-08)

Breaking Changes

New Features

  • [#52]: Add required property

Bug Fixes

  • Fix small border radius issues when alignActions="top"
  • Force Firefox to make input borders transparent when focus received (like Chrome)

v3.0.1 (2022-10-28)

Bug Fixes

  • [#139]: Fix issue where selections would persist after moving options

Other

  • Increase performance when simpleValue={false}

v3.0.0 (2022-10-24)

New Features

  • [#76]: (breaking) Add htmlDir property to support RTL languages (defaults to LTR)
  • [#146]: Add styles for small viewport devices (<576px)
  • [#203]: Add controlKey to the onChange function such that developers may identify which control triggered the change
  • [#209]: (breaking) Add iconsClass, make icons more semantic, and support Unicode icons

Bug Fixes

  • [#142]: Fix issue where preserveSelectOrder could result in the improper removal of selected values when filtering
  • [#148]: Fix issue where the "Move All" actions ignored individual disabled status

v2.3.0 (2022-09-06)

Other

  • [#196]: Add React 18 to the peer dependency (Note: React 18 is not part of the automatic testing, but should work)

v2.2.0 (2021-06-08)

Other

  • [#136]: Add support for React 17

v2.1.2 (2021-05-20)

Other

  • [#147]: Update lodash to resolve security vulnerability

v2.1.1 (2021-04-04)

Bug Fixes

  • [#113]: Fix issue with simpleValue={false} not playing nicely with preserveSelectOrder
  • [#116]: Fix issue where the canFilter would ignore optgroup labels

v2.1.0 (2021-04-03)

New Features

  • [#80]: Add disabled support for elements in the options property
  • [#87]: Add title support for elements in the options property
  • [#90]: Add selection argument to the onChange handler to track highlighted values
  • [#104]: Add className property to allow specification of a custom class on the root node
  • [#133]: Add moveTop and moveBottom buttons to showOrderButtons property

Bug Fixes

  • [#103]: Fix issue where allowDuplicates would fail to add extra items when simpleValue={false}
  • [#110]: Fix issue where allowDuplicates would cause the available property to be ignored
  • [#124]: Fix issue where the selection area would return to the top of the list after moving items with some properties

v2.0.0 (2019-05-14)

New Features

  • [#22]: Add showHeaderLabels property to make labels appear above the available and selected list boxes

Bug Fixes

  • [#73]: Fix issue where a numeric value types would be passed as strings in the onChange callback

Other

  • [#61]: (breaking) Merge availableLabel and selectedLabel into the lang property and rename them to availableHeader and selectedHeader
  • [#62]: Add test to ensure that Less and Sass source files generate the same compiled CSS
  • [#75]: Reduce filtering computational complexity to increase performance when using a large number of options

v1.4.2 (2018-12-21)

Bug Fixes

  • [#57]: Fix issue where clicking on the ordering buttons would result in errors if the selected list was empty
  • [#58]: Fix issue where not all items marked in the selected list would be removed when the "Move left" button was clicked

v1.4.1 (2018-12-17)

Bug Fixes

  • [#56]: Fix various PropTypes errors

v1.4.0 (2018-12-16)

New Features

  • [#24]: Add showOrderButtons property to allow users to move the selected options up or down in the list
  • [#43]: Add showNoOptionsText property to make text appear in place of available/selected list boxes when no options are present
  • [#48]: Add allowDuplicates property to allow more than one copy of an available value to be selected
  • [#50]: Add id property for control over the HTML ID assigned to the component instance
  • [#54]: Add lang property for localization
  • [#55]: Add icons property for icon customization

Bug Fixes

  • [#53]: Fix an issue where previously selected options would be duplicated when using the "Move all right" button

v1.3.2 (2018-02-06)

Bug Fixes

  • [#35]: Fix issue where simpleValue would not reveal selected optgroup options
  • [#36]: Fix default filtering when dealing with regular expression symbols

v1.3.1 (2018-01-06)

Bug Fixes

  • [#33]: Fix sizing issues in IE 11 when the action buttons are aligned to the top

v1.3.0 (2017-09-10)

New Features

  • [#27]: Add simpleValue property to disable the default behavior of returning an array of values rather than an array of option objects
  • [#28]: Add availableLabel and selectedLabel to change the hidden control label texts
  • [#30]: Add moveKeyCodes property to set the key codes that trigger a move for the select options

v1.2.0 (2017-08-12)

New Features

  • [#26]: Add support for filter and onFilterChange properties

v1.1.0 (2017-05-11)

New Features

  • [#21]: Add support for disabled property

v1.0.1 (2017-04-11)

Bug Fixes

  • [#19]: Fix issue with additional border appearing between two action buttons

v1.0.0 (2017-04-10)

New Features

  • [#6]: Search and filtering has been added with the props canFilter, filterPlaceholder, and filterCallback
  • [#14]: Allow movement buttons to be arranged above lists using the alignActions prop

Bug Fixes

  • [#10]: Fix an issue where selections would shift down after moving items to the opposite list

Other

  • [#18]: Remove requirement on Array.from polyfill

v0.6.0 (2017-03-25)

New Features

  • [#15]: Components are now more accessible to assistive technologies

Other

  • [#16]: (breaking) Rename .rdl-btn to .rdl-move
  • [#17]: (breaking) Use color more consistently and make font-family inherit

v0.5.1 (2017-01-12)

New Features

  • [#2]: Add support for availableRef and selectedRef

v0.5.0 (2017-01-10)

New Features

  • [#12]: Bootstrap is no longer required for the component to display properly
  • [#13]: Component styles are a bit more flexible by default

v0.4.0 (2016-12-31)

Bug Fixes

  • [#3]: Fix an issue where events were not firing in IE 11
  • [#9]: Fix an issue where flexbox styling in IE 11 was not being applied correctly

New Features

  • [#11]: Add ability to toggle selected options on pressing <kbd>Enter</kbd>

v0.3.4 (2016-12-28)

Bug Fixes

  • [#7]: Fix an issue where clicking on the icon of a button would not trigger events properly in some browsers