Select
The Select component is a form component that enables a user to select a single option from a dropdown menu as well as behaving like a standard text input with autocomplete options.
Import
- React
- Angular
- Vue.js
// with @dhl-official/react-library:
import { DhlSelect } from "@dhl-official/react-library"
// with @dhl-official/ui-libraries/react-library:
import { DhlSelect } from "@dhl-official/ui-libraries/react-library"
If the DUIL has been installed, you can use the web component directly:
<dhl-select></dhl-select>
// with @dhl-official/vue-library:
import { DhlSelect } from "@dhl-official/vue-library"
// with @dhl-official/ui-libraries/vue-library:
import { DhlSelect } from "@dhl-official/ui-libraries/vue-library"
Code
- React
- Angular
- Vue.js
<DhlSelect options={options}></DhlSelect>
<dhl-select [options]="options" ></dhl-select>
<dhl-select :options.prop="options" ></dhl-select>
The options property should be passed to the component as an array; objects within this array accept 4 values, label, value, image and disabled. The label and value properties are required. However, image and disabled are optional. Any other values that are added to this object will be ignored by default, however they can be taken into consideration when using them with custom props such as the customFilter. The select option type definition is as follows:
type DhlSelectOptionType = {
label: string;
value: string;
image?: string;
disabled?: boolean;
}
Interactive Demo
Readme
Usage
Dhl-select
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 with custom event and, default filter function and custom validation
<form novalidate>
<dhl-select
name="select"
required
value=""
></dhl-select>
<hr />
<dhl-button
type="reset"
variant="outline"
>reset</dhl-button
>
<dhl-button type="submit">submit</dhl-button>
</form>
<script type="module">
const form = document.querySelector("form");
const options = Array(30)
.fill(0)
.map((_a, i) => ({
image: i % 2 ? "./icons/airport.svg" : "./icons/x.svg",
label: "label " + i,
value: "value " + i,
}));
const select = document.querySelector("dhl-select");
select.options = [...options];
select.variant = {
label: "label",
placeholder: "placeholder",
type: "animated",
};
const checkSelectValidity = async () => {
const validationMessageInvalid = "This field is NOT valid";
const validationMessageValid = "This field is valid";
const isValid = await select.checkValidity();
select.validation = {
type: isValid ? "valid" : "invalid",
message: isValid ? validationMessageValid : validationMessageInvalid,
};
};
select.addEventListener("dhlKeyUp", console.log);
select.addEventListener("dhlKeyDown", console.log);
select.addEventListener("dhlInput", console.log);
form.addEventListener("submit", async (e) => {
e.preventDefault();
await checkSelectValidity();
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
</script>
usage with custom event, custom filter function and custom validation messages
<form novalidate>
<dhl-select
name="select"
value=""
></dhl-select>
<hr />
<dhl-button
type="reset"
variant="outline"
>reset</dhl-button
>
<dhl-button type="submit">submit</dhl-button>
</form>
<script type="module">
const form = document.querySelector("form");
const options = Array(30)
.fill(0)
.map((_a, i) => ({
image: i % 2 ? "./icons/airport.svg" : "./icons/x.svg",
label: i + " label",
value: i + " value",
}));
const select = document.querySelector("dhl-select");
select.options = [...options];
select.variant = {
label: "label",
placeholder: "placeholder",
type: "animated",
};
// custom filter example:
// only filter for values with at least 3 characters.
// if the user types "1 la" the options will be filtered
// to show only the options that contain "1 la" in the label
select.customFilter = (options, value) =>
value?.length < 3
? options
: options.filter((option) => option.label.includes(value));
const checkSelectValidity = async () => {
const validationMessageInvalid = "This field is NOT valid";
const validationMessageValid = "This field is valid";
const isValid = await select.checkValidity();
select.validation = {
type: isValid ? "valid" : "invalid",
message: isValid ? validationMessageValid : validationMessageInvalid,
};
};
select.addEventListener("dhlKeyUp", console.log);
select.addEventListener("dhlKeyDown", console.log);
select.addEventListener("dhlInput", console.log);
form.addEventListener("submit", async (e) => {
e.preventDefault();
await checkSelectValidity();
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
</script>
usage as phone input use case, with custom filter and custom option
<form novalidate>
<dhl-grid-container>
<dhl-grid-cell span-columns="3">
<dhl-select
name="calling-code"
value=""
></dhl-select>
</dhl-grid-cell>
<dhl-grid-cell span-columns="9">
<dhl-input-field
name="phone-number"
type="number"
></dhl-input-field>
</dhl-grid-cell>
<dhl-grid-cell span-columns="6">
<dhl-button
type="reset"
variant="outline"
>reset</dhl-button
>
</dhl-grid-cell>
<dhl-grid-cell span-columns="6">
<dhl-button type="submit">submit</dhl-button>
</dhl-grid-cell>
</dhl-grid-container>
</form>
<script type="module">
const form = document.querySelector("form");
const options = [
{
label: "+54 (Argentina)",
value: "Argentina",
callingCode: ["+54", "0054", "Argentina"],
},
{
label: "+61 (Australia)",
value: "Australia",
callingCode: ["+61", "0061", "Australia"],
},
{
label: "+39 (Italy)",
value: "Italy",
callingCode: ["+39", "0039", "Italy"],
},
{
label: "+971 (United Arab Emirates)",
value: "United Arab Emirates",
callingCode: ["+971", "0971", "United Arab Emirates"],
},
{
label: "+44 (United Kingdom)",
value: "United Kingdom",
callingCode: ["+44", "0044", "United Kingdom"],
},
];
const select = document.querySelector("dhl-select");
select.options = [...options];
select.variant = {
label: "Calling Code",
placeholder: "Calling Code",
type: "animated",
};
// custom filter example with custom option:
// filter for values using the custom option (callingCode).
// if the user inputs any of the values that are within the callingCode array e.g. "+44",
// the options will be filtered to show only the option/s that have "+44" in the label.
select.customFilter = (options, value) =>
options.filter((option) =>
option.callingCode.some(
(i) => i.includes(value) || option.label.includes(value),
),
);
const checkSelectValidity = async () => {
const validationMessageInvalid = "This field is NOT valid";
const validationMessageValid = "This field is valid";
const isValid = await select.checkValidity();
select.validation = {
type: isValid ? "valid" : "invalid",
message: isValid ? validationMessageValid : validationMessageInvalid,
};
};
select.addEventListener("dhlOptionsVisibilityChange", console.log);
select.addEventListener("dhlFocus", console.log);
const input = document.querySelector("dhl-input-field");
input.variant = {
label: "Phone Number",
placeholder: "Phone Number",
type: "animated",
};
form.addEventListener("submit", async (e) => {
e.preventDefault();
await checkSelectValidity();
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
</script>
Properties
Property | Attribute | Description | Type | Default |
---|---|---|---|---|
customFilter | -- | An optional callback handler that accepts the options and input data, used for custom filtering. If this function is not passed, by default, filtering will happen on the "label" key of the item if its an object or the actual value if the item is a primitive data type | (options: unknown, value: string) => DhlSelectOptionType[] | 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 | "When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures." |
dataId | data-id | An optional prop. Gives a valid HTML ID attribute value for the component. | string | dhl-select-${getRandomString()} |
getItemLabel | -- | An optional prop used to read the label of an option. | (option: any) => void | undefined |
isDisabled | is-disabled | An optional flag to define if the component is disabled. | boolean | false |
name | name | An optional value to be set to the element HTML name attribute. It takes any valid value that can be used for the name attribute of an HTMLInputElement. | string | undefined |
openOnFocus | open-on-focus | An optional prop when set to true, the select option list will be shown on input focus. | boolean | false |
options | -- | An optional data prop to pass the list of options to be rendered. | DhlSelectOptionType[] | [] |
required | required | An optional prop to flag the component as required within a form context. | boolean | undefined |
validation | -- | An optional object to set-up a custom components validation state. Required Fields: type | { type: Variants.valid \| Variants.invalid \| Variants.note; message?: string; } | undefined |
value | value | An optional prop defining the value of the component which is taken when a form is submitted. | string | "" |
variant | -- | A optional 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; } | undefined |
Events
Event | Description | Type |
---|---|---|
dhlOptionsVisibilityChange | Event emitted every time the select options visibility changes (i.e. every time it is displayed/hidden). | CustomEvent<any> |
Methods
checkValidity() => Promise<boolean>
Checks the validity of the input field.
Returns
Type: Promise<boolean>
A promise that resolves to true if the input field 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 input field.
Returns
Type: Promise<string>
A promise that resolves to a string representing the validation message.
reportValidity() => Promise<boolean>
Reports the validity of the input field.
Returns
Type: Promise<boolean>
A promise that resolves to a boolean indicating whether the input field is valid.
setValidity(validity: ValidityState, validationMessage?: string) => Promise<void>
Sets the validity state of the input field.
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-image
- dhl-input-field
- dhl-select-option
- dhl-validation-feedback
Graph
Built by DHL User Interface Library Team!