diff --git a/src/index.html b/src/index.html index 97346b8..cf2dadf 100644 --- a/src/index.html +++ b/src/index.html @@ -1,33 +1,29 @@ - + - - - - - - Little Notes - - - - - - -
-
- - - -
+ + + + + Little Notes + + + + + M + + + + + + + + + S + + + + +
-
+
-
-
+ + + + + + 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";