@cbpds/web-components
Version:
Web components for the CBP Design System.
105 lines (101 loc) • 5.59 kB
JavaScript
/*!
* CPB Design System web components - built with Stencil
*/
import { r as registerInstance, c as createEvent, h, a as Host, g as getElement } from './index-6c11fa0c.js';
import { c as createNamespaceKey, b as clickAwayListener, e as doKeyboardNav, s as setCSSProps } from './utils-475ba472.js';
const cbpMenuCss = ":root{--cbp-menu-color-bg:var(--cbp-color-gray-cool-80);--cbp-menu-color-bg-dark:var(--cbp-color-gray-cool-5);--cbp-menu-gap:var(--cbp-space-3x)}[data-cbp-theme=light] cbp-menu[context*=dark],[data-cbp-theme=dark] cbp-menu:not([context=dark-inverts]):not([context=light-always]){--cbp-menu-color-bg:var(--cbp-menu-color-bg-dark)}cbp-menu{position:relative;display:inline-block;max-width:100%;}cbp-menu .cbp-menu__menu{position:absolute;top:0;left:0;display:block;width:max-content;padding:0;background:var(--cbp-menu-color-bg);border-radius:var(--cbp-border-radius-softer);box-shadow:var(--cbp-shadow-level-1-down);z-index:var(--cbp-z-index-level-0)}@media (min-width: 37.5em){cbp-menu .cbp-menu__menu{width:max-content;max-width:max-content;margin:0}cbp-menu[position=top-start] .cbp-menu__menu{top:100%;left:0;transform:translate(0, -100%)}cbp-menu[position=top-end] .cbp-menu__menu{top:100%;left:100%;transform:translate(-100%, -100%)}cbp-menu[position=bottom-start] .cbp-menu__menu{top:0;left:0}cbp-menu[position=bottom-end] .cbp-menu__menu{top:0;left:100%;transform:translate(-100%, 0)}}";
const CbpMenuStyle0 = cbpMenuCss;
const CbpMenu = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.toggleMenu = createEvent(this, "toggleMenu", 7);
this.position = 'bottom-start';
this.open = false;
this.uid = createNamespaceKey('cbp-menu');
this.accessibilityText = undefined;
this.context = undefined;
this.sx = {};
}
async openMenu() {
this.open = true;
}
async closeMenu() {
var _a;
this.open = false;
(_a = this.control) === null || _a === void 0 ? void 0 : _a.focus();
}
watchOpen(newValue) {
if (newValue) {
this.menuItems = Array.from(this.menu.querySelectorAll('button, a'));
clickAwayListener(this.host, _ => {
this.open = false;
});
this.toggleMenu.emit({
host: this.host,
control: this.control,
open: this.open
});
setTimeout(() => this.setCurrentMenuItem(), 500);
}
this.CBPButton.expanded = `${this.open}`;
}
clickAwayHandler({ target }) {
if (!target.closest(this.host))
this.open = false;
}
handleKeyPress(e) {
const { key, shiftKey } = e;
const openKeys = ['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'];
const navKeys = ['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft', 'Enter', 'Home', 'End'];
if (key == 'Escape')
this.closeMenu();
if (key == 'Tab' && !shiftKey)
this.open = false;
if (openKeys.includes(key) && !this.open) {
this.open = true;
return;
}
if (navKeys.includes(key)) {
this.focusIndex = doKeyboardNav(this.menuItems, key, this.focusIndex);
this.setCurrentMenuItem(this.focusIndex);
}
return;
}
setCurrentMenuItem(i = 0) {
this.menuItems[i].focus();
}
handleKeyPressCloseButton(e) {
if (e.key == 'Tab' && !e.shiftKey)
this.open = false;
}
componentWillLoad() {
this.CBPButton = this.host.querySelector('cbp-button');
this.control = this.host.querySelector('button');
if (typeof this.sx == 'string') {
this.sx = JSON.parse(this.sx) || {};
}
setCSSProps(this.host, Object.assign({}, this.sx));
}
componentDidLoad() {
this.menuItems = Array.from(this.menu.querySelectorAll('button,a'));
if (!this.control)
this.control = this.host.querySelector('button');
if (this.control) {
this.CBPButton.controls = this.uid;
this.CBPButton.expanded = `${this.open}`;
this.control.setAttribute('aria-controls', `${this.uid}-menu`);
this.control.setAttribute("aria-haspopup", "menu");
}
}
render() {
var _a;
return (h(Host, { key: '21624525db101101290ee100b176d9742b9637a4', id: this.uid, onKeyDown: (e) => this.handleKeyPress(e) }, h("slot", { key: '7f2ea4fddb22560d4f06ee0cde151bb448de738f' }), h("div", { key: 'e0e13d603ec15a0dd9ed4f0089ad0b801e6287fa', ref: (el) => this.menu = el, id: `${this.uid}-menu`, class: "cbp-menu__menu", role: "menu", hidden: !this.open, "aria-labelledby": (_a = this.control) === null || _a === void 0 ? void 0 : _a.id }, h("slot", { key: '6abc181437d81e93d107cc2a86cb7028934cf9ed', name: "cbp-menu-items" }), h("cbp-menu-item", { key: 'b7851c6be73a18bd9b3d71f18e24a6f5f23a7280', class: "cbp-menu__close-btn" }, h("cbp-button", { key: 'b6ee4d56ca853d6301f5d93289a92d48497cc314', fill: "solid", color: "primary", context: "dark-inverts", onButtonClick: () => this.closeMenu(), onKeyDown: (e) => this.handleKeyPressCloseButton(e) }, h("cbp-icon", { key: '5bbdab67491d4d31f35481d19b98335e852a0abc', name: "circle-xmark", size: "var(--cbp-space-5x)" }), "Close")))));
}
get host() { return getElement(this); }
static get watchers() { return {
"open": ["watchOpen"]
}; }
};
CbpMenu.style = CbpMenuStyle0;
export { CbpMenu as cbp_menu };
//# sourceMappingURL=cbp-menu.entry.js.map