@ribajs/bs5
Version:
Bootstrap 5 module for Riba.js
91 lines (78 loc) • 2.64 kB
text/typescript
import { Binder } from "@ribajs/core";
import { Popover, PopoverOptions } from "@ribajs/bs5";
/**
*
*/
export class PopoverBinder extends Binder<string, HTMLElement> {
static key = "bs5-popover";
private popover?: Popover;
private listeners: { [key: string]: EventListener } = {};
routine(el: HTMLElement, optionsOrContent: string | PopoverOptions) {
let options: Partial<PopoverOptions> = {};
if (typeof optionsOrContent === "string") {
options.content = optionsOrContent;
} else if (typeof optionsOrContent === "object") {
options = { ...optionsOrContent };
}
options.placement = options.placement || "auto";
const popover = new Popover(el, {
...Popover.Default,
...options,
});
// destroy previous popover if it already exists
if (this.popover) {
this.popover.dispose();
}
this.popover = popover;
/*
* Methods "show", "hide", etc. of the Popover can be called by dispatching an
* event `trigger-${methodName}` on the bound element.
* All these methods have no arguments.
*/
const methodNames: (keyof typeof popover)[] = [
"show",
"hide",
"toggle",
"dispose",
"enable",
"disable",
"update", // render update
];
// remove listeners of previous Popover if there already was one
if (this.listeners) {
for (const [trigger, listener] of Object.entries(this.listeners)) {
this.el.removeEventListener(trigger, listener as EventListener);
}
}
this.listeners = Object.create(null);
for (const methodName of methodNames) {
if (popover[methodName] && typeof popover[methodName] === "function") {
const trigger = `trigger-${String(methodName)}`;
const listener = (popover[methodName] as any).bind(popover);
this.el.addEventListener(trigger, listener);
this.listeners[trigger] = listener;
} else {
console.warn("Unknown method " + methodName);
}
}
}
bind(el: HTMLElement) {
// inform ancestors that this popover was bound
// Event name in same style as the other popover CustomEvents from Bootstrap
el.dispatchEvent(
new CustomEvent("bound.bs.popover", { bubbles: true, cancelable: true }),
);
}
unbind() {
// destroy Popover if it already exists
if (this.popover) {
this.popover.dispose();
}
// remove listeners if there are any
if (this.listeners) {
for (const [trigger, listener] of Object.entries(this.listeners)) {
this.el.removeEventListener(trigger, listener as EventListener);
}
}
}
}