@scania/tegel
Version:
Tegel Design System
662 lines (655 loc) • 37.9 kB
JavaScript
import { p as proxyCustomElement, H, d as createEvent, h, c as Host } from './p-28ef5186.js';
import { c as convertToString, a as convertArrayToStrings } from './p-a1181b1f.js';
import { g as generateUniqueId } from './p-11648030.js';
import { d as defineCustomElement$1 } from './p-b390ece5.js';
/**
* Find the next focusable element index in a list of focusable elements.
* @param items List of focusable elements, element with a attribute of disabled that is true will be skipped over.
* @param nextItemIndex The index in the list to start the search on.
*/
const findNextFocusableElement = (items, nextItemIndex) => {
if (items[nextItemIndex] === undefined) {
return 0;
}
for (let index = nextItemIndex; index < items.length; index++) {
if (!items[index].disabled) {
return index;
}
}
};
/**
* Find the previous focusable element index in a list of focusable elements.
*
* @param items List of focusable elements, element with a attribute of disabled that is true will be skipped over.
* @param nextItemIndex The index in the list to start the search on.
*/
const findPreviousFocusableElement = (items, previousItemIndex) => {
if (items[previousItemIndex] === undefined) {
return items.length - 1;
}
for (let index = previousItemIndex; index >= 0; index--) {
if (!items[index].disabled) {
return index;
}
}
};
/** reference: https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/helpers.ts#L346
*
* Appends a hidden input element to allow the component
* work within and get picked up by a <form>.
* @param element The element on which the input with be appended.
* @param name Name of the input.
* @param value The value of the input.
* @param disabled Disables the input if true.
* @param additionalAttributes Additional attributes that should be passed to the input.
*/
const appendHiddenInput = (element, name, value, disabled, additionalAttributes) => {
let input = element.querySelector('input');
if (!element.querySelector('input')) {
input = element.ownerDocument.createElement('input');
input.type = 'hidden';
if (additionalAttributes) {
additionalAttributes.forEach((attr) => input.setAttribute(attr.key, attr.value));
}
element.appendChild(input);
}
input.disabled = disabled;
input.name = name;
input.value = value || '';
};
const dropdownCss = "@charset \"UTF-8\";:host button{all:unset;height:100%;width:100%;background-color:var(--tds-dropdown-bg);border-bottom:1px solid var(--tds-dropdown-border-bottom);border-radius:var(--tds-dropdown-border-radius)}:host button:hover{border-bottom:1px solid var(--tds-dropdown-border-bottom-hover)}:host button .value-wrapper{padding:0 16px;display:flex;align-items:center;justify-content:space-between}:host button.placeholder{color:var(--tds-dropdown-placeholder-color);line-height:1.3}:host button.value{color:var(--tds-dropdown-value-color);font:var(--tds-detail-02);letter-spacing:var(--tds-detail-02-ls);line-height:1.3}:host button:focus{border-bottom:0}:host button.error{border-bottom:1px solid var(--tds-dropdown-error)}:host button.error:focus{border-bottom-color:transparent}:host button.error:focus::before{content:\"\";position:absolute;bottom:0;left:0;width:100%;height:1px;background:var(--tds-dropdown-error)}:host button:disabled{color:var(--tds-dropdown-disabled-color);border-bottom:1px solid transparent}:host button .menu-icon{margin-right:0}:host .dropdown-select:focus-within{outline:2px solid var(--tds-focus-outline-color);box-shadow:0 0 0 1px var(--tds-white);outline-offset:1px;z-index:1}:host .filter{display:flex;align-items:center;justify-content:space-between;height:100%;background-color:var(--tds-dropdown-bg);border-bottom:1px solid var(--tds-dropdown-border-bottom);padding-left:16px;border-radius:4px 4px 0 0}:host .filter:hover{border-bottom:1px solid var(--tds-dropdown-border-bottom-hover)}:host .filter.disabled{color:var(--tds-dropdown-disabled-color);border-bottom:1px solid transparent}:host .filter.disabled .value-wrapper input{color:var(--tds-dropdown-disabled-color)}:host .filter .value-wrapper{display:flex;width:100%;height:100%}:host .filter .value-wrapper input{color:var(--tds-dropdown-filter-input-color)}:host .filter .label-inside-as-placeholder{position:absolute;font:var(--tds-detail-02);letter-spacing:var(--tds-detail-02-ls);line-height:1.3;color:var(--tds-dropdown-placeholder-color)}:host .filter .label-inside-as-placeholder.lg{top:20px}:host .filter .label-inside-as-placeholder.md{top:16px}:host .filter .label-inside-as-placeholder.sm{display:none}:host .filter .label-inside-as-placeholder.selected{font:var(--tds-detail-07);letter-spacing:var(--tds-detail-07-ls);transition:all 0.2s ease-in-out}:host .filter .label-inside-as-placeholder.selected.lg{top:12px}:host .filter .label-inside-as-placeholder.selected.md{top:8px}:host .filter .label-inside-as-placeholder.selected.sm{display:none}:host .filter .label-inside-as-placeholder.selected+.placeholder:not(.sm){margin-top:8px}:host .filter.focus{border-bottom:0}:host .filter.focus:hover{border-bottom:0}:host .filter.error{border-bottom:1px solid var(--tds-dropdown-error)}:host .filter.error.focus{border-bottom-color:transparent}:host .filter.error.focus::before{content:\"\";position:absolute;bottom:0;left:0;width:100%;height:1px;background:var(--tds-dropdown-error)}:host .filter input{flex:1;all:unset;width:100%}:host .filter input::placeholder{color:var(--tds-dropdown-placeholder-color)}:host .filter input:disabled::placeholder{color:var(--tds-dropdown-disabled-color)}:host .filter tds-icon{cursor:pointer}:host .filter .menu-icon{margin-right:16px}:host .filter .clear-icon{margin:0 8px;color:var(--tds-dropdown-clear-icon-color);padding-right:8px;border-right:1px solid var(--tds-dropdown-clear-icon-color)}:host .filter .clear-icon:hover{color:var(--tds-dropdown-clear-icon-hover-color)}:host .filter .clear-icon.hide{display:none;visibility:hidden}:host{--tds-scrollbar-width-standard:thin;--tds-scrollbar-width:10px;--tds-scrollbar-height:10px;--tds-scrollbar-thumb-border-width:3px;--tds-scrollbar-thumb-border-hover-width:2px}body{scrollbar-width:thin}:host{display:block;position:relative;font:var(--tds-detail-02);letter-spacing:var(--tds-detail-02-ls)}:host .label-outside{font:var(--tds-detail-05);letter-spacing:var(--tds-detail-05-ls);color:var(--tds-dropdown-label-color);margin-bottom:8px}:host .label-outside.disabled{color:var(--tds-dropdown-disabled-color)}:host .dropdown-select{position:relative}:host .dropdown-select button:focus{outline:2px solid var(--tds-focus-outline-color);box-shadow:0 0 0 1px var(--tds-white);outline-offset:1px;z-index:1;border-radius:0}:host .dropdown-select button{transition:border-bottom-color var(--tds-motion-duration-fast-02) var(--tds-motion-easing-scania)}:host .dropdown-select button:hover{border-bottom-color:var(--tds-dropdown-border-bottom-hover)}:host .dropdown-select button{border-bottom-color:var(--tds-dropdown-border-bottom)}:host .dropdown-select button.error{border-bottom-color:var(--tds-dropdown-error)}:host .dropdown-select button.error:focus{border-bottom-color:transparent}:host .dropdown-select.disabled .label-inside,:host .dropdown-select.disabled .placeholder,:host .dropdown-select.disabled .label-inside-as-placeholder,:host .dropdown-select.disabled .value-wrapper{color:var(--tds-dropdown-disabled-color)}:host .dropdown-select.disabled button{border:none}:host .dropdown-select .label-inside{position:absolute;font:var(--tds-detail-07);letter-spacing:var(--tds-detail-07-ls);color:var(--tds-dropdown-label-inside-color)}:host .dropdown-select .label-inside.lg{top:12px;left:16px}:host .dropdown-select .label-inside.md{top:8px;left:16px}:host .dropdown-select .label-inside.sm{display:none}:host .dropdown-select .label-inside.xs{display:none}:host .dropdown-select .label-inside+.placeholder:not(.sm){margin-top:8px}:host .dropdown-select .placeholder{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:var(--tds-placeholder-margin);}:host .dropdown-select .placeholder.xs{line-height:1}:host .dropdown-select .label-inside-as-placeholder{color:var(--tds-dropdown-placeholder-color)}:host .dropdown-select .label-inside-as-placeholder.selected{position:absolute;font:var(--tds-detail-07);letter-spacing:var(--tds-detail-07-ls);transition:all 0.2s ease-in-out}:host .dropdown-select .label-inside-as-placeholder.selected.lg{top:12px}:host .dropdown-select .label-inside-as-placeholder.selected.md{top:8px}:host .dropdown-select .label-inside-as-placeholder.selected.sm{display:none}:host .dropdown-select .label-inside-as-placeholder.selected+.placeholder:not(.sm){margin-top:8px}:host .dropdown-select.lg{height:55px}:host .dropdown-select.md{height:47px}:host .dropdown-select.sm{height:39px}:host .dropdown-select.xs{height:29px}:host .helper{margin-top:4px;color:var(--tds-dropdown-helper-color);font:var(--tds-detail-05);letter-spacing:var(--tds-detail-05-ls);display:flex;align-items:center;gap:8px}:host .helper.error{color:var(--tds-dropdown-error)}:host .helper.disabled{color:var(--tds-dropdown-disabled-color)}:host .dropdown-list{z-index:100;position:absolute;width:100%;transform-origin:top;box-shadow:0 2px 3px 0 rgba(0, 0, 0, 0.1);border-radius:var(--tds-dropdown-list-border-radius-down);overflow-y:auto;transform:scaleY(0);pointer-events:none}:host .dropdown-list:hover::-webkit-scrollbar-thumb{border:var(--tds-scrollbar-thumb-border-hover-width) solid transparent;background:var(--tds-scrollbar-hover-thumb-color);background-clip:padding-box}:host .dropdown-list::-webkit-scrollbar{width:var(--tds-scrollbar-width)}:host .dropdown-list::-webkit-scrollbar-track{background:var(--tds-scrollbar-track-color)}:host .dropdown-list::-webkit-scrollbar-thumb{border-radius:40px;background:var(--tds-scrollbar-thumb-color);border:var(--tds-scrollbar-thumb-border-width) solid transparent;background-clip:padding-box}:host .dropdown-list::-webkit-scrollbar-button{height:0;width:0}@supports not selector(::-webkit-scrollbar){:host .dropdown-list{scrollbar-color:var(--tds-scrollbar-thumb-color) var(--tds-scrollbar-track-color);scrollbar-width:var(--tds-scrollbar-width-standard)}}:host .dropdown-list.lg{max-height:312px}:host .dropdown-list.md{max-height:312px}:host .dropdown-list.sm{max-height:260px}:host .dropdown-list.xs{max-height:260px}:host .dropdown-list.up{bottom:100%;margin-top:0;margin-bottom:1px;transform-origin:bottom;display:flex;flex-direction:column-reverse;border-radius:var(--tds-dropdown-list-border-radius-up)}:host .dropdown-list.up.label-outside{bottom:calc(100% - 24px)}:host .dropdown-list.closed{transform:scaleY(0);pointer-events:none}:host .dropdown-list.open{transform:scaleY(1);visibility:visible;opacity:1;pointer-events:auto}:host .dropdown-list.animation-enter-slide{transition:transform var(--tds-motion-duration-moderate-01) var(--tds-motion-easing-enter)}:host .dropdown-list.animation-exit-slide{transition:transform var(--tds-motion-duration-moderate-01) var(--tds-motion-easing-exit)}:host .dropdown-list .no-result{font:var(--tds-detail-02);letter-spacing:var(--tds-detail-02-ls);display:flex;align-items:center;padding:0 16px;background-color:var(--tds-dropdown-bg)}:host .dropdown-list .no-result.lg{height:56px}:host .dropdown-list .no-result.md{height:48px}:host .dropdown-list .no-result.sm{height:40px}:host .dropdown-list .no-result.xs{height:40px}:host .menu-icon{color:var(--tds-dropdown-menu-icon-color)}:host tds-icon{transition:transform var(--tds-motion-duration-fast-02) var(--tds-motion-easing-scania)}:host tds-icon.open{transform:rotateZ(180deg)}";
const TdsDropdownStyle0 = dropdownCss;
function hasValueChanged(newValue, currentValue) {
if (newValue.length !== currentValue.length)
return true;
return newValue.some((val) => !currentValue.includes(val));
}
const TdsDropdown = /*@__PURE__*/ proxyCustomElement(class TdsDropdown extends H {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.tdsChange = createEvent(this, "tdsChange", 6);
this.tdsFocus = createEvent(this, "tdsFocus", 6);
this.tdsBlur = createEvent(this, "tdsBlur", 6);
this.tdsInput = createEvent(this, "tdsInput", 6);
this.setDefaultOption = () => {
if (this.internalDefaultValue) {
// Convert the internal default value to an array if it's not already
const defaultValues = this.multiselect
? this.internalDefaultValue.split(',')
: [this.internalDefaultValue];
this.updateDropdownStateInternal(defaultValues);
}
};
this.getChildren = () => {
const tdsDropdownOptions = Array.from(this.host.children).filter((element) => element.tagName === 'TDS-DROPDOWN-OPTION');
if (tdsDropdownOptions.length === 0) {
console.warn('TDS DROPDOWN: No options found. Disregard if loading data asynchronously.');
}
return tdsDropdownOptions;
};
this.getSelectedChildren = () => {
if (this.selectedOptions.length === 0)
return [];
return this.selectedOptions
.map((stringValue) => {
var _a;
const matchingElement = (_a = this.getChildren()) === null || _a === void 0 ? void 0 : _a.find((element) => convertToString(element.value) === convertToString(stringValue));
return matchingElement;
})
.filter(Boolean);
};
this.getSelectedChildrenLabels = () => {
var _a;
return (_a = this.getSelectedChildren()) === null || _a === void 0 ? void 0 : _a.map((element) => element.textContent.trim());
};
this.getValue = () => {
const labels = this.getSelectedChildrenLabels();
if (!labels) {
return '';
}
return labels === null || labels === void 0 ? void 0 : labels.join(', ');
};
this.setValueAttribute = () => {
if (this.selectedOptions.length === 0) {
this.host.removeAttribute('value');
}
else {
this.host.setAttribute('value', this.selectedOptions.join(','));
}
};
this.getOpenDirection = () => {
var _a, _b, _c, _d, _e;
if (this.openDirection === 'auto' || !this.openDirection) {
const dropdownMenuHeight = (_b = (_a = this.dropdownList) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0;
const distanceToBottom = (_e = (_d = (_c = this.host).getBoundingClientRect) === null || _d === void 0 ? void 0 : _d.call(_c).top) !== null && _e !== void 0 ? _e : 0;
const viewportHeight = window.innerHeight;
if (distanceToBottom + dropdownMenuHeight + 57 > viewportHeight) {
return 'up';
}
return 'down';
}
return this.openDirection;
};
this.handleToggleOpen = () => {
if (!this.disabled) {
this.open = !this.open;
if (this.open) {
if (this.filter) {
this.focusInputElement();
}
else {
const button = this.host.shadowRoot.querySelector('button');
if (button) {
button.focus();
}
}
}
}
};
this.focusInputElement = () => {
if (this.inputElement)
this.inputElement.focus();
};
this.handleFilter = (event) => {
this.tdsInput.emit(event);
const query = event.target.value.toLowerCase();
/* Check if the query is empty, and if so, show all options */
const children = this.getChildren();
if (query === '') {
children.forEach((element) => {
element.removeAttribute('hidden');
return element;
});
this.filterResult = null;
/* Hide the options that do not match the query */
}
else {
this.filterResult = children.filter((element) => {
if (!this.normalizeString(element.textContent)
.toLowerCase()
.includes(this.normalizeString(query).toLowerCase())) {
element.setAttribute('hidden', '');
}
else {
element.removeAttribute('hidden');
}
return !element.hasAttribute('hidden');
}).length;
}
};
this.handleFilterReset = () => {
this.reset();
this.inputElement.value = '';
this.handleFilter({ target: { value: '' } });
this.inputElement.focus();
// Add this line to ensure internal value is cleared
this.internalValue = '';
};
this.handleFocus = (event) => {
this.open = true;
this.filterFocus = true;
if (this.multiselect && this.inputElement) {
this.inputElement.value = '';
}
this.tdsFocus.emit(event);
if (this.filter) {
this.handleFilter({ target: { value: '' } });
}
};
this.handleBlur = (event) => {
this.tdsBlur.emit(event);
};
this.resetInput = () => {
const inputEl = this.host.querySelector('input');
if (inputEl) {
this.reset();
}
};
this.name = undefined;
this.disabled = false;
this.helper = undefined;
this.label = undefined;
this.labelPosition = undefined;
this.modeVariant = null;
this.openDirection = 'auto';
this.placeholder = undefined;
this.size = 'lg';
this.animation = 'slide';
this.error = false;
this.multiselect = false;
this.filter = false;
this.normalizeText = true;
this.noResultText = 'No result';
this.defaultValue = undefined;
this.value = null;
this.tdsAriaLabel = undefined;
this.open = false;
this.internalValue = undefined;
this.filterResult = undefined;
this.filterFocus = undefined;
this.internalDefaultValue = undefined;
this.selectedOptions = [];
}
handleValueChange(newValue) {
// Normalize to array
const normalizedValue = this.normalizeValue(newValue);
// Only update if actually changed
if (hasValueChanged(normalizedValue, this.selectedOptions)) {
this.updateDropdownStateFromUser(normalizedValue);
}
}
normalizeValue(value) {
if (value === null || value === undefined || value === '')
return [];
// For single select, ensure we handle both string and array inputs
if (!this.multiselect) {
// If array is passed to single select, take first value
if (Array.isArray(value)) {
return [convertToString(value[0])];
}
return [convertToString(value)];
}
// For multiselect
if (Array.isArray(value)) {
return convertArrayToStrings(value);
}
// Handle comma-separated string for multiselect
return value
.toString()
.split(',')
.filter((v) => v !== '');
}
updateDropdownStateInternal(values) {
this.updateDropdownState(values, false);
}
updateDropdownStateFromUser(values) {
this.updateDropdownState(values, true);
}
updateDropdownState(values, emitChange = true) {
// Validate the values first
const validValues = this.validateValues(values);
// Update internal state
this.selectedOptions = [...validValues];
// Update the value prop
this.value = this.multiselect ? this.selectedOptions : this.selectedOptions[0] || null;
// Update internal value for display
this.internalValue = this.getValue();
// Update DOM
this.updateOptionElements();
// Update display value
this.updateDisplayValue();
// Emit change event only if value has changed by user
if (emitChange)
this.emitChange();
// Update value attribute
this.setValueAttribute();
}
validateValues(values) {
// Make sure we have children before validation
const children = this.getChildren();
if (!children || children.length === 0) {
console.warn('No dropdown options found');
return values; // Return original values if no children yet
}
return values.filter((val) => {
const isValid = children.some((element) => convertToString(element.value) === convertToString(val));
if (!isValid) {
console.warn(`Option with value "${val}" does not exist`);
}
return isValid;
});
}
updateOptionElements() {
var _a;
(_a = this.getChildren()) === null || _a === void 0 ? void 0 : _a.forEach((element) => {
// Convert element.value to string for comparison
element.setSelected(this.selectedOptions.includes(convertToString(element.value)));
});
}
updateDisplayValue() {
this.internalValue = this.getSelectedChildrenLabels().join(', ');
if (this.filter && this.inputElement) {
this.inputElement.value = this.internalValue;
}
}
emitChange() {
const value = this.multiselect
? this.selectedOptions.join(',')
: this.selectedOptions[0] || null;
this.tdsChange.emit({
name: this.name,
value: value !== null && value !== void 0 ? value : null,
});
}
/** Method for setting the selected value of the Dropdown.
*
* Single selection example:
*
* <code>
* dropdown.setValue('option-1', 'Option 1');
* </code>
*
* Multiselect example:
*
* <code>
* dropdown.setValue(['option-1', 'option-2']);
* </code>
*/
// @ts-expect-error for label: the label is optional here ONLY to not break the API. Should be removed for 2.0.
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
async setValue(value, label) {
let normalizedValue;
if (Array.isArray(value)) {
normalizedValue = convertArrayToStrings(value);
}
else {
normalizedValue = [convertToString(value)];
}
this.updateDropdownStateFromUser(normalizedValue);
return this.getSelectedChildren().map((element) => ({
value: element.value,
label: element.textContent.trim(),
}));
}
async reset() {
this.updateDropdownStateFromUser([]);
}
async removeValue(oldValue) {
const newValues = this.selectedOptions.filter((v) => v !== oldValue);
this.updateDropdownStateFromUser(newValues);
}
/** Method that forces focus on the input element. */
async focusElement() {
if (this.filter) {
// For filter mode, focus the input element
this.focusInputElement();
}
else {
// For non-filter mode, focus the button element
const button = this.host.shadowRoot.querySelector('button');
if (button) {
button.focus();
}
}
// Always trigger the focus event to open the dropdown
this.handleFocus({});
}
/** Method for closing the Dropdown. */
async close() {
this.open = false;
}
/** Method to force update the dropdown display value.
* Use this method when you programmatically change the text content of dropdown options
* to ensure the selected value display updates immediately.
*/
async updateDisplay() {
this.updateDisplayValue();
}
onAnyClick(event) {
if (this.open) {
// Source: https://lamplightdev.com/blog/2021/04/10/how-to-detect-clicks-outside-of-a-web-component/
const isClickOutside = !event.composedPath().includes(this.host);
if (isClickOutside) {
this.open = false;
}
}
}
async onKeyDown(event) {
var _a;
// Get the active element
const { activeElement } = document;
if (!activeElement) {
return;
}
const children = this.getChildren();
if (event.key === 'ArrowDown') {
/* Get the index of the current focus index, if there is no
nextElementSibling return the index for the first child in our Dropdown. */
const startingIndex = activeElement.nextElementSibling
? children.findIndex((element) => element === activeElement.nextElementSibling)
: 0;
const elementIndex = findNextFocusableElement(children, startingIndex);
children[elementIndex].focus();
}
else if (event.key === 'ArrowUp') {
/* Get the index of the current focus index, if there is no
previousElementSibling return the index for the first last in our Dropdown. */
const startingIndex = activeElement.nextElementSibling
? this.getChildren().findIndex((element) => element === activeElement.previousElementSibling)
: 0;
const elementIndex = findPreviousFocusableElement(children, startingIndex);
children[elementIndex].focus();
}
else if (event.key === 'Escape') {
this.open = false;
// Return focus to input/button when Escape key is used
if (this.filter) {
(_a = this.inputElement) === null || _a === void 0 ? void 0 : _a.focus();
}
else {
const button = this.host.shadowRoot.querySelector('button');
button === null || button === void 0 ? void 0 : button.focus();
}
}
}
// If the Dropdown gets closed,
// this sets the value of the dropdown to the current selection labels or null if no selection is made.
handleOpenState() {
if (this.filter && this.multiselect) {
if (!this.open) {
this.inputElement.value = this.selectedOptions.length ? this.getValue() : '';
}
}
// Update the inert state of dropdown list when open state changes
this.updateDropdownListInertState();
}
handleDefaultValueChange(newValue) {
if (newValue !== undefined && newValue !== null) {
this.internalDefaultValue = convertToString(newValue);
this.setDefaultOption();
}
}
componentWillLoad() {
// First handle the value prop if it exists
if (this.value !== null && this.value !== undefined) {
const normalizedValue = this.normalizeValue(this.value);
this.updateDropdownStateInternal(normalizedValue);
return; // Exit early if we handled the value prop
}
// Only use defaultValue if no value prop was provided
if (this.defaultValue !== null && this.defaultValue !== undefined) {
const defaultValueStr = convertToString(this.defaultValue);
const initialValue = this.multiselect
? defaultValueStr.split(',').map(convertToString)
: [defaultValueStr];
this.updateDropdownStateInternal(initialValue);
}
}
/** Method to handle slot changes */
handleSlotChange() {
this.setDefaultOption();
}
/** Method to check if we should normalize text */
normalizeString(text) {
return this.normalizeText ? text.normalize('NFD').replace(/\p{Diacritic}/gu, '') : text;
}
/**
* @internal
*/
async appendValue(value) {
if (this.multiselect) {
this.updateDropdownStateFromUser([...this.selectedOptions, value]);
}
else {
this.updateDropdownStateFromUser([value]);
}
}
componentDidRender() {
const form = this.host.closest('form');
if (form) {
form.addEventListener('reset', this.resetInput);
}
// Initialize inert state after rendering
this.updateDropdownListInertState();
}
disconnectedCallback() {
const form = this.host.closest('form');
if (form) {
form.removeEventListener('reset', this.resetInput);
}
}
connectedCallback() {
if (!this.tdsAriaLabel) {
console.warn('Tegel Dropdown component: tdsAriaLabel prop is missing');
}
}
updateDropdownListInertState() {
if (this.dropdownList) {
if (this.open) {
this.dropdownList.removeAttribute('inert');
}
else {
this.dropdownList.setAttribute('inert', '');
}
}
}
render() {
appendHiddenInput(this.host, this.name, this.selectedOptions.join(','), this.disabled);
// Generate unique IDs for associating labels and helpers with the input/button
const labelId = this.label ? `dropdown-label-${this.name || generateUniqueId()}` : undefined;
const helperId = this.helper ? `dropdown-helper-${this.name || generateUniqueId()}` : undefined;
return (h(Host, { key: '676f9d61c5fd8488cedbc949757e992be13e49eb', class: {
[`tds-mode-variant-${this.modeVariant}`]: Boolean(this.modeVariant),
} }, this.label && this.labelPosition === 'outside' && (h("div", { key: 'ac4f3c9ca2719acc72f06ae977bf032d05913c6d', id: labelId, class: `label-outside ${this.disabled ? 'disabled' : ''}` }, this.label)), h("div", { key: 'c9d4142f63e315c73daef5038f266a32b05559a1', class: {
'dropdown-select': true,
[this.size]: true,
'disabled': this.disabled,
} }, this.filter ? (h("div", { class: {
filter: true,
focus: this.filterFocus,
disabled: this.disabled,
error: this.error,
} }, h("div", { class: "value-wrapper" }, this.label && this.labelPosition === 'inside' && this.placeholder && (h("div", { id: labelId, class: `label-inside ${this.size}` }, this.label)), this.label && this.labelPosition === 'inside' && !this.placeholder && (h("div", { id: labelId, class: `
label-inside-as-placeholder
${this.size}
${this.selectedOptions.length ? 'selected' : ''}
` }, this.label)), h("input", { "aria-label": this.tdsAriaLabel, "aria-labelledby": labelId, "aria-describedby": helperId, "aria-disabled": this.disabled,
// eslint-disable-next-line no-return-assign
ref: (inputEl) => (this.inputElement = inputEl), class: {
placeholder: this.labelPosition === 'inside',
}, type: "text", placeholder: this.filterFocus ? '' : this.placeholder, value: this.multiselect && this.filterFocus ? '' : this.getValue(), disabled: this.disabled, onInput: (event) => this.handleFilter(event), onBlur: (event) => {
this.filterFocus = false;
if (this.multiselect) {
this.inputElement.value = this.getValue();
}
this.handleBlur(event);
}, onFocus: (event) => this.handleFocus(event), onKeyDown: (event) => {
if (event.key === 'Escape') {
this.open = false;
}
} })), h("tds-icon", { tabIndex: 0, role: "button", "aria-label": "Clear filter", svgTitle: "Clear filter", onClick: this.handleFilterReset, onKeyDown: (event) => {
if (event.key === 'Enter') {
this.handleFilterReset();
}
}, class: {
'clear-icon': true,
'hide': !(this.open && this.inputElement.value !== ''),
}, name: "cross", size: "16px" }), h("tds-icon", { tdsAriaHidden: true, role: "button", "aria-label": "Open/Close dropdown", svgTitle: "Open/Close dropdown", onClick: this.handleToggleOpen, onKeyDown: (event) => {
if (event.key === 'Enter') {
this.handleToggleOpen();
}
}, class: `menu-icon ${this.open ? 'open' : 'closed'}`, name: "chevron_down", size: "16px" }))) : (h("button", { "aria-label": this.tdsAriaLabel, "aria-labelledby": labelId, "aria-describedby": helperId, "aria-disabled": this.disabled, onClick: () => this.handleToggleOpen(), onKeyDown: (event) => {
if (event.key === 'Escape') {
this.open = false;
}
}, class: `
${this.selectedOptions.length ? 'value' : 'placeholder'}
${this.open ? 'open' : 'closed'}
${this.error ? 'error' : ''}
`, disabled: this.disabled }, h("div", { class: `value-wrapper ${this.size}` }, this.label && this.labelPosition === 'inside' && this.placeholder && (h("div", { id: labelId, class: `label-inside ${this.size}` }, this.label)), this.label && this.labelPosition === 'inside' && !this.placeholder && (h("div", { id: labelId, class: `
label-inside-as-placeholder
${this.size}
${this.selectedOptions.length ? 'selected' : ''}
` }, this.label)), h("div", { class: `placeholder ${this.size}` }, this.selectedOptions.length ? this.getValue() : this.placeholder), h("tds-icon", { "aria-label": "Open/Close dropdown", svgTitle: "Open/Close dropdown", class: `menu-icon ${this.open ? 'open' : 'closed'}`, name: "chevron_down", size: "16px" }))))), h("div", { key: '6de931198040eec79815f83e2617d2646507b6a1', role: "listbox", "aria-label": this.tdsAriaLabel, inert: !this.open, "aria-orientation": "vertical", "aria-multiselectable": this.multiselect, ref: (element) => {
this.dropdownList = element;
}, class: {
'dropdown-list': true,
[this.size]: true,
[this.getOpenDirection()]: true,
'label-outside': this.label && this.labelPosition === 'outside',
'open': this.open,
'closed': !this.open,
[`animation-enter-${this.animation}`]: this.animation !== 'none' && this.open,
[`animation-exit-${this.animation}`]: this.animation !== 'none' && !this.open,
} }, h("slot", { key: '61ab9737181371073b25b95c34dad3311c2995c0', onSlotchange: () => this.handleSlotChange() }), this.filterResult === 0 && this.noResultText !== '' && (h("div", { key: 'aca39f881a57a6a23de03da78b5062e5dff55af7', class: `no-result ${this.size}` }, this.noResultText))), this.helper && (h("div", { key: '1e4221e58bc16608bfb0f780b7bc8040935eab37', id: helperId, class: {
helper: true,
error: this.error,
disabled: this.disabled,
} }, this.error && h("tds-icon", { key: 'ec946e77add75e7eaf194e2b38e5dd1c548ab32f', name: "error", size: "16px" }), this.helper))));
}
get host() { return this; }
static get watchers() { return {
"value": ["handleValueChange"],
"open": ["handleOpenState"],
"defaultValue": ["handleDefaultValueChange"]
}; }
static get style() { return TdsDropdownStyle0; }
}, [1, "tds-dropdown", {
"name": [1],
"disabled": [4],
"helper": [1],
"label": [1],
"labelPosition": [1, "label-position"],
"modeVariant": [1, "mode-variant"],
"openDirection": [1, "open-direction"],
"placeholder": [1],
"size": [1],
"animation": [1],
"error": [4],
"multiselect": [4],
"filter": [4],
"normalizeText": [4, "normalize-text"],
"noResultText": [1, "no-result-text"],
"defaultValue": [8, "default-value"],
"value": [1032],
"tdsAriaLabel": [1, "tds-aria-label"],
"open": [32],
"internalValue": [32],
"filterResult": [32],
"filterFocus": [32],
"internalDefaultValue": [32],
"selectedOptions": [32],
"setValue": [64],
"reset": [64],
"removeValue": [64],
"focusElement": [64],
"close": [64],
"updateDisplay": [64],
"appendValue": [64]
}, [[9, "mousedown", "onAnyClick"], [0, "keydown", "onKeyDown"]], {
"value": ["handleValueChange"],
"open": ["handleOpenState"],
"defaultValue": ["handleDefaultValueChange"]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["tds-dropdown", "tds-icon"];
components.forEach(tagName => { switch (tagName) {
case "tds-dropdown":
if (!customElements.get(tagName)) {
customElements.define(tagName, TdsDropdown);
}
break;
case "tds-icon":
if (!customElements.get(tagName)) {
defineCustomElement$1();
}
break;
} });
}
defineCustomElement();
export { TdsDropdown as T, defineCustomElement as d };