@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
424 lines (369 loc) • 8.8 kB
JavaScript
/**
* 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);