> For the complete documentation index, see [llms.txt](https://docs.avonnicomponents.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.avonnicomponents.com/lwc-components/core-components/dual-listbox.md).

# Dual Listbox

`avonni-dual-listbox`

Lets users move options between a source list and a selected list to build an ordered selection.

## Overview

**Dual Listbox** is a Lightning Web Component that lets users move options between a source list and a selected list, with optional search, reordering, and drag-and-drop.

Use it in your own Lightning Web Components whenever users build a curated subset from a larger set of options. You supply the options, control the labels and button styling, set min/max constraints, and read the selection from the `change` event.

### Use Cases

* **Permission assignment:** Move permissions from Available to Granted.
* **Field selection:** Let users choose which columns or fields to display.
* **Team membership:** Build a team by moving users into a selected list.
* **Tag curation:** Pick and order a subset of tags or categories.
* **Report configuration:** Select and prioritize metrics for a custom report.

***

## Use Case Examples

### Example 1: Permission assignment with a locked option

**Scenario:** Let an admin grant role permissions by moving them from Available to Granted, with "Read" pre-selected and locked.

```html
<!-- rolePermissions.html -->
<template>
    <avonni-dual-listbox
        label="Role permissions"
        source-label="Available"
        selected-label="Granted"
        add-button-label="Grant permission"
        remove-button-label="Revoke permission"
        options={options}
        value={value}
        required-options={requiredOptions}
        allow-search
        search-input-placeholder="Filter permissions…"
        min="1"
        required
        message-when-value-missing="Select at least one permission."
        variant="label-stacked"
        onchange={handleChange}
    ></avonni-dual-listbox>
</template>
```

```js
// rolePermissions.js
import { LightningElement } from 'lwc';

export default class RolePermissions extends LightningElement {
    options = [
        { label: 'Read', value: 'read', description: 'View records' },
        { label: 'Create', value: 'create', description: 'Add records' },
        { label: 'Edit', value: 'edit', description: 'Modify records' },
        { label: 'Delete', value: 'delete', description: 'Remove records' }
    ];
    value = ['read'];
    requiredOptions = ['read'];

    handleChange(event) {
        const selected = event.detail.value; // array of values
    }
}
```

**Result:** Two lists with search; "Read" is selected and cannot be removed, and each move fires `change` with the current selection.

### Example 2: Draggable field picker

**Scenario:** Let users choose and reorder which fields appear in a custom table.

```html
<!-- fieldPicker.html -->
<template>
    <avonni-dual-listbox
        label="Visible fields"
        source-label="Available fields"
        selected-label="Shown fields"
        options={fieldOptions}
        draggable
        max="6"
        size="large"
        onchange={handleChange}
    ></avonni-dual-listbox>
</template>
```

```js
// fieldPicker.js
import { LightningElement } from 'lwc';

export default class FieldPicker extends LightningElement {
    fieldOptions = [
        { label: 'Name', value: 'name' },
        { label: 'Stage', value: 'stage' },
        { label: 'Amount', value: 'amount' },
        { label: 'Close Date', value: 'closeDate' }
    ];

    handleChange(event) {
        const fields = event.detail.value; // selected, in order
    }
}
```

**Result:** Users drag fields into the selected list (up to six) and reorder them; the ordered selection is returned on `change`.

***

## Specifications

### Attributes

| Name                                        | Description                                                                                                                                                                                                                                                             | Type                       | Default                                                        | Required |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -------------------------------------------------------------- | -------- |
| `add-button-icon-name`                      | Name of the add button icon, in the format 'utility:right'.                                                                                                                                                                                                             | String                     | `"utility:right"`                                              |          |
| `add-button-label`                          | Label of the add button.                                                                                                                                                                                                                                                | String                     | —                                                              |          |
| `allow-search`                              | If present, a search box is added to the first listbox.                                                                                                                                                                                                                 | Boolean                    | `false`                                                        |          |
| `button-size`                               | For the bare variant, valid values include x-small, small, medium, and large. For non-bare variants, valid values include xx-small, x-small, small, and medium.                                                                                                         | String                     | `"medium"`                                                     |          |
| `button-variant`                            | Use this variant for all button icons (add, up, down and remove). Valid values include bare, container, brand, border, border-filled, bare-inverse and border-inverse.                                                                                                  | String                     | —                                                              |          |
| `disable-reordering`                        | If present, the Up and Down buttons used for reordering are hidden.                                                                                                                                                                                                     | Boolean                    | `false`                                                        |          |
| `disabled`                                  | If present, the listbox is disabled and users cannot interact with it.                                                                                                                                                                                                  | Boolean                    | `false`                                                        |          |
| `down-button-icon-name`                     | Name of the down button icon to be used in the format ‘utility:down’.                                                                                                                                                                                                   | String                     | `"utility:down"`                                               |          |
| `down-button-label`                         | Label of the down button                                                                                                                                                                                                                                                | String                     | —                                                              |          |
| `draggable`                                 | If present, the options are draggable.                                                                                                                                                                                                                                  | Boolean                    | `false`                                                        |          |
| `field-level-help`                          | Help text detailing the purpose and function of the dual listbox.                                                                                                                                                                                                       | String                     | —                                                              |          |
| `hide-bottom-divider`                       | If present, hides the bottom divider.                                                                                                                                                                                                                                   | Boolean                    | `false`                                                        |          |
| `is-loading`                                | If present, the source options listbox is in a loading state and shows a spinner.                                                                                                                                                                                       | Boolean                    | `false`                                                        |          |
| `keyboard-interaction-assistive-text`       | The assistive text for the keyboard interaction.                                                                                                                                                                                                                        | String                     | \`"Press Ctrl (Cmd on Mac) + Left Arrow or Ctrl (Cmd on Mac) + |          |
| Right Arrow to move items between lists."\` |                                                                                                                                                                                                                                                                         |                            |                                                                |          |
| `label`                                     | Label of the dual listbox.                                                                                                                                                                                                                                              | String                     | —                                                              |          |
| `loading-state-alternative-text`            | Message displayed while the listbox is in the loading state.                                                                                                                                                                                                            | String                     | `"Loading..."`                                                 |          |
| `max`                                       | Maximum number of options allowed in the selected options listbox.                                                                                                                                                                                                      | Number                     | `Infinity`                                                     |          |
| `max-visible-options`                       | Number of options displayed in the listboxes before vertical scrollbars are displayed. Determines the height of the listbox.                                                                                                                                            | Number                     | `5`                                                            |          |
| `message-when-range-overflow`               | Error message to be displayed when a range overflow is detected.                                                                                                                                                                                                        | String                     | —                                                              |          |
| `message-when-range-underflow`              | Error message to be displayed when a range underflow is detected.                                                                                                                                                                                                       | String                     | —                                                              |          |
| `message-when-value-missing`                | Error message to be displayed when the value is missing and input is required.                                                                                                                                                                                          | String                     | —                                                              |          |
| `min`                                       | Minimum number of options required in the selected options listbox.                                                                                                                                                                                                     | Number                     | `0`                                                            |          |
| `name`                                      | Specifies the name of an input element.                                                                                                                                                                                                                                 | String                     | —                                                              |          |
| `options`                                   | Array of option objects that are available for selection.                                                                                                                                                                                                               | AvonniDualListboxOption\[] | —                                                              |          |
| `remove-button-icon-name`                   | Name of the remove button icon in the format ‘utility:left’.                                                                                                                                                                                                            | String                     | `"utility:left"`                                               |          |
| `remove-button-label`                       | Label of the remove button.                                                                                                                                                                                                                                             | String                     | —                                                              |          |
| `required`                                  | If present, the user must add an item to the selected listbox before submitting the form.                                                                                                                                                                               | Boolean                    | `false`                                                        |          |
| `required-alternative-text`                 | The assistive text when the required attribute is set to true.                                                                                                                                                                                                          | String                     | `"Required"`                                                   |          |
| `required-options`                          | A list of required options that cannot be removed from selected options listbox. This list is populated with values from the options attribute.                                                                                                                         | string\[]                  | —                                                              |          |
| `search-input-placeholder`                  | The placeholder text for the search input.                                                                                                                                                                                                                              | String                     | `"Search…"`                                                    |          |
| `selected-label`                            | Label of the Selected options list.                                                                                                                                                                                                                                     | String                     | —                                                              |          |
| `selected-placeholder`                      | Text displayed when no options are selected.                                                                                                                                                                                                                            | String                     | —                                                              |          |
| `size`                                      | Width of the source options listbox and the selected options listbox. Valid values include small, medium and large.                                                                                                                                                     | String                     | `"responsive"`                                                 |          |
| `source-label`                              | Label of the Source options list.                                                                                                                                                                                                                                       | String                     | —                                                              |          |
| `up-button-icon-name`                       | Name of the up button icon to be used in the format ‘utility:up’.                                                                                                                                                                                                       | String                     | `"utility:up"`                                                 |          |
| `up-button-label`                           | Label of the up button.                                                                                                                                                                                                                                                 | String                     | —                                                              |          |
| `value`                                     | A list of default options that are included in the selected options listbox. This list is populated with values from the options attribute.                                                                                                                             | string\[]                  | —                                                              |          |
| `variant`                                   | The variant changes the appearance of the dual listbox. Valid variants include standard, label-hidden and label-stacked. Use label-hidden to hide the label but make it available to assistive technology. Use label-stacked to place the label above the dual listbox. | String                     | `"standard"`                                                   |          |

### Methods

| Name                | Description                                                                                                                                           | Argument Name | Argument Type | Argument Description                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------- | ----------------------------------------------------------------------------------------------- |
| `checkValidity`     | Checks if the input is valid.                                                                                                                         |               |               |                                                                                                 |
| `focus`             | Sets focus on the first option from either list. If the source list doesn't contain any options, the first option on the selected list is focused on. |               |               |                                                                                                 |
| `getErrorMessage`   | Retrieve the current error message. If it is null than the input is valid.                                                                            |               |               |                                                                                                 |
| `reportValidity`    | Displays the error messages. If the input is valid, `reportValidity()` clears displayed error messages.                                               |               |               |                                                                                                 |
| `setCustomValidity` | Sets a custom error message to be displayed when a form is submitted.                                                                                 | `message`     | String        | The string that describes the error. If message is an empty string, the error message is reset. |

### Custom Events

#### `change`

The event fired when one or several options are moved from one box to the other.

The `change` event returns the following parameters.

| Parameter | Type      | Description                      |
| --------- | --------- | -------------------------------- |
| `value`   | string\[] | Array of selected option values. |

The event properties are as follows.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | true  | This event bubbles up through the DOM.                                                                    |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | true  | This event propagates outside of the component in which it was dispatched.                                |

#### `loadmore`

The event fired when the users scroll to the bottom of the source listbox to load more options.

The `loadmore` event doesn't return any parameters.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | false | This event does not bubble.                                                                               |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | false | This event does not propagate outside of the component in which it was dispatched.                        |

#### `optionclick`

The event fired when an option is clicked.

The `optionclick` event returns the following parameters.

| Parameter | Type   | Description                  |
| --------- | ------ | ---------------------------- |
| `value`   | string | Value of the clicked option. |

The event properties are as follows.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | true  | This event bubbles up through the DOM.                                                                    |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | false | This event does not propagate outside of the component in which it was dispatched.                        |

#### `search`

The event fired when the user types in the search input.

The `search` event returns the following parameters.

| Parameter | Type   | Description                |
| --------- | ------ | -------------------------- |
| `value`   | string | Value of the search input. |

The event properties are as follows.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | false | This event does not bubble.                                                                               |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | false | This event does not propagate outside of the component in which it was dispatched.                        |

### Styling Hooks

| CSS Variable                                             | Type    | Default    |
| -------------------------------------------------------- | ------- | ---------- |
| `--avonni-dual-listbox-boxes-color-background`           | color   | `#ffffff`  |
| `--avonni-dual-listbox-boxes-color-border`               | radius  | —          |
| `--avonni-dual-listbox-boxes-radius-border`              | color   | `#747474`  |
| `--avonni-dual-listbox-boxes-sizing-border`              | sizing  | `1px`      |
| `--avonni-dual-listbox-boxes-styling-border`             | styling | `solid`    |
| `--avonni-dual-listbox-boxes-label-text-color`           | color   | `#3e3e3c`  |
| `--avonni-dual-listbox-boxes-label-font-size`            | font    | `0.75rem`  |
| `--avonni-dual-listbox-boxes-label-font-style`           | font    | `normal`   |
| `--avonni-dual-listbox-boxes-label-font-weight`          | font    | `400`      |
| `--avonni-dual-listbox-group-color-background`           | color   | —          |
| `--avonni-dual-listbox-group-label-text-color`           | color   | `#181818`  |
| `--avonni-dual-listbox-group-label-font-size`            | font    | `0.875rem` |
| `--avonni-dual-listbox-group-label-font-style`           | font    | `normal`   |
| `--avonni-dual-listbox-group-label-font-weight`          | font    | `700`      |
| `--avonni-dual-listbox-header-text-color`                | color   | `#3e3e3c`  |
| `--avonni-dual-listbox-header-font-size`                 | font    | `0.75rem`  |
| `--avonni-dual-listbox-header-font-style`                | font    | `normal`   |
| `--avonni-dual-listbox-header-font-weight`               | font    | `700`      |
| `--avonni-dual-listbox-option-color-background`          | color   | `#ffffff`  |
| `--avonni-dual-listbox-option-text-color`                | color   | `#181818`  |
| `--avonni-dual-listbox-option-color-background-hover`    | color   | `#f3f2f2`  |
| `--avonni-dual-listbox-option-text-color-hover`          | color   | `#181818`  |
| `--avonni-dual-listbox-option-color-background-selected` | color   | `#edeceb`  |
| `--avonni-dual-listbox-option-text-color-selected`       | color   | `#181818`  |
| `--avonni-dual-listbox-option-color-border`              | color   | `#747474`  |
| `--avonni-dual-listbox-option-sizing-border`             | sizing  | `1px`      |
| `--avonni-dual-listbox-option-styling-border`            | styling | `solid`    |

## Key Considerations

* **Constraints:** `min` and `max` enforce how many options must/can be selected; pair with `message-when-range-underflow`/`message-when-range-overflow`.
* **Locked options:** Values in `required-options` stay in the selected list and cannot be removed.
* **Reordering:** Order is preserved in the `change` value; hide controls with `disable-reordering` if order doesn't matter.
* **Search:** `allow-search` only filters the source list and fires the `search` event for server-side filtering if needed.
* **Loading:** Use `is-loading` with `loadmore` to lazy-load large option sets.
* **Best Practice:** Provide clear `source-label` and `selected-label` text, and use `required-options` to lock items that should never be removed.

***

## Troubleshooting Common Issues

* **Options not appearing:** Verify `options` is a non-empty array of `{ label, value }` objects with unique values.
* **Selection not updating:** Confirm the `onchange` handler reads `event.detail.value` (an array of values).
* **Cannot remove an option:** Check whether its value is listed in `required-options`.
* **If issues persist:** Contact our support team at <support@avonni.app> for assistance.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.avonnicomponents.com/lwc-components/core-components/dual-listbox.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
