Skip to content

Commit

Permalink
feat: add modal efect for menu and remove it when click outside
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgianStan committed Jun 9, 2023
1 parent ac3956b commit af51b35
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ class Menu {

class VanillaContextMenu extends HTMLElement {
// private properties
#id: string;
#shadow: ShadowRoot;

#menu: Menu | undefined;
#menuTrigger: HTMLElement;

// private methods
#_onContextMenu(event: MouseEvent) {
Expand All @@ -67,19 +70,42 @@ class VanillaContextMenu extends HTMLElement {
// To remove and event listener, the same options that were send to 'addEventListener' functions must be send. Since 'bind' creates a new function, it's necessary to store the reference to this new function in a variable.
#onContextMenu: (event: MouseEvent) => void = this.#_onContextMenu.bind(this);

/** Removes the custom element and the 'contextmenu' event attached to the parent element. */
#remove() {
this.parentElement.removeEventListener('contextmenu', this.#onContextMenu);
this.remove();
}
/** Determine if a click event was triggered outside of the context menu and if so, remove it. */
#onDocumentClick = (event: MouseEvent): void => {
const clickedTarget = event.target as HTMLElement;

if (clickedTarget.closest(`[id='${this.#id}']`)) {
return;
}

this.#menu && this.#menu.remove();
};

// life-cycle methods
constructor() {
super();

this.#shadow = this.attachShadow({ mode: 'open' });
this.#menuTrigger = this.parentElement as HTMLElement;

// Append the style tag using the style-loader's configuration defined in webpack.config.js.
style.use({ target: this.#shadow });

this.parentElement.addEventListener('contextmenu', this.#onContextMenu);
// Set an unique id on this element.
this.setAttribute('id', (this.#id = crypto.randomUUID()));

this.#menuTrigger.addEventListener('contextmenu', this.#onContextMenu);

// Add a click event listener to create a modal effect for the menu and remove it if a click event is triggered outside of it.
document.addEventListener('click', this.#onDocumentClick);
}

disconnectedCallback() {
// Cleanup login when the custom element is removed from the DOM.
this.#menuTrigger.removeEventListener('contextmenu', this.#onContextMenu);
document.removeEventListener('click', this.#onDocumentClick);

this.#menu && this.#menu.remove();
}
}

Expand Down

0 comments on commit af51b35

Please sign in to comment.