+
-
-
+
+
+
+
-
-
-
+
+
+
+
+
diff --git a/src/index.ts b/src/index.ts
index 83fe588..6a5187e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,21 +6,18 @@ import { Pen, ToolsController } from "./canvasController/tools";
import { CacheController } from "./canvasController/canvasData/cache";
import {
clearBtnController,
- dropdownController,
openBtnController,
saveBtnController,
- switchBtnController,
} from "./uiController";
import { loadData, saveData } from "./canvasController/canvasData/manipulate";
import { formatDate } from "./canvasController/helpers";
import { WindowData } from "./canvasController/windowData/windowDataController";
+import { Dropdown } from "./uiController/menu";
const board = document.getElementById("board") as HTMLCanvasElement;
const boardController = new CanvasController(board);
const windowData = new WindowData();
-const toggleClass = "menu-dropdown--isClosed";
-
if (boardController.ctx) {
// available tools
const pen = new Pen(boardController.ctx);
@@ -66,11 +63,7 @@ if (boardController.ctx) {
// ui setup
function uiSetup() {
- switchBtnController.onClick(() => {
- dropdownController.toggleIsOpen();
- dropdownController.toggleClass(toggleClass);
- dropdownController.toggleAriaHidden();
- });
+ customElements.define("canvas-dropdown", Dropdown);
saveBtnController.onClick(() => {
const curDate = formatDate(new Date());
diff --git a/src/style.css b/src/style.css
index 723682f..a4d09c5 100644
--- a/src/style.css
+++ b/src/style.css
@@ -41,29 +41,10 @@ button:hover {
box-shadow: inset 0 0 20px 20px rgba(0, 0, 0, 0.1);
}
-.menu,
-.tool-settings {
- position: absolute;
-
- margin: var(--content-padding);
-}
-
-.tool-settings {
+#settings-dropdown {
bottom: 0;
}
-.menu__item--onTop,
-.tool-settings__item--onTop {
- position: relative;
- z-index: 1;
-}
-
-#menu-dropdown {
- display: grid;
-
- margin-top: calc(var(--content-padding) / 2);
-}
-
#tool-settings-dropdown {
display: grid;
gap: 1rem;
@@ -71,10 +52,6 @@ button:hover {
background-color: white;
}
-.menu-dropdown--isClosed {
- display: none !important;
-}
-
-.menu-dropdown__divider {
+.menu__divider {
border: solid;
}
diff --git a/src/uiController/index.ts b/src/uiController/index.ts
index 67709de..4cffb6f 100644
--- a/src/uiController/index.ts
+++ b/src/uiController/index.ts
@@ -1,27 +1,17 @@
import { UiBtnController } from "./UiBtnController";
-import { DropdownController } from "./menu";
-
-const switchBtn = document.getElementById(
- "menu__toggle-btn"
-) as HTMLButtonElement;
const openBtn = document.getElementById(
- "menu-dropdown__open"
+ "menu__open"
) as HTMLButtonElement;
const saveBtn = document.getElementById(
- "menu-dropdown__save"
+ "menu__save"
) as HTMLButtonElement;
const clearBtn = document.getElementById(
- "menu-dropdown__clear"
+ "menu__clear"
) as HTMLButtonElement;
-const dropdown = document.getElementById("menu-dropdown") as HTMLElement;
-
-export const switchBtnController = new UiBtnController(switchBtn);
-
-export const dropdownController = new DropdownController(dropdown);
export const openBtnController = new UiBtnController(openBtn);
export const saveBtnController = new UiBtnController(saveBtn);
export const clearBtnController = new UiBtnController(clearBtn);
diff --git a/src/uiController/menu/Dropdown.ts b/src/uiController/menu/Dropdown.ts
new file mode 100644
index 0000000..99d8282
--- /dev/null
+++ b/src/uiController/menu/Dropdown.ts
@@ -0,0 +1,110 @@
+interface ICustomElement {
+ _internals: ElementInternals;
+
+ connectedCallback: () => void;
+ disconnectedCallback: () => void;
+ adoptedCallback: () => void;
+ attributeChangedCallback: (
+ name: observedAttributes,
+ oldValue: string,
+ newValue: string
+ ) => void;
+}
+
+type observedAttributes = "isopen";
+
+export class Dropdown extends HTMLElement implements Partial
{
+ static observedAttributes: observedAttributes[] = ["isopen"];
+
+ constructor() {
+ super();
+ }
+
+ connectedCallback() {
+ const shadow = this.attachShadow({ mode: "open" });
+ const template = document.getElementById("dropdown") as HTMLTemplateElement;
+
+ const style = new CSSStyleSheet();
+ style.replaceSync(`
+ :host {
+ position: absolute;
+
+ margin: var(--content-padding) !important;
+ }
+
+ #dropdown__section {
+ display: grid;
+
+ margin-top: calc(var(--content-padding) / 2);
+ }
+
+ .dropdown--onTop {
+ position: relative;
+ z-index: 1;
+ }
+
+ .dropdown--isClosed {
+ display: none !important;
+ }
+ `);
+
+ shadow.appendChild(template?.content.cloneNode(true));
+ shadow.adoptedStyleSheets = [style];
+
+ this.dropdownBtn.classList.add("dropdown--onTop");
+ this.dropdownBtn.addEventListener("click", this.toggleIsOpen);
+
+ this.dropdownSection.classList.add("dropdown--onTop");
+ this.dropdownSection.classList.add("dropdown--isClosed");
+ this.dropdownSection.ariaHidden = "true";
+ }
+
+ attributeChangedCallback(
+ //@ts-ignore
+ name: observedAttributes,
+ oldValue: string,
+ newValue: string
+ ): void {
+ if (!oldValue) return;
+
+ switch (newValue) {
+ case "true":
+ this.dropdownSection.classList.remove("dropdown--isClosed");
+ this.dropdownSection.ariaHidden = "false";
+ break;
+ case "false":
+ this.dropdownSection.classList.add("dropdown--isClosed");
+ this.dropdownSection.ariaHidden = "true";
+ break;
+ default:
+ break;
+ }
+ }
+
+ disconnectedCallback() {
+ this.dropdownBtn.removeEventListener("click", this.toggleIsOpen);
+ }
+
+ toggleIsOpen = () => {
+ switch (this.getAttribute("isopen")) {
+ case "true":
+ this.setAttribute("isopen", "false");
+ break;
+ case "false":
+ this.setAttribute("isopen", "true");
+ break;
+ default:
+ break;
+ }
+ };
+
+ get dropdownBtn() {
+ return this.shadowRoot?.getElementById(
+ "dropdown__btn"
+ ) as HTMLButtonElement;
+ }
+
+ get dropdownSection() {
+ return this.shadowRoot?.getElementById("dropdown__section") as HTMLElement;
+ }
+}
diff --git a/src/uiController/menu/dropdown.ts b/src/uiController/menu/dropdown.ts
deleted file mode 100644
index 888b48f..0000000
--- a/src/uiController/menu/dropdown.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-interface IDropdown {
- toggleIsOpen: () => void;
- toggleClass: (cssClass: string) => void;
- toggleAriaHidden: () => void;
-}
-
-export class DropdownController implements IDropdown {
- #dropdownEl: HTMLElement;
- #isOpen: "true" | "false";
-
- constructor(dropdownEl: HTMLElement) {
- this.#dropdownEl = dropdownEl;
-
- this.#isOpen = "false";
- this.#dropdownEl.dataset.isOpen = this.#isOpen;
- }
-
- toggleIsOpen() {
- switch (this.#isOpen) {
- case "true":
- this.#isOpen = "false";
- this.#dropdownEl.dataset.isOpen = this.#isOpen;
- break;
- case "false":
- this.#isOpen = "true";
- this.#dropdownEl.dataset.isOpen = this.#isOpen;
- break;
- default:
- break;
- }
- }
-
- toggleClass(cssClass: string) {
- switch (this.#isOpen) {
- case "true":
- this.#dropdownEl.classList.remove(cssClass);
- break;
- case "false":
- this.#dropdownEl.classList.add(cssClass);
- break;
- default:
- break;
- }
- }
-
- toggleAriaHidden() {
- switch (this.#isOpen) {
- case "true":
- this.#dropdownEl.ariaHidden = "false";
- break;
- case "false":
- this.#dropdownEl.ariaHidden = "true";
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/uiController/menu/index.ts b/src/uiController/menu/index.ts
index 4e5b6fd..6393c5e 100644
--- a/src/uiController/menu/index.ts
+++ b/src/uiController/menu/index.ts
@@ -1 +1 @@
-export { DropdownController } from "./dropdown";
+export { Dropdown } from "./Dropdown";