web-ui-pack
Version:
Web package with UI elements
96 lines (95 loc) • 3.92 kB
JavaScript
import WUPBaseElement from "./baseElement";
import WUPPopupElement from "./popup/popupElement";
import { WUPcssButton, WUPcssMenu } from "./styles";
const tagName = "wup-dropdown";
export default class WUPDropdownElement extends WUPBaseElement {
#ctr = this.constructor;
static get $style() {
return `${super.$style}
:host {
contain: style;
display: inline-block;
}${WUPcssButton(":host button")}
:host button {
min-width: initial;
margin: 0;
padding: 0.7em;
}${WUPcssMenu(":host>[menu]")}`;
}
static $defaults = {
...WUPPopupElement.$defaults,
animation: 1,
openCase: 8 | 4,
closeOnPopupClick: true,
minHeightByTarget: true,
minWidthByTarget: true,
placement: [
WUPPopupElement.$placements.$bottom.$start,
WUPPopupElement.$placements.$bottom.$end,
WUPPopupElement.$placements.$top.$start,
WUPPopupElement.$placements.$top.$end,
WUPPopupElement.$placements.$bottom.$start.$resizeHeight,
WUPPopupElement.$placements.$bottom.$end.$resizeHeight,
WUPPopupElement.$placements.$top.$start.$resizeHeight,
WUPPopupElement.$placements.$top.$end.$resizeHeight,
],
};
$refTitle = this.firstElementChild;
$refPopup = this.lastElementChild;
$refMenu = this.lastElementChild;
gotReady() {
this.$refTitle = this.firstElementChild;
this.$refPopup = this.lastElementChild;
if (this.$refTitle === this.$refPopup || !this.$refPopup.$open) {
this.throwError("Invalid structure. Expected 1st element: <any/>, last element: <wup-popup/>");
}
else {
this.$refPopup.setAttribute("menu", "");
this.$refPopup.goOpen = this.goOpenPopup.bind(this);
this.$refPopup.goClose = this.goClosePopup.bind(this);
const excluded = new Set();
const proto = Object.getPrototypeOf(this.$refPopup).constructor;
const mappedAttr = proto.mappedAttributes;
this.$refPopup.getAttributeNames().forEach((a) => {
a = a.startsWith("w-") ? a.substring(2) : a;
const m = mappedAttr[a];
m && excluded.add(m.prop ?? a);
});
Object.keys(this._opts).forEach((k) => {
if (!excluded.has(k)) {
this.$refPopup.$options[k] = this._opts[k];
}
});
const menu = this.$refPopup.querySelector("ul,ol,[items]") || this.$refPopup;
menu.id = menu.id || this.#ctr.$uniqueId;
this.$refMenu = menu;
const lbl = this.$refTitle;
lbl.setAttribute("aria-owns", menu.id);
lbl.setAttribute("aria-controls", menu.id);
lbl.setAttribute("aria-haspopup", "listbox");
lbl.setAttribute("aria-expanded", false);
!menu.hasAttribute("tabindex") && menu.setAttribute("tabindex", -1);
}
super.gotReady();
}
goOpenPopup(openCase, ev) {
const p = WUPPopupElement.prototype.goOpen.call(this.$refPopup, openCase, ev);
const t = this.$refPopup.$options.target;
t.setAttribute("aria-expanded", true);
t.style.zIndex = `${+getComputedStyle(this.$refPopup).zIndex + 2}`;
return p;
}
goClosePopup(closeCase, ev) {
if (closeCase === 4 && !this._opts.closeOnPopupClick) {
return Promise.resolve(false);
}
const p = WUPPopupElement.prototype.goClose.call(this.$refPopup, closeCase, ev).finally(() => {
t.style.zIndex = "";
this.removeEmptyStyle.call(t);
});
const t = this.$refPopup.$options.target;
t.setAttribute("aria-expanded", false);
return p;
}
}
customElements.define(tagName, WUPDropdownElement);