UNPKG

@claromentis/design-system

Version:

Claromentis Design System Component Library

184 lines (183 loc) 4.93 kB
import { h } from '@stencil/core'; /** * @slot - Allows menu items to be added to the dropdown menu. */ export class Cardmenu { constructor() { this.toggle = false; this.isMobile = false; this.closeOnSelect = false; } /** * Listen for mousedown events and handle them */ handleClick(event) { // Close the menu if the user clicks elsewhere on the page if (!this.toggle) return; if (event.composedPath().indexOf(this.element) === -1) this.toggle = false; // Close Menu on Item Select const targetElement = event.target; if (this.closeOnSelect && targetElement.parentElement.closest('cla-menu')) { this.toggle = false; } } /** * Listen for window resize events and handle */ handleWindowResize() { this.checkIfMobile(); } /** * Listen for keydown events and handle * */ handleKeyDown(event) { const targetElement = event.target; switch (event.key) { case "Enter": // open/close menu when the toggle button is focussed if (targetElement.className === "dropdown-toggle-button") { this.toggleMenu(); } //when closeOnSelect is true close menu when 'Enter' is pressed if (this.closeOnSelect && targetElement.parentElement.closest('cla-menu')) { this.toggle = false; } break; case "Escape": //close menu when escape key is pressed if (this.toggle) { this.toggleMenu(); } break; case "Tab": //close menu if tab away from last item if (this.toggle && targetElement.parentElement.closest('cla-menu') && targetElement.nextElementSibling === null && !event.shiftKey) { this.toggleMenu(); } } } componentWillLoad() { //make non-link menu items tabbable let childrenArray = Array.from(this.element.children); childrenArray.forEach(function (menuItem) { menuItem.setAttribute('tabindex', '0'); }); } componentDidLoad() { this.checkIfMobile(); } /** * Checks if screen width is a mobile width * * @return Boolean */ checkIfMobile() { return window.screen.width < 768 ? this.isMobile = true : this.isMobile = false; } /** * Toggles the opening and closing of the menu. * * @return Boolean */ toggleMenu() { return this.toggle = !this.toggle; } /** * Get the map of CSS classes for the button. * * @return CssClassMap */ getMenuClassMap() { return { 'dropdown-menu': true, 'dropdown-menu-right': this.isMobile ? true : false }; } render() { return (h("div", { class: this.toggle ? "dropdown-wrapper in" : "dropdown-wrapper" }, h("button", { class: "dropdown-toggle-button", onMouseDown: () => this.toggleMenu(), onKeyDown: (e) => this.handleKeyDown(e) }, h("span", { class: "dot" }), h("span", { class: "dot" }), h("span", { class: "dot" }), h("span", { class: "sr-only" }, "toggle dropdown")), h("div", { class: this.getMenuClassMap() }, h("slot", null)))); } static get is() { return "cla-menu"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["cla-menu.scss"] }; } static get styleUrls() { return { "$": ["cla-menu.css"] }; } static get properties() { return { "closeOnSelect": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "If 'true' the menu will close when an item is selected" }, "attribute": "close-on-select", "reflect": false, "defaultValue": "false" } }; } static get states() { return { "toggle": {}, "isMobile": {} }; } static get events() { return [{ "method": "toggleEvent", "name": "toggleEvent", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the menu is toggled." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get elementRef() { return "element"; } static get listeners() { return [{ "name": "mousedown", "method": "handleClick", "target": "window", "capture": false, "passive": true }, { "name": "resize", "method": "handleWindowResize", "target": "window", "capture": false, "passive": true }, { "name": "keydown", "method": "handleKeyDown", "target": "window", "capture": false, "passive": false }]; } }