UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

183 lines (161 loc) 4.81 kB
/** * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved. * Node module: @schukai/monster * * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3). * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html * * For those who do not wish to adhere to the AGPLv3, a commercial license is available. * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms. * For more information about purchasing a commercial license, please contact schukai GmbH. * * SPDX-License-Identifier: AGPL-3.0 */ import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs"; import { assembleMethodSymbol, CustomElement, registerCustomElement, } from "../../dom/customelement.mjs"; import { validateInstance, validateString } from "../../types/validate.mjs"; import { Message } from "./message.mjs"; import { NotifyStyleSheet } from "./stylesheet/notify.mjs"; import { Queue } from "../../types/queue.mjs"; import { fireCustomEvent } from "../../dom/events.mjs"; export { Notify }; /** * @private * @type {symbol} */ const controlElementSymbol = Symbol("controlElement"); /** * @private * @type {symbol} */ const containerElementSymbol = Symbol("containerElement"); /** * @private * @type {symbol} */ const queueSymbol = Symbol("queue"); /** * The Notify control * * @fragments /fragments/components/notify/notify * * @example /examples/components/notify/notify-simple Notify * @example /examples/components/notify/notify-inline Inline Notify * * @issue https://localhost.alvine.dev:8440/development/issues/closed/269.html * * @since 1.0.0 * @copyright schukai GmbH * @summary The Notify control is a notification container that can be used to display messages to the user. */ class Notify extends CustomElement { constructor() { super(); this[queueSymbol] = new Queue(); } /** * @property {string} orientation The orientation of the notify element. Allowed values for horizontal orientation are "left", "center", "right". Allowed values for vertical orientation are "top" and "bottom". * @property {object} templates The templates of the notify element. * @property {string} templates.main The main template of the notify element. * @property {object} classes The classes of the notify element. * @property {string} classes.container The container class of the notify element. * @property {string} classes.control The control class of the notify element. */ get defaults() { return Object.assign({}, super.defaults, { orientation: "left top", templates: { main: getTemplate(), }, classes: { container: "", control: "center", }, }); } /** * @return {Notify} */ [assembleMethodSymbol]() { super[assembleMethodSymbol](); initControlReferences.call(this); if (this[containerElementSymbol]) { while (this[queueSymbol].isEmpty() === false) { this.push(this[queueSymbol].poll()); } } return this; } /** * @return {string} */ static getTag() { return "monster-notify"; } /** * * @return {CSSStyleSheet[]} */ static getCSSStyleSheet() { return [NotifyStyleSheet]; } /** * @param {Massage|String} message * @return {Notify} */ push(message) { let messageElement = message; if (!(message instanceof Message)) { const text = validateString(message); messageElement = document.createElement("monster-notify-message"); messageElement.setOption("content", text); } validateInstance(messageElement, Message); messageElement.setAttribute(ATTRIBUTE_ROLE, "message"); // if not connected, add to queue if (!this[containerElementSymbol]) { this[queueSymbol].add(messageElement); return this; } fireCustomEvent(this, "monster-notify-message", { messageElement, }); this[containerElementSymbol].appendChild(messageElement); return this; } } /** * @private * @return {Select} * @throws {Error} no shadow-root is defined */ function initControlReferences() { if (!this.shadowRoot) { throw new Error("no shadow-root is defined"); } this[controlElementSymbol] = this.shadowRoot.querySelector( "[" + ATTRIBUTE_ROLE + "=control]", ); this[containerElementSymbol] = this.shadowRoot.querySelector( "[" + ATTRIBUTE_ROLE + "=container]", ); } /** * @private * @return {string} */ function getTemplate() { // language=HTML return ` <div data-monster-role="control" part="control" data-monster-attributes="data-monster-orientation path:orientation, class path:classes.control"> <div data-monster-attributes="class path:classes.container" part="container" data-monster-role="container"></div> </div> `; } registerCustomElement(Notify);