@scania/tegel
Version:
Tegel Design System
125 lines (124 loc) • 4.96 kB
JavaScript
import { Host, h } from "@stencil/core";
import generateUniqueId from "../../../utils/generateUniqueId";
import inheritAriaAttributes from "../../../utils/inheritAriaAttributes";
/**
* @slot <default> - <b>Unnamed slot.</b> For a launcher list (or grid) element.
*/
export class TdsHeaderLauncher {
constructor() {
this.open = false;
this.hasListTypeMenu = false;
this.uuid = generateUniqueId();
}
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, _b;
if (event.key === 'Escape' && this.open) {
this.open = false;
const btnShadow = (_b = (_a = this.buttonEl) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('button');
if (btnShadow)
btnShadow.focus();
}
}
componentDidLoad() {
const hasListTypeMenu = !!this.host.querySelector('tds-header-launcher-list');
this.hasListTypeMenu = hasListTypeMenu;
}
toggleLauncher() {
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() {
this.ariaAttributes = Object.assign(Object.assign({}, this.ariaAttributes), inheritAriaAttributes(this.host, ['role']));
const buttonAttributes = Object.assign(Object.assign({}, this.ariaAttributes), { 'aria-expanded': `${this.open}`, 'aria-controls': `launcher-${this.uuid}`, 'class': 'button', 'active': this.open, 'onClick': () => {
this.toggleLauncher();
}, 'ref': (el) => {
this.buttonEl = el;
} });
return (h(Host, { key: 'a794dc8a1d6585403012a2059b40fe2868e84e3e' }, h("div", { key: '2dffd73d6d9054fc0b84d59229f7264254173f47', class: {
'wrapper': true,
'state-open': this.open,
'state-list-type-menu': this.hasListTypeMenu,
} }, h("tds-header-launcher-button", Object.assign({ key: '26d9cd3499ee637bc16cb7588f03cf4b954ddac0' }, buttonAttributes, { "tds-aria-label": this.tdsAriaLabel })), this.buttonEl && (h("tds-popover-canvas", { key: '96e2dd6e07ff7e9c4d6e2f9ef335d1d043312d49', id: `tds-launcher-${this.uuid}`, class: "menu", referenceEl: this.buttonEl, placement: "bottom-start", show: this.open, offsetDistance: 0, modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: [],
},
},
] }, this.open ? h("slot", null) : null)))));
}
static get is() { return "tds-header-launcher"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["header-launcher.scss"]
};
}
static get styleUrls() {
return {
"$": ["header-launcher.css"]
};
}
static get properties() {
return {
"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 of the launcher button"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "tds-aria-label"
}
};
}
static get states() {
return {
"open": {},
"buttonEl": {},
"hasListTypeMenu": {}
};
}
static get elementRef() { return "host"; }
static get listeners() {
return [{
"name": "click",
"method": "onAnyClick",
"target": "window",
"capture": false,
"passive": false
}, {
"name": "keydown",
"method": "handleKeyDown",
"target": "window",
"capture": false,
"passive": false
}];
}
}