UNPKG

@scania/tegel

Version:
183 lines (182 loc) 7.41 kB
import { h, Host } from "@stencil/core"; import generateUniqueId from "../../../utils/generateUniqueId"; /** * @slot <default> - <b>Unnamed slot.</b> For injecting a dropdown list. * @slot icon - Slot for an Icon in the dropdown button. * @slot label - Slot for a label text in the dropdown button. */ export class TdsHeaderDropdown { constructor() { /** If the dropdown icon (downwards chevron) should be hidden. */ this.noDropdownIcon = false; /** If the button that opens the dropdown should appear selected. */ this.selected = false; this.open = false; this.uuid = generateUniqueId(); this.handleSlottedItemClick = (event) => { const eventSource = event.target.tagName.toLowerCase(); if (['a', 'button'].includes(eventSource)) { this.open = false; } }; } onAnyClick(event) { // 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; } } handleKeyDown(event) { var _a; if (event.key === 'Escape' && this.open) { this.open = false; (_a = this.buttonEl) === null || _a === void 0 ? void 0 : _a.focus(); } } toggleDropdown() { this.open = !this.open; if (this.open) { requestAnimationFrame(() => { var _a; const selectors = "a, [tabindex='0']"; const firstFocusableElement = ((_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(selectors)) || this.host.querySelector(selectors); if (firstFocusableElement instanceof HTMLElement) { firstFocusableElement.focus(); } }); } } render() { return (h(Host, { key: '81c477e45d3f6a4614c3928797f900fb9b64ffcc' }, h("div", { key: '2b4a3509254a827fa6d300793b699e57ac36cd9a', class: { 'state-open': this.open, } }, h("tds-header-item", { key: '4847e06a7b5fdf61642234f7179b01103e34fb38', class: "button", active: this.open, selected: this.selected }, h("button", { key: '8cc7fed2a05c68f0026ef7d4c17400d85d6a40af', ref: (el) => { this.buttonEl = el; }, "aria-expanded": `${this.open}`, "aria-controls": `launcher-${this.uuid}`, "aria-current": this.selected ? 'location' : 'false', onClick: () => { this.toggleDropdown(); }, "aria-label": this.tdsAriaLabel }, h("slot", { key: '8254bfb1f48d193bc0c58363df96fad41b61aad6', name: "icon" }), this.label, h("slot", { key: '5722ecd4748ad029b5b803bb4ff731cca119fc7b', name: "label" }), !this.noDropdownIcon && (h("tds-icon", { key: 'c0c9c51b4705226891b21383ce27c0680113af7c', class: "dropdown-icon", name: "chevron_down", size: "16px", svgTitle: "Dropdown icon" })))), this.buttonEl && (h("tds-popover-canvas", { key: '52e127dbe4eef7082e62f3421d338fa0b44ab919', id: `tds-dropdown-${this.uuid}`, class: "menu", referenceEl: this.buttonEl, placement: "bottom-start", show: this.open, offsetDistance: 0, modifiers: [ { name: 'flip', options: { fallbackPlacements: [], }, }, ] }, this.open ? (h("span", { onClick: (e) => this.handleSlottedItemClick(e), onKeyDown: (e) => e.key === 'Enter' && this.handleSlottedItemClick(e) }, h("slot", null))) : null))))); } static get is() { return "tds-header-dropdown"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["header-dropdown.scss"] }; } static get styleUrls() { return { "$": ["header-dropdown.css"] }; } static get properties() { return { "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The label of the button that opens the dropdown.\nThis is an alternative to the label slot." }, "getter": false, "setter": false, "reflect": false, "attribute": "label" }, "noDropdownIcon": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "If the dropdown icon (downwards chevron) should be hidden." }, "getter": false, "setter": false, "reflect": false, "attribute": "no-dropdown-icon", "defaultValue": "false" }, "selected": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "If the button that opens the dropdown should appear selected." }, "getter": false, "setter": false, "reflect": false, "attribute": "selected", "defaultValue": "false" }, "tdsAriaLabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Value to be used by the aria-label attribute" }, "getter": false, "setter": false, "reflect": false, "attribute": "tds-aria-label" } }; } static get states() { return { "open": {}, "buttonEl": {} }; } static get elementRef() { return "host"; } static get listeners() { return [{ "name": "click", "method": "onAnyClick", "target": "document", "capture": false, "passive": false }, { "name": "keydown", "method": "handleKeyDown", "target": "window", "capture": false, "passive": false }]; } }