UNPKG

@nent/core

Version:

Functional elements to add routing, data-binding, dynamic HTML, declarative actions, audio, video, and so much more. Supercharge static HTML files into web apps without script or builds.

155 lines (154 loc) 4.92 kB
/*! * NENT 2022 */ import { Component, Element, h, Host, Prop } from '@stencil/core'; import { appState, onAppChange } from '../n-app/services/state'; /** * This element checks for the preferred light/dark theme preference of the * user and sets the ui state: theme, accordingly. * * @system app */ export class AppTheme { constructor() { /** * Change the element that is decorated with * the dark-mode class */ this.targetElement = 'body'; /** * Change the class name that is added to the * target element when the theme is determined to * be dark. */ this.darkClass = 'dark'; /** * Display the user's system preference. */ this.display = false; /** * This element displays the current theme, * unless in switch-mode, it will show the opposite. */ this.switch = false; } componentWillLoad() { this.subscribeToSystem(); } subscribeToSystem() { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); if ((prefersDark === null || prefersDark === void 0 ? void 0 : prefersDark.addEventListener) && appState.darkMode == null) { prefersDark.addEventListener('change', ev => { appState.darkMode = ev.matches; }); appState.darkMode = prefersDark.matches; } this.stateSubscription = onAppChange('darkMode', () => { this.toggleDarkTheme(); }); } componentWillRender() { this.toggleDarkTheme(); } toggleDarkTheme() { const element = this.targetElement == 'body' ? this.el.ownerDocument.body : this.el.ownerDocument.querySelector(this.targetElement); if (appState.darkMode) element === null || element === void 0 ? void 0 : element.classList.toggle(this.darkClass, true); else element === null || element === void 0 ? void 0 : element.classList.remove(this.darkClass); } render() { if (this.display) { const swap = this.switch ? !appState.darkMode : appState.darkMode; return (h(Host, null, h("svg", { class: "themeIcon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "24", height: "24" }, h("path", { fill: "none", d: "M0 0h24v24H0z" }), swap ? (h("path", { d: "M11.38 2.019a7.5 7.5 0 1 0 10.6 10.6C21.662 17.854 17.316 22 12.001 22 6.477 22 2 17.523 2 12c0-5.315 4.146-9.661 9.38-9.981z" })) : (h("path", { d: "M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z" }))))); } return null; } disconnectedCallback() { var _a; (_a = this.stateSubscription) === null || _a === void 0 ? void 0 : _a.call(this); } static get is() { return "n-app-theme"; } static get properties() { return { "targetElement": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Change the element that is decorated with\nthe dark-mode class" }, "attribute": "target-element", "reflect": false, "defaultValue": "'body'" }, "darkClass": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Change the class name that is added to the\ntarget element when the theme is determined to\nbe dark." }, "attribute": "dark-class", "reflect": false, "defaultValue": "'dark'" }, "display": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Display the user's system preference." }, "attribute": "display", "reflect": false, "defaultValue": "false" }, "switch": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "This element displays the current theme,\nunless in switch-mode, it will show the opposite." }, "attribute": "switch", "reflect": false, "defaultValue": "false" } }; } static get elementRef() { return "el"; } }