Dropdown
The Dropdown component is a form component that enables a user to select an option or multiple options from a set of options.
Import
- React
- Angular
- Vue.js
// with @dhl-official/react-library:
import { DhlDropdown } from "@dhl-official/react-library"
// with @dhl-official/ui-libraries/react-library:
import { DhlDropdown } from "@dhl-official/ui-libraries/react-library"
If the DUIL has been installed, you can use the web component directly:
<dhl-dropdown></dhl-dropdown>
// with @dhl-official/vue-library:
import { DhlDropdown } from "@dhl-official/vue-library"
// with @dhl-official/ui-libraries/vue-library:
import { DhlDropdown } from "@dhl-official/ui-libraries/vue-library"
Code
- React
- Angular
- Vue.js
<DhlDropdown data={options}></DhlDropdown>
<dhl-dropdown [data]="options" ></dhl-dropdown>
<dhl-dropdown :data.prop="options" ></dhl-dropdown>
The data needs to be passed in following format:
const data = [
{
label: "Option 1",
value: "option-1",
},
{
label: "Option 2",
value: "option-2",
},
{
label: "Option 3",
value: "option-3",
},
{
type: "group",
label: "Group 1",
items: [
{
label: "group-1-option-1",
value: "g1-o1",
},
{
label: "group-1-option-2",
value: "g1-o2",
},
],
},
{
type: "group",
label: "Group 2",
items: [
{
label: "group-2-option-1",
value: "g2-o1",
},
{
label: "group-2-option-2",
value: "g2-o2",
},
],
},
];
Interactive Demo
Single selection
Multiselect and option groups
Disabled multiselect with selected values
Filtering the options
Readme
Usage
Dhl-dropdown
Snippets of code in HTML and JavaScript to show some of the use cases for the component.
The code is not meant to be executed, but to be used as a reference for the usage of the component.
Angular, React and Vue usages are not included in this documentation, but can be easily derived from the html and javascript code.
default usage
<form novalidate>
<dhl-grid-container columns="2">
<dhl-grid-cell span-columns="2">
<dhl-dropdown
label="Dropdown single select"
name="dropdown-1"
>
</dhl-dropdown>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="reset"
variant="text"
>
reset
</dhl-button>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="submit"
variant="primary"
>
submit
</dhl-button>
</dhl-grid-cell>
</dhl-grid-container>
</form>
<script type="module">
const dropdown = document.querySelector("dhl-dropdown");
const form = document.querySelector("form");
dropdown.data = [
{
label: "Option 1",
value: "option-1",
},
{
label: "Option 2",
value: "option-2",
},
{
label: "Option 3",
value: "option-3",
},
{
type: "group",
label: "Group 1",
items: [
{
label: "group-1-option-1",
value: "g1-o1",
},
{
label: "group-1-option-2",
value: "g1-o2",
},
],
},
{
type: "group",
label: "Group 2",
items: [
{
label: "group-2-option-1",
value: "g2-o1",
},
{
label: "group-2-option-2",
value: "g2-o2",
},
],
},
];
form.addEventListener("submit", async (e) => {
e.preventDefault();
console.log(Object.fromEntries(new FormData(form)));
return await e.target.checkValidity();
});
</script>
usage with validation (required) and (browser) default validation message
<form novalidate>
<dhl-grid-container columns="2">
<dhl-grid-cell span-columns="2">
<dhl-dropdown
label="Dropdown single select"
required
name="dropdown-1"
>
</dhl-dropdown>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="reset"
variant="text"
>
reset
</dhl-button>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="submit"
variant="primary"
>
submit
</dhl-button>
</dhl-grid-cell>
</dhl-grid-container>
</form>
<script type="module">
const form = document.querySelector("form");
const dropdown = document.querySelector("dhl-dropdown");
dropdown.data = [
{
label: "Option 1",
value: "option-1",
},
{
label: "Option 2",
value: "option-2",
},
{
label: "Option 3",
value: "option-3",
},
{
type: "group",
label: "Group 1",
items: [
{
label: "group-1-option-1",
value: "g1-o1",
},
{
label: "group-1-option-2",
value: "g1-o2",
},
],
},
{
type: "group",
label: "Group 2",
items: [
{
label: "group-2-option-1",
value: "g2-o1",
},
{
label: "group-2-option-2",
value: "g2-o2",
},
],
},
];
form.addEventListener("submit", async (e) => {
e.preventDefault();
console.log(Object.fromEntries(new FormData(form)));
return await e.target.checkValidity();
});
</script>
usage with validation (required) and custom validation message
<form novalidate>
<dhl-grid-container columns="2">
<dhl-grid-cell span-columns="2">
<dhl-dropdown
label="Dropdown single select"
required
name="dropdown-1"
>
</dhl-dropdown>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="reset"
variant="text"
>
reset
</dhl-button>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="submit"
variant="primary"
>
submit
</dhl-button>
</dhl-grid-cell>
</dhl-grid-container>
</form>
<script type="module">
const form = document.querySelector("form");
const dropdown = document.querySelector("dhl-dropdown");
dropdown.data = [
{
label: "Option 1",
value: "option-1",
},
{
label: "Option 2",
value: "option-2",
},
{
label: "Option 3",
value: "option-3",
},
{
type: "group",
label: "Group 1",
items: [
{
label: "group-1-option-1",
value: "g1-o1",
},
{
label: "group-1-option-2",
value: "g1-o2",
},
],
},
{
type: "group",
label: "Group 2",
items: [
{
label: "group-2-option-1",
value: "g2-o1",
},
{
label: "group-2-option-2",
value: "g2-o2",
},
],
},
];
const validationMessageInvalid = "This field is invalid";
const validationMessageValid = "This field is valid";
form.addEventListener("submit", async (e) => {
e.preventDefault();
console.log(Object.fromEntries(new FormData(form)));
const isValid = await dropdown.checkValidity();
if (isValid) {
dropdown.validation = {
type: "valid",
message: validationMessageValid,
};
} else {
dropdown.validation = {
type: "invalid",
message: validationMessageInvalid,
};
}
return isValid;
});
</script>
usage with custom events
<form novalidate>
<dhl-grid-container columns="2">
<dhl-grid-cell span-columns="2">
<dhl-dropdown
label="Dropdown single select"
required
name="dropdown-1"
>
</dhl-dropdown>
</dhl-grid-cell>
<dhl-grid-cell span-columns="2">
You selected: <dhl-text></dhl-text>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="reset"
variant="text"
>
reset
</dhl-button>
</dhl-grid-cell>
<dhl-grid-cell>
<dhl-button
type="submit"
variant="primary"
>
submit
</dhl-button>
</dhl-grid-cell>
</dhl-grid-container>
</form>
<script type="module">
const form = document.querySelector("form");
const dropdown = document.querySelector("dhl-dropdown");
dropdown.data = [
{
label: "Option 1",
value: "option-1",
},
{
label: "Option 2",
value: "option-2",
},
{
label: "Option 3",
value: "option-3",
},
{
type: "group",
label: "Group 1",
items: [
{
label: "group-1-option-1",
value: "g1-o1",
},
{
label: "group-1-option-2",
value: "g1-o2",
},
],
},
{
type: "group",
label: "Group 2",
items: [
{
label: "group-2-option-1",
value: "g2-o1",
},
{
label: "group-2-option-2",
value: "g2-o2",
},
],
},
];
const validationMessageInvalid = "This field is invalid";
const validationMessageValid = "This field valid";
const text = document.querySelector("dhl-text");
const isElementValid = async () => {
const isValid = await dropdown.checkValidity();
if (isValid) {
dropdown.validation = {
type: "valid",
message: validationMessageValid,
};
} else {
dropdown.validation = {
type: "invalid",
message: validationMessageInvalid,
};
}
return isValid;
};
form.addEventListener("submit", async (e) => {
e.preventDefault();
console.log(Object.fromEntries(new FormData(form)));
return await isElementValid();
});
dropdown.addEventListener("dhlChange", async (e) => {
await isElementValid();
text.innerHTML = e.target.value;
});
dropdown.addEventListener("dhlBlur", async (e) => {
console.log(e);
await isElementValid();
});
dropdown.addEventListener("dhlFocus", async (e) => {
console.log(e);
await isElementValid();
});
dropdown.addEventListener("dhlOpen", async (e) => {
console.log(e);
await isElementValid();
});
dropdown.addEventListener("dhlClose", async (e) => {
console.log(e);
await isElementValid();
});
</script>
Properties
Property | Attribute | Description | Type | Default |
---|---|---|---|---|
changeEvent | -- | [DEPRECATED] Use dhlChange event insteadAn optional onChange callback handler. | (e: InputEvent) => boolean | undefined |
closeEvent | -- | [DEPRECATED] Use dhlClose event insteadAn optional onClose callback handler | () => void | undefined |
data | -- | An optional data prop to pass the list of options to be rendered. | DhlDropDownOptions[] | [] |
dataAriaControls | data-aria-controls | An optional ariaControls prop that is used as a 'relationship attribute' which denotes which elements in a page an interactive element or set of elements has control over and affects. It's commonly used to describe a relationship between a button and the expandable region revealed by that button. | string | undefined |
dataAriaDescribedby | data-aria-describedby | An optional prop defining the list of reference IDs (separated by spaces), recommended when you want to an error message on your field. | string | undefined |
dataAriaLabel | data-aria-label | An optional prop defining the text read by the screen reader to represent the component; use this if you need different text to be read from label. | string | undefined |
dataClassName | data-class-name | An optional class name prop for the component. | string | undefined |
dataId | id | An optional prop. Gives a valid HTML ID attribute value for the component. | string | dhl-dropdown-${getRandomString()} |
dataTestid | data-testid | An optional prop. The test id attached to the component as a data-testid attribute. | string | undefined |
dataTracking | data-tracking | An optional data tracking prop for the component. | string | undefined |
filterChangeEvent | -- | [DEPRECATED] Use dhlFilter event insteadAn optional onFilterChange callback handler; triggered when filter value is changed. When handled; it overrides internal filtering | (filter: string) => void | undefined |
filterPlaceholder | filter-placeholder | An optional props for the placeholder for filter input | string | "Filter options" |
isDisabled | disabled | An optional flag to define if the component is disabled. | boolean | false |
label | label | An optional label for the component. | string | undefined |
multiple | multiple | An optional multiple prop used to allow user to select multiple options; please note when using multiple; the value should be an array | boolean | false |
name | name | A REQUIRED name prop for the component. | string | "dhl-dropdown" |
openEvent | -- | [DEPRECATED] Use dhlOpen event insteadAn optional onOpen callback handler | () => void | undefined |
optionClickEvent | -- | [DEPRECATED] Use dhlClickOption event insteadAn optional onClick callback for an option, value of the clicked item is passed as callback parameter | (value: string) => void | undefined |
optionsContainerClassName | options-container-class-name | An optional classname prop for the Dropdown Options Container | string | undefined |
placeholder | placeholder | An optional prop used to set the placeholder text. | string | undefined |
required | required | An optional prop to flag the component as required within a form context. | boolean | false |
rightIcon | right-icon | An optional prop to pass the icon name to be rendered on the right side of the component. | string | undefined |
showFilter | show-filter | An optional prop flag to control if the input to filter the options should be shown. When this prop is set to true a text input filed is shown emitting the custom events dhlFilter (note: this deprecates filterChangeEvent ). Be aware, by setting this prop to true will only show the form element used to provide a value to filter the list of options. No default filter functionality is provided by the component itself: it needs to be implemented by the developer. | boolean | false |
textDescribe | text-describe | An optional prop to read by screen readers, used for accessibility to pass instructions to user | string | undefined |
validation | -- | An optional object to set-up a custom components validation state. Required Fields: message type | { type: Variants.valid \| Variants.invalid \| Variants.note; message?: string; } | undefined |
value | value | An optional prop holding the array of selected values in case of multiselect, and string value in case of single select. | string \| string[] | undefined |
variant | -- | A REQUIRED object to set-up a custom components variant state. It can be used to set a custom label, a custom placeholder text, enable or disable label animation (via the mandatory type field). | { label?: string; placeholder?: string; type: Variants.animated \| Variants.static; } | null as Variant |
Events
Event | Description | Type |
---|---|---|
dhlBlur | Event emitted when the component loses focus | CustomEvent<{ value: string \| string[]; }> |
dhlChange | Event emitted when the component changes value. | CustomEvent<{ value: string \| string[]; }> |
dhlClickOption | Event emitted when an option is clicked in the DHL dropdown. | CustomEvent<{ value: any; }> |
dhlClose | Event emitted when the component is closed. | CustomEvent<any> |
dhlFilter | Event emitted when the component filter value is changed. | CustomEvent<string> |
dhlFocus | Event emitted when the component receives focus. | CustomEvent<{ value: string \| string[]; }> |
dhlKeyDown | Event emitted when a key is pressed down on the component. | CustomEvent<KeyboardEvent> |
dhlOpen | Event emitted when the component is opened. | CustomEvent<any> |
Methods
checkValidity() => Promise<boolean>
Checks the validity of the component.
Returns
Type: Promise<boolean>
A promise that resolves to true if the component is valid, otherwise false.
getInputElement() => Promise<HTMLInputElement>
Retrieves the input element asynchronously.
Returns
Type: Promise<HTMLInputElement>
A promise that resolves to the input element.
getValidationMessage() => Promise<string>
Retrieves the validation message for the component.
Returns
Type: Promise<string>
A promise that resolves to a string representing the validation message.
reportValidity() => Promise<boolean>
Reports the validity of the component.
Returns
Type: Promise<boolean>
A promise that resolves to a boolean indicating whether the component is valid.
setValidity(validity: ValidityState, validationMessage?: string) => Promise<void>
Sets the validity state of the component.
Parameters
Name | Type | Description |
---|---|---|
validity | ValidityState | - The validity state to set. |
validationMessage | string | - An optional validation message to set. |
Returns
Type: Promise<void>
A Promise that resolves when the validity state is set.
willValidate() => Promise<boolean>
Returns a promise that resolves to true if the element will successfully validate, or false otherwise.
Returns
Type: Promise<boolean>
A promise that resolves to a boolean value indicating whether the element will validate.
Dependencies
Depends on
- dhl-chip-container
- dhl-chip
- dhl-label
- dhl-placeholder
- dhl-icon-wrapper
- dhl-icon
- dhl-text-sr-only
- dhl-validation-feedback
Graph
Built by DHL User Interface Library Team!
Migrating from DUIL 1.0
- Options are now passed to
data
prop, passing options as children/childNodes in no longer supported. - Rename
disabled
toisDisabled
- Rename
onChange
tochangeEvent
- Rename
onClick
toclickEvent
- Rename
onClose
tocloseEvent
- Rename
onFilterChange
tofilterChangeEvent
- Rename
onOpen
toopenEvent
- Rename
ariaDescribe
totextDescribe
- Now a required prop:
dataId
- Now a required prop:
name
rightIcon
now only supports string, a path to the icon or data url for the icon- Consumer to handle the filtration of the options on
filterChangeEvent
- Remove
isBlock