import "./ol-toolbar"; import "./ol-reader"; import "./ol-highlight" import { LitElement, html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { Styles, Tags } from './types/types'; import { STYLES, injectStyles, injectFontStyles } from './styles' import { injectSelf } from "./utils/injectSelf"; import { useStore } from "./state/store"; import { applyActiveElement } from "./utils/activeElement"; import { observeDOM } from "./utils/utils"; /** * The Ol Provider element * * Provides styles for all the children components. These styles * can be mutated with teh updateStyles function. * * @fires styles-changed - Indicates when the styles change * @slot - This element has a slot */ const LS_PREFIX = "ol-provider" injectSelf(); @customElement('ol-provider') export class OlProvider extends LitElement { @property({ attribute: false }) styles: Styles = { 'color': 'black', 'font-family': "'Roboto'", 'line-height': "1", 'word-spacing': "normal", 'background-color': "white", 'font-size': "100%", 'animation': '.1s ease-in-out', 'text-align': 'initial', }; @property({ type: String }) tags: String = "p" @property({ attribute: false }) mounted = false; // Override the connected callback to check the localStorage // for previous styles. override connectedCallback(): void { super.connectedCallback(); // Add a listener to inject styles everytime an IFRAME is loaded. observeDOM(document, () => { injectStyles(this.styles, this.tags.split(" ") as unknown as Tags[]); injectFontStyles(); // Apply the active element listeners to the host element const host: HTMLElement = (this.renderRoot as (HTMLElement & { host: HTMLElement })).host; applyActiveElement(host); // Reinject on dom change for single page apps injectSelf(); }); useStore(this); // Inject the styles for fonts and icons injectFontStyles(); // Retrieve all of the previous values and set them to // the styles property const styles = this.styles; // Get the keys of the styles and validate them. function isValidKey(key: string): key is keyof Styles { return STYLES.hasOwnProperty(key); } const keys: (keyof Styles)[] = Object.keys(this.styles).filter(isValidKey); for (const key of keys) { // Check if in local storage const value = localStorage.getItem(`${LS_PREFIX}-${key}`); // Make sure that value in local storage is valid. const isValidValue = (v: string): v is Styles[typeof key] => { return STYLES[key as keyof typeof STYLES].includes(v); } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore This is checked via the prior function. if (value && isValidValue(value)) styles[key] = value as Styles[typeof key]; } } // The styles mutation function. You can use it to mutate // styles that are specified in the Styles interface. updateStyles = (key: K, value: Styles[K]) => { this.styles[key] = value; // Save the changes to local storage localStorage.setItem(`${LS_PREFIX}-${key}`, value); // Request an update to re-render the slot this.requestUpdate(); this.dispatchEvent(new CustomEvent('style-changed')) } override render() { // Inject the document styles for the applicable tags injectStyles(this.styles, this.tags.split(" ") as unknown as Tags[]); this.mounted = true; return html`
`; } } declare global { interface HTMLElementTagNameMap { 'ol-provider': OlProvider; } }