-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshoestring-theme-selector.js
111 lines (100 loc) · 3.04 KB
/
shoestring-theme-selector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* @license
* Copyright 2032 Lalo Martins
* SPDX-License-Identifier: MIT
*/
import {LitElement, css, html} from 'lit';
/**
* A web component for pagination that uses Shoelace buttons for consistent UI.
*
* @element shoestring-pagination
*
* @dependency sl-switch
* @dependency sl-icon
*
* @attr [size=small] - Size to pass down to sl-switch
*
* @slot - If you provide contents, they will be used for the label; otherwise, `sl-icon name="moon" alt="Dark mode"`
*
* @fires theme-change - Indicates when the theme changes; `event.detail.isDark` is true when dark mode
*/
export class ThemeSelector extends LitElement {
static properties = {
size: {},
isDark: {state: true},
};
static styles = css`
:host {
display: block;
}
`;
constructor() {
super();
this.size = 'small';
}
connectedCallback() {
super.connectedCallback();
this.systemDarkMode =
window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches;
this.origDarkMode =
document.documentElement.classList.contains('sl-theme-dark');
this.origLightMode =
document.documentElement.classList.contains('sl-theme-light');
document.documentElement.classList.remove('sl-theme-light');
if (this.origDarkMode && this.origLightMode) {
this.isDark = this.systemDarkMode;
if (!this.systemDarkMode)
document.documentElement.classList.remove('sl-theme-dark');
} else if (!this.origDarkMode && !this.origLightMode) {
this.isDark = this.systemDarkMode;
if (this.systemDarkMode)
document.documentElement.classList.add('sl-theme-dark');
} else {
this.isDark =
(this.systemDarkMode && !this.origLightMode) || this.origDarkMode;
}
const customEvent = new CustomEvent('theme-change', {
bubbles: true,
composed: true,
detail: {isDark: this.isDark},
});
this.dispatchEvent(customEvent);
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.origDarkMode)
document.documentElement.classList.add('sl-theme-dark');
else document.documentElement.classList.remove('sl-theme-dark');
if (this.origLightMode)
document.documentElement.classList.add('sl-theme-light');
else document.documentElement.classList.remove('sl-theme-light');
}
_updateMode(event) {
this.isDark = event.target.checked;
if (this.isDark) {
document.documentElement.classList.add('sl-theme-dark');
} else {
document.documentElement.classList.remove('sl-theme-dark');
}
const customEvent = new CustomEvent('theme-change', {
bubbles: true,
composed: true,
detail: {isDark: this.isDark},
});
this.dispatchEvent(customEvent);
}
render() {
return html`<sl-switch
size=${this.size}
?checked=${this.isDark}
@sl-change=${this._updateMode}
aria-label="Toggle dark mode"
>
<slot>
<sl-icon name="moon" alt="Dark mode"></sl-icon>
</slot>
</sl-switch>`;
}
}
customElements.define('shoestring-theme-selector', ThemeSelector);