UNPKG

@schukai/monster

Version:

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

424 lines (369 loc) 8.8 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. */ import { instanceSymbol } from "../../constants.mjs"; import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs"; import { CustomElement } from "../../dom/customelement.mjs"; import { assembleMethodSymbol, registerCustomElement, } from "../../dom/customelement.mjs"; import { DayStyleSheet } from "./stylesheet/day.mjs"; import { isString } from "../../types/is.mjs"; import { getLocaleOfDocument } from "../../dom/locale.mjs"; import { Observer } from "../../types/observer.mjs"; import { Processing } from "../../util/processing.mjs"; export { Day }; /** * @private * @type {symbol} */ const dayElementSymbol = Symbol("dayElement"); /** * @private * @type {symbol} */ const dayMonthElementSymbol = Symbol("dayMonthElement"); /** * @private * @type {symbol} */ const dayDayElementSymbol = Symbol("dayDayElement"); /** * @private * @type {symbol} */ const dayWeekdayElementSymbol = Symbol("dayWeekdayElement"); /** * @private * @type {symbol} */ const dayLabelElementSymbol = Symbol("dayLabelElement"); /** * A Day Control * * @fragments /fragments/components/time/day/ * * @example /examples/components/time/day-simple * @example /examples/components/time/day-simple-small * * @since 3.113.0 * @copyright schukai GmbH * @summary A day control that displays the day, month, weekday and a label. */ class Day extends CustomElement { /** * */ constructor() { super(); initOptionObserver.call(this); } /** * This method is called by the `instanceof` operator. * @returns {symbol} */ static get [instanceSymbol]() { return Symbol.for("@schukai/monster/components/time/day@@instance"); } /** * * @return {Components.Time.Day */ [assembleMethodSymbol]() { super[assembleMethodSymbol](); initControlReferences.call(this); updateDate.call(this); return this; } /** * To set the options via the HTML Tag, the attribute `data-monster-options` must be used. * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} * * The individual configuration values can be found in the table. * * @property {Object} templates Template definitions * @property {string} templates.main Main template * @property {string} date The date of the day */ get defaults() { return Object.assign({}, super.defaults, { templates: { main: getTemplate(), }, date: null, day: null, month: null, weekday: null, label: null, disabled: false, }); } /** * @return {string} */ static getTag() { return "monster-day"; } /** * @return {CSSStyleSheet[]} */ static getCSSStyleSheet() { return [DayStyleSheet]; } /** * @return {string[]} * @since 1.15.0 */ static get observedAttributes() { return ["data-monster-option-date"]; } } /** * @private */ function initOptionObserver() { const self = this; let lastDate = this.getOption("date"); self.attachObserver( new Observer(function () { new Processing(() => { if (lastDate !== self.getOption("date")) { lastDate = self.getOption("date"); updateDate.call(self); } }).run(); }), ); } /** * @private */ function updateDate() { const labels = getLabels.call(this); let date = this.getOption("date"); let day = null; let label = null; if (date === null) { date = new Date(); } else if (isString(date)) { date = new Date(date); } if (!(date instanceof Date)) { return; } day = date.getDate(); const locale = getLocaleOfDocument(); this.setOption("day", day); this.setOption( "month", new Intl.DateTimeFormat(locale.toString(), { month: "short", }).format(date), ); this.setOption( "weekday", new Intl.DateTimeFormat(locale.toString(), { weekday: "long", }).format(date), ); if (date.toDateString() === new Date().toDateString()) { label = labels.today; } else if ( date.toDateString() === new Date(new Date().setDate(new Date().getDate() - 1)).toDateString() ) { label = labels.yesterday; } else if ( date.toDateString() === new Date(new Date().setDate(new Date().getDate() + 1)).toDateString() ) { label = labels.tomorrow; } this.setOption("label", label); } function getLabels() { switch (getLocaleOfDocument().language) { case "de": // German return { today: "Heute", tomorrow: "Morgen", yesterday: "Gestern", }; case "es": // Spanish return { today: "Hoy", tomorrow: "Mañana", yesterday: "Ayer", }; case "zh": // Mandarin return { today: "今天", tomorrow: "明天", yesterday: "昨天", }; case "hi": // Hindi return { today: "आज", tomorrow: "कल", yesterday: "बीता कल", }; case "bn": // Bengali return { today: "আজ", tomorrow: "আগামীকাল", yesterday: "গতকাল", }; case "pt": // Portuguese return { today: "Hoje", tomorrow: "Amanhã", yesterday: "Ontem", }; case "ru": // Russian return { today: "Сегодня", tomorrow: "Завтра", yesterday: "Вчера", }; case "ja": // Japanese return { today: "今日", tomorrow: "明日", yesterday: "昨日", }; case "pa": // Western Punjabi return { today: "ਅਜ", tomorrow: "ਕਲ", yesterday: "ਬੀਤੇ ਕਲ", }; case "mr": // Marathi return { today: "आज", tomorrow: "उद्या", yesterday: "काल", }; case "fr": // French return { today: "Aujourd'hui", tomorrow: "Demain", yesterday: "Hier", }; case "it": // Italian return { today: "Oggi", tomorrow: "Domani", yesterday: "Ieri", }; case "nl": // Dutch return { today: "Vandaag", tomorrow: "Morgen", yesterday: "Gisteren", }; case "sv": // Swedish return { today: "Idag", tomorrow: "Imorgon", yesterday: "Igår", }; case "pl": // Polish return { today: "Dziś", tomorrow: "Jutro", yesterday: "Wczoraj", }; case "da": // Danish return { today: "I dag", tomorrow: "I morgen", yesterday: "I går", }; case "fi": // Finnish return { today: "Tänään", tomorrow: "Huomenna", yesterday: "Eilen", }; case "no": // Norwegian return { today: "I dag", tomorrow: "I morgen", yesterday: "I går", }; case "cs": // Czech return { today: "Dnes", tomorrow: "Zítra", yesterday: "Včera", }; default: return { today: "Today", tomorrow: "Tomorrow", yesterday: "Yesterday", }; } } /** * @private * @param format * @returns {*[]} */ function getWeekdays(format = "long") { const locale = getLocaleOfDocument(); const weekdays = []; for (let i = 1; i < 8; i++) { const date = new Date(1970, 0, 4 + i); // 4. Jan. 1970 = Sonntag weekdays.push( new Intl.DateTimeFormat(locale, { weekday: format }).format(date), ); } return weekdays; } /** * @private * @return {void} */ function initControlReferences() { this[dayElementSymbol] = this.shadowRoot.querySelector( `[${ATTRIBUTE_ROLE}="control"]`, ); this[dayMonthElementSymbol] = this.shadowRoot.querySelector( `[${ATTRIBUTE_ROLE}="month"]`, ); this[dayDayElementSymbol] = this.shadowRoot.querySelector( `[${ATTRIBUTE_ROLE}="day"]`, ); this[dayWeekdayElementSymbol] = this.shadowRoot.querySelector( `[${ATTRIBUTE_ROLE}="weekday"]`, ); this[dayLabelElementSymbol] = this.shadowRoot.querySelector( `[${ATTRIBUTE_ROLE}="label"]`, ); } /** * @private * @return {string} */ function getTemplate() { // language=HTML return ` <div data-monster-role="control" part="control"> <div class="month" data-monster-role="month" part="month" data-monster-replace="path:month"></div> <div data-monster-role="day" part="day" data-monster-replace="path:day">12</div> <div style="width: 100%; height: 0;" part="divider"></div> <div data-monster-role="weekday" part="weekday" data-monster-replace="path:weekday">Wed</div> <div data-monster-role="label" part="label" data-monster-replace="path:label">Tomorrow</div> </div>`; } registerCustomElement(Day);