Skip to content

Commit

Permalink
Reflect changes of one instance of the element to other instances of …
Browse files Browse the repository at this point in the history
…the element (if any) on page

In other words, animate their icons as well
  • Loading branch information
mahozad committed Mar 7, 2022
1 parent ce7798b commit 8811803
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 10 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
7 changes: 5 additions & 2 deletions test/template-4.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<script src="../theme-switch.js"></script>
<style>
#container {
display: flex;
flex-direction: column;
display: grid;
gap: 50px;
grid-template: 1fr 1fr / 1fr 1fr;
width: max-content;
}

Expand All @@ -19,6 +20,8 @@
<div id="container">
<theme-switch id="theme-switch-1"></theme-switch>
<theme-switch id="theme-switch-2"></theme-switch>
<theme-switch id="theme-switch-3"></theme-switch>
<theme-switch id="theme-switch-4"></theme-switch>
</div>

</body>
Expand Down
8 changes: 5 additions & 3 deletions test/theme-switch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const dom = new JSDOM(`
global.window = dom.window;
global.document = dom.window.document;
global.HTMLElement = dom.window.HTMLElement;
global.CustomEvent = dom.window.CustomEvent;
global.localStorage = dom.window.localStorage;
setSystemThemeTo("light");

Expand Down Expand Up @@ -230,12 +231,13 @@ describe("Screenshot tests", () => {
await expect(action).rejects.toThrowError("Node is either not visible or not an HTMLElement");
}, 100_000);

test(`When there are multiple instances of the element in page, clicking on of them should affect only that element`, async () => {
test(`When there are multiple instances of the element in page and one of them is toggled, others should be toggled too`, async () => {
const screenshot = await takeScreenshot(
() => { localStorage.setItem("theme", "light"); },
async (page) => {
const element = await page.$("#theme-switch-1");
element.click();
(await page.$("#theme-switch-2")).click();
await page.waitForTimeout(600);
(await page.$("#theme-switch-3")).click();
},
"template-4.html",
"#container"
Expand Down
35 changes: 34 additions & 1 deletion theme-switch.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ const ICON_INITIAL_STATE_FOR_AUTO = [10, 0, 33, 0];
const ICON_INITIAL_STATE_FOR_DARK = [10, 0, 20, 1];
const ICON_INITIAL_STATE_FOR_LIGHT = [5, 1, 33, 1];

let counter = 0; // See https://stackoverflow.com/a/43116254/8583692

class ThemeSwitchElement extends HTMLElement {
shadowRoot;
themeToggleEvent;
identifier = counter++;

constructor() {
super();
Expand All @@ -123,7 +127,25 @@ class ThemeSwitchElement extends HTMLElement {

// Add the click listener to the top-most parent (the custom element itself)
// so the padding etc. on the element be also clickable
this.shadowRoot.host.addEventListener("click", this.toggleTheme);
this.shadowRoot.host.addEventListener("click", () => {
this.toggleTheme();
this.dispatchEvent(this.themeToggleEvent);
});

// If another theme switch in page toggled, update my icon too
document.addEventListener("themeToggle", (event) => {
if (event.detail !== this.identifier) {
this.reflectTheme();
}
});

// See https://stackoverflow.com/a/53804106/8583692
this.themeToggleEvent = new CustomEvent("themeToggle", {
detail: this.identifier,
bubbles: true,
composed: true,
cancelable: false
});

// Create some CSS to apply to the shadow DOM
// See https://css-tricks.com/styling-a-web-component/
Expand All @@ -148,6 +170,17 @@ class ThemeSwitchElement extends HTMLElement {
updateTheme();
}

reflectTheme() {
const theme = getUserThemeSelection();
if (theme === THEME_AUTO) {
this.animateThemeButtonIconToAuto();
} else if (theme === THEME_DARK) {
this.animateThemeButtonIconToDark();
} else /* if (theme === THEME_LIGHT) */ {
this.animateThemeButtonIconToLight();
}
}

animateThemeButtonIconToLight() {
this.shadowRoot.getElementById("letter-anim-hide").beginElement();
this.shadowRoot.getElementById("core-anim-shrink").beginElement();
Expand Down
6 changes: 3 additions & 3 deletions theme-switch.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion theme-switch.min.js.map

Large diffs are not rendered by default.

0 comments on commit 8811803

Please sign in to comment.