From b20240699b50ecd358cb85937badc0ce08009aad Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 28 Mar 2026 20:01:16 -0600 Subject: [PATCH] Update the toggle so that the animation plays fully before the events are emitted --- module/apps/elements/Toggle.mjs | 28 +++++++++++++++++++--------- styles/components/toggle.css | 8 ++++---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/module/apps/elements/Toggle.mjs b/module/apps/elements/Toggle.mjs index 8905879..e12b70f 100644 --- a/module/apps/elements/Toggle.mjs +++ b/module/apps/elements/Toggle.mjs @@ -1,5 +1,7 @@ import { StyledShadowElement } from "./StyledShadowElement.mjs"; +const { debounce } = foundry.utils; + export class TafToggle extends StyledShadowElement(HTMLElement) { static elementName = `taf-toggle`; static formAssociated = true; @@ -72,8 +74,9 @@ export class TafToggle extends StyledShadowElement(HTMLElement) { }; }; - const label = document.createElement(`label`); - label.dataset.type = `round`; + const container = document.createElement(`div`); + container.classList = `toggle`; + container.dataset.type = `round`; const input = this._input = document.createElement(`input`); input.type = `checkbox`; @@ -83,13 +86,17 @@ export class TafToggle extends StyledShadowElement(HTMLElement) { this.#emitEvents(); }); - label.appendChild(input); + this.addEventListener(`click`, () => { + input.click(); + }); + + container.appendChild(input); const slider = document.createElement(`div`); slider.classList = `slider`; - label.appendChild(slider); + container.appendChild(slider); - this._shadow.appendChild(label); + this._shadow.appendChild(container); this._mounted = true; }; @@ -100,8 +107,11 @@ export class TafToggle extends StyledShadowElement(HTMLElement) { this._mounted = false; }; - #emitEvents() { - this.dispatchEvent(new Event(`input`, {bubbles: true, cancelable: false})); - this.dispatchEvent(new Event(`change`, {bubbles: true, cancelable: false})); - }; + #emitEvents = debounce( + () => { + this.dispatchEvent(new Event(`input`, {bubbles: true, cancelable: false})); + this.dispatchEvent(new Event(`change`, {bubbles: true, cancelable: false})); + }, + 150, + ); }; diff --git a/styles/components/toggle.css b/styles/components/toggle.css index ce8fc67..ff21137 100644 --- a/styles/components/toggle.css +++ b/styles/components/toggle.css @@ -16,11 +16,11 @@ input { --slider-colour, var(--toggle-slider-unchecked-colour) ); - transition: all var(--speed, 150ms) ease-in-out; + transition: all 150ms ease-in-out; border-radius: 9999px; } -label { +.toggle { display: flex; padding: var(--padding, 4px); height: calc(var(--size, 16px) + (var(--padding, 4px) * 2)); @@ -34,7 +34,7 @@ label { cursor: pointer; /* Non-checked, clicking */ - &:active .slider { + &:is(&:active, &.active) .slider { width: calc(var(--size, 16px) * 1.5); } @@ -48,7 +48,7 @@ label { } /* checked, clicking */ - &:active > :checked + .slider { + &:is(&:active, &.active) > :checked + .slider { width: calc(var(--size, 16px) * 1.5); transform: translateX(calc(var(--size, 16px) * 0.5)); }