diff --git a/nix/scripts/release.nix b/nix/scripts/release.nix index 33e6232e9e88baa2a677f5f18dd9b6c4ecb6fdfd..448def3c36d06fe8176f46526d1842b83d78f0c8 100644 --- a/nix/scripts/release.nix +++ b/nix/scripts/release.nix @@ -26,11 +26,9 @@ in cd $CI_PROJECT_DIR || exit 1 - #### ${pkgs'.git}/bin/git remote set-url origin https://''${CI_REPOSITORY_URL#*@} echo_step "Set git remote url to https://pad:secret@''${CI_REPOSITORY_URL#*@}" ${pkgs'.git}/bin/git remote set-url origin https://pad:''${GITLAB_TOKEN}@''${CI_REPOSITORY_URL#*@} - ${pkgs'.git}/bin/git fetch --all --tags --unshallow ${pkgs'.git}/bin/git reset --hard origin/master ${pkgs'.git}/bin/git clean -fd diff --git a/source/components/form/context-error.mjs b/source/components/form/context-error.mjs index 7e5d4d5cec765d56b8ea9b740a3235bb223dc8e5..7eff7ae613db3bacbede9788b5ea78054bbceac5 100644 --- a/source/components/form/context-error.mjs +++ b/source/components/form/context-error.mjs @@ -228,7 +228,7 @@ class ContextError extends Popper { } /** - * Returns the html tag of the control. + * Returns the HTML Tag of the control. * * @return {string} */ diff --git a/source/components/form/field-set.mjs b/source/components/form/field-set.mjs index 498b070bd4450f7ea9645dbc6a4a787172369abc..27e1501693f307cd36c8dabc1a37e556294bea7e 100644 --- a/source/components/form/field-set.mjs +++ b/source/components/form/field-set.mjs @@ -67,39 +67,6 @@ const toggleSwitchElementSymbol = Symbol("toggleSwitchElement"); */ const extendedSwitchElementSymbol = Symbol("extendedSwitchElement"); -/** - * This CustomControl creates a FieldSet element with a variety of options. - * - * <img src="./images/field-set.png"> - * - * You can create this control either by specifying the HTML tag <monster-field-set />` directly in the HTML or using - * Javascript via the `document.createElement('monster-field-set');` method. - * - * ```html - * <monster-field-set></monster-field-set> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import {FieldSet} from '@schukai/monster/source/components/form/field-set.mjs'; - * document.createElement('monster-field-set'); - * ``` - * - * @externalExample ../..../example/components/form/field-set.mjs - * @startuml field-set.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * CustomControl <|-- FieldSet - * @enduml - * - * @copyright schukai GmbH - * @memberOf Monster.Components.Form - * @summary A simple FieldSet - */ - /** * A field set control that can be used to group form elements. * @@ -143,6 +110,7 @@ class FieldSet extends CustomControl { * @property {Object} actions Callbacks * @property {string} actions.click="throw Error" Callback when clicked * @property {Object} features Features + * @property {boolean} features.multipleColumns=true Multiple columns * @property {Object} classes CSS classes * @property {boolean} disabled=false Disabled state */ @@ -152,14 +120,16 @@ class FieldSet extends CustomControl { main: getTemplate(), }, labels: { - "toggle-switch-on": "✔", - "toggle-switch-off": "✖", - "toggle-switch-label": "Expand", + toggleSwitchOn: "✔", + toggleSwitchOff: "✖", + toggleSwitchLabel: "Expand", title: "", }, classes: {}, disabled: false, - features: {}, + features: { + multipleColumns: true, + }, actions: { click: () => { throw new Error("the click action is not defined"); @@ -293,12 +263,12 @@ function updateExtendedFields() { */ function initEventHandler() { this[toggleSwitchElementSymbol].setOption( - "labels.toggle-switch-on", - this.getOption("labels.toggle-switch-on"), + "labels.toggleSwitchOn", + this.getOption("labels.toggleSwitchOn"), ); this[toggleSwitchElementSymbol].setOption( - "labels.toggle-switch-off", - this.getOption("labels.toggle-switch-off"), + "labels.toggleSwitchOff", + this.getOption("labels.toggleSwitchOff"), ); this[toggleSwitchElementSymbol].setOption("actions.on", () => { diff --git a/source/components/form/toggle-switch.mjs b/source/components/form/toggle-switch.mjs index c8bae61505ee065d908334168c78c4f258ca48cf..7fbf692e7f2233a8031758f9aa976f331944790d 100644 --- a/source/components/form/toggle-switch.mjs +++ b/source/components/form/toggle-switch.mjs @@ -12,26 +12,26 @@ * SPDX-License-Identifier: AGPL-3.0 */ -import { instanceSymbol } from "../../constants.mjs"; -import { internalSymbol } from "../../constants.mjs"; -import { CustomControl } from "../../dom/customcontrol.mjs"; -import { Observer } from "../../types/observer.mjs"; -import { ProxyObserver } from "../../types/proxyobserver.mjs"; +import {instanceSymbol} from "../../constants.mjs"; +import {internalSymbol} from "../../constants.mjs"; +import {CustomControl} from "../../dom/customcontrol.mjs"; +import {Observer} from "../../types/observer.mjs"; +import {ProxyObserver} from "../../types/proxyobserver.mjs"; -import { addAttributeToken } from "../../dom/attributes.mjs"; +import {addAttributeToken} from "../../dom/attributes.mjs"; import { - assembleMethodSymbol, - registerCustomElement, - updaterTransformerMethodsSymbol, + assembleMethodSymbol, + registerCustomElement, + updaterTransformerMethodsSymbol, } from "../../dom/customelement.mjs"; -import { isObject, isFunction } from "../../types/is.mjs"; -import { ToggleSwitchStyleSheet } from "./stylesheet/toggle-switch.mjs"; +import {isObject, isFunction} from "../../types/is.mjs"; +import {ToggleSwitchStyleSheet} from "./stylesheet/toggle-switch.mjs"; import { - ATTRIBUTE_ERRORMESSAGE, - ATTRIBUTE_ROLE, + ATTRIBUTE_ERRORMESSAGE, + ATTRIBUTE_ROLE, } from "../../dom/constants.mjs"; -export { ToggleSwitch }; +export {ToggleSwitch}; /** * @private @@ -49,25 +49,6 @@ export const STATE_ON = "on"; */ export const STATE_OFF = "off"; -/** - * This CustomControl creates a ToggleSwitch element - * - * <img src="./images/toggleswitch.png"> - * - * - * @startuml toggleswitch.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * CustomControl <|-- ToggleSwitch - * @enduml - * - * @copyright schukai GmbH - * @memberOf Monster.Components.Form - * @summary A simple toggle switch - */ - /** * A simple toggle switch * @@ -84,340 +65,340 @@ export const STATE_OFF = "off"; * @fires monster-changed */ class ToggleSwitch extends CustomControl { - /** - * 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 {string} value=current value of the element - * @property {Boolean} disabled=disabled=false Disabled state - * @property {Object} classes - * @property {string} classes.on=specifies the class for the on state. - * @property {string} classes.off=specifies the class for the off state. - * @property {Object} values - * @property {string} values.off=specifies the value of the element if it is not selected - * @property {Object} labels - * @property {string} labels.on=specifies the label for the on state. - * @property {string} labels.off=specifies the label for the off state. - * @property {string} actions - * @property {string} actions.on=specifies the action for the on state. - * @property {string} actions.off=specifies the action for the off state. - * @property {Object} templates - * @property {string} templates.main=specifies the main template used by the control. - */ - get defaults() { - return Object.assign({}, super.defaults, { - value: null, - disabled: false, - classes: { - on: "monster-theme-on", - off: "monster-theme-off", - handle: "monster-theme-primary-1", - }, - values: { - on: "on", - off: "off", - }, - labels: { - "toggle-switch-on": "ON", - "toggle-switch-off": "OFF", - }, - templates: { - main: getTemplate(), - }, - actions: { - on: () => { - throw new Error("the on action is not defined"); - }, - off: () => { - throw new Error("the off action is not defined"); - }, - }, - }); - } - - /** - * @return {ToggleSwitch} - */ - [assembleMethodSymbol]() { - const self = this; - super[assembleMethodSymbol](); - initControlReferences.call(this); - initEventHandler.call(this); - - /** - * init value to off - * if the value was not defined before inserting it into the HTML - */ - if (self.getOption("value") === null) { - self.setOption("value", self.getOption("values.off")); - } - - /** - * value from attribute - */ - if (self.hasAttribute("value")) { - self.setOption("value", self.getAttribute("value")); - } - - /** - * validate value - */ - validateAndSetValue.call(self); - - if (this.state === STATE_ON) { - toggleClassOn.call(self); - } else { - toggleClassOff.call(self); - } - - /** - * is called when options changed - */ - self[internalSymbol].attachObserver( - new Observer(function () { - if (isObject(this) && this instanceof ProxyObserver) { - validateAndSetValue.call(self); - toggleClass.call(self); - } - }), - ); - - return this; - } - - /** - * updater transformer methods for pipe - * - * @return {function} - */ - [updaterTransformerMethodsSymbol]() { - return { - "state-callback": (Wert) => { - return this.state; - }, - }; - } - - /** - * @return [CSSStyleSheet] - */ - static getCSSStyleSheet() { - return [ToggleSwitchStyleSheet]; - } - - /** - * toggle switch - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * e.click() - * ``` - */ - click() { - toggleValues.call(this); - } - - /** - * toggle switch on/off - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * e.toggle() - * ``` - * - * @return {ToggleSwitch} - */ - toggle() { - this.click(); - return this; - } - - /** - * toggle switch on - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * e.toggleOn() - * ``` - * - * @return {ToggleSwitch} - */ - toggleOn() { - this.setOption("value", this.getOption("values.on")); - return this; - } - - /** - * toggle switch off - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * e.toggleOff() - * ``` - * - * @return {ToggleSwitch} - */ - toggleOff() { - this.setOption("value", this.getOption("values.off")); - return this; - } - - /** - * returns the status of the element - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * console.log(e.state) - * // ↦ off - * ``` - * - * @return {string} - */ - get state() { - return this.getOption("value") === this.getOption("values.on") - ? STATE_ON - : STATE_OFF; - } - - /** - * The current value of the Switch - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * console.log(e.value) - * // ↦ on - * ``` - * - * @return {string} - */ - get value() { - return this.state === STATE_ON - ? this.getOption("values.on") - : this.getOption("values.off"); - } - - /** - * Set value - * - * ``` - * e = document.querySelector('monster-toggle-switch'); - * e.value="on" - * ``` - * - * @property {string} value - */ - set value(value) { - this.setOption("value", value); - } - - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for( - "@schukai/monster/components/form/toggle-switch@@instance", - ); - } - - static getTag() { - return "monster-toggle-switch"; - } + /** + * 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 {string} value=current value of the element + * @property {Boolean} disabled=disabled=false Disabled state + * @property {Object} classes + * @property {string} classes.on=specifies the class for the on state. + * @property {string} classes.off=specifies the class for the off state. + * @property {Object} values + * @property {string} values.off=specifies the value of the element if it is not selected + * @property {Object} labels + * @property {string} labels.on=specifies the label for the on state. + * @property {string} labels.off=specifies the label for the off state. + * @property {string} actions + * @property {string} actions.on=specifies the action for the on state. + * @property {string} actions.off=specifies the action for the off state. + * @property {Object} templates + * @property {string} templates.main=specifies the main template used by the control. + */ + get defaults() { + return Object.assign({}, super.defaults, { + value: null, + disabled: false, + classes: { + on: "monster-theme-on", + off: "monster-theme-off", + handle: "monster-theme-primary-1", + }, + values: { + on: "on", + off: "off", + }, + labels: { + toggleSwitchOn: "✔", + toggleSwitchOff: "✖", + }, + templates: { + main: getTemplate(), + }, + actions: { + on: () => { + throw new Error("the on action is not defined"); + }, + off: () => { + throw new Error("the off action is not defined"); + }, + }, + }); + } + + /** + * @return {ToggleSwitch} + */ + [assembleMethodSymbol]() { + const self = this; + super[assembleMethodSymbol](); + initControlReferences.call(this); + initEventHandler.call(this); + + /** + * init value to off + * if the value was not defined before inserting it into the HTML + */ + if (self.getOption("value") === null) { + self.setOption("value", self.getOption("values.off")); + } + + /** + * value from attribute + */ + if (self.hasAttribute("value")) { + self.setOption("value", self.getAttribute("value")); + } + + /** + * validate value + */ + validateAndSetValue.call(self); + + if (this.state === STATE_ON) { + toggleClassOn.call(self); + } else { + toggleClassOff.call(self); + } + + /** + * is called when options changed + */ + self[internalSymbol].attachObserver( + new Observer(function () { + if (isObject(this) && this instanceof ProxyObserver) { + validateAndSetValue.call(self); + toggleClass.call(self); + } + }), + ); + + return this; + } + + /** + * updater transformer methods for pipe + * + * @return {function} + */ + [updaterTransformerMethodsSymbol]() { + return { + "state-callback": (Wert) => { + return this.state; + }, + }; + } + + /** + * @return [CSSStyleSheet] + */ + static getCSSStyleSheet() { + return [ToggleSwitchStyleSheet]; + } + + /** + * toggle switch + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * e.click() + * ``` + */ + click() { + toggleValues.call(this); + } + + /** + * toggle switch on/off + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * e.toggle() + * ``` + * + * @return {ToggleSwitch} + */ + toggle() { + this.click(); + return this; + } + + /** + * toggle switch on + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * e.toggleOn() + * ``` + * + * @return {ToggleSwitch} + */ + toggleOn() { + this.setOption("value", this.getOption("values.on")); + return this; + } + + /** + * toggle switch off + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * e.toggleOff() + * ``` + * + * @return {ToggleSwitch} + */ + toggleOff() { + this.setOption("value", this.getOption("values.off")); + return this; + } + + /** + * returns the status of the element + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * console.log(e.state) + * // ↦ off + * ``` + * + * @return {string} + */ + get state() { + return this.getOption("value") === this.getOption("values.on") + ? STATE_ON + : STATE_OFF; + } + + /** + * The current value of the Switch + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * console.log(e.value) + * // ↦ on + * ``` + * + * @return {string} + */ + get value() { + return this.state === STATE_ON + ? this.getOption("values.on") + : this.getOption("values.off"); + } + + /** + * Set value + * + * ``` + * e = document.querySelector('monster-toggle-switch'); + * e.value="on" + * ``` + * + * @property {string} value + */ + set value(value) { + this.setOption("value", value); + } + + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for( + "@schukai/monster/components/form/toggle-switch@@instance", + ); + } + + static getTag() { + return "monster-toggle-switch"; + } } /** * @private */ function initControlReferences() { - this[switchElementSymbol] = this.shadowRoot.querySelector( - `[${ATTRIBUTE_ROLE}=switch]`, - ); + this[switchElementSymbol] = this.shadowRoot.querySelector( + `[${ATTRIBUTE_ROLE}=switch]`, + ); } /** * @private */ function toggleClassOn() { - this[switchElementSymbol].classList.remove(this.getOption("classes.off")); // change color - this[switchElementSymbol].classList.add(this.getOption("classes.on")); // change color + this[switchElementSymbol].classList.remove(this.getOption("classes.off")); // change color + this[switchElementSymbol].classList.add(this.getOption("classes.on")); // change color } /** * @private */ function toggleClassOff() { - this[switchElementSymbol].classList.remove(this.getOption("classes.on")); // change color - this[switchElementSymbol].classList.add(this.getOption("classes.off")); // change color + this[switchElementSymbol].classList.remove(this.getOption("classes.on")); // change color + this[switchElementSymbol].classList.add(this.getOption("classes.off")); // change color } /** * @private */ function toggleClass() { - if (this.getOption("value") === this.getOption("values.on")) { - toggleClassOn.call(this); - } else { - toggleClassOff.call(this); - } + if (this.getOption("value") === this.getOption("values.on")) { + toggleClassOn.call(this); + } else { + toggleClassOff.call(this); + } } /** * @private */ function toggleValues() { - if (this.getOption("disabled") === true) { - return; - } + if (this.getOption("disabled") === true) { + return; + } - let callback, value; + let callback, value; - if (this.getOption("value") === this.getOption("values.on")) { - value = this.getOption("values.off"); - callback = this.getOption("actions.off"); - } else { - value = this.getOption("values.on"); - callback = this.getOption("actions.on"); - } + if (this.getOption("value") === this.getOption("values.on")) { + value = this.getOption("values.off"); + callback = this.getOption("actions.off"); + } else { + value = this.getOption("values.on"); + callback = this.getOption("actions.on"); + } - this.setOption("value", value); - this?.setFormValue(value); + this.setOption("value", value); + this?.setFormValue(value); - if (isFunction(callback)) { - callback.call(this); - } + if (isFunction(callback)) { + callback.call(this); + } - this.setOption("state", this.state); + this.setOption("state", this.state); } /** * @private */ function validateAndSetValue() { - const value = this.getOption("value"); - - const validatedValues = []; - validatedValues.push(this.getOption("values.on")); - validatedValues.push(this.getOption("values.off")); - - if (validatedValues.includes(value) === false) { - addAttributeToken( - this, - ATTRIBUTE_ERRORMESSAGE, - 'The value "' + - value + - '" must be "' + - this.getOption("values.on") + - '" or "' + - this.getOption("values.off"), - ); - this.setOption("disabled", true); - this.formDisabledCallback(true); - } else { - this.setOption("disabled", false); - this.formDisabledCallback(false); - } + const value = this.getOption("value"); + + const validatedValues = []; + validatedValues.push(this.getOption("values.on")); + validatedValues.push(this.getOption("values.off")); + + if (validatedValues.includes(value) === false) { + addAttributeToken( + this, + ATTRIBUTE_ERRORMESSAGE, + 'The value "' + + value + + '" must be "' + + this.getOption("values.on") + + '" or "' + + this.getOption("values.off"), + ); + this.setOption("disabled", true); + this.formDisabledCallback(true); + } else { + this.setOption("disabled", false); + this.formDisabledCallback(false); + } } /** @@ -425,16 +406,16 @@ function validateAndSetValue() { * @return {initEventHandler} */ function initEventHandler() { - const self = this; - self.addEventListener("keyup", function (event) { - if (event.code === "Space") { - self[switchElementSymbol].click(); - } - }); - self.addEventListener("click", function (event) { - toggleValues.call(self); - }); - return this; + const self = this; + self.addEventListener("keyup", function (event) { + if (event.code === "Space") { + self[switchElementSymbol].click(); + } + }); + self.addEventListener("click", function (event) { + toggleValues.call(self); + }); + return this; } /** @@ -442,13 +423,13 @@ function initEventHandler() { * @return {string} */ function getTemplate() { - // language=HTML - return ` + // language=HTML + return ` <div data-monster-role="control" part="control" tabindex="0"> <div class="switch" data-monster-role="switch" data-monster-attributes="data-monster-state path:value | call:state-callback"> - <div class="label on" data-monster-replace="path:labels.toggle-switch-on"></div> - <div class="label off" data-monster-replace="path:labels.toggle-switch-off"></div> + <div class="label on" data-monster-replace="path:labels.toggleSwitchOn"></div> + <div class="label off" data-monster-replace="path:labels.toggleSwitchOff"></div> <div data-monster-attributes="class path:classes.handle | suffix:\\ switch-slider"></div> </div> </div>`; diff --git a/source/components/host/collapse.mjs b/source/components/host/collapse.mjs index 937f88ef046ac94af21bb626c464d94382b95f59..accc80c086b8ef328d74a3b0f1670a9b0f7fdeb5 100644 --- a/source/components/host/collapse.mjs +++ b/source/components/host/collapse.mjs @@ -19,6 +19,6 @@ export { Collapse }; * @since 1.10.0 * @copyright schukai GmbH * @memberOf Monster.Components.Form - * @deprecated since 3.64.0 use {@link Monster.Components.Layout.Collapse} + * @deprecated since 3.64.0 use Layout.Collapse instead */ class Collapse extends NewCollapse {} diff --git a/source/components/state/log.mjs b/source/components/state/log.mjs index c98cae51109e073521eff13ba37aa9676a105e74..133f4cccd92493cd0267eee9a8c0def311aab824 100644 --- a/source/components/state/log.mjs +++ b/source/components/state/log.mjs @@ -12,19 +12,19 @@ * SPDX-License-Identifier: AGPL-3.0 */ -import { instanceSymbol } from "../../constants.mjs"; +import {instanceSymbol} from "../../constants.mjs"; import { - assembleMethodSymbol, - CustomElement, - getSlottedElements, - registerCustomElement, + assembleMethodSymbol, + CustomElement, + getSlottedElements, + registerCustomElement, } from "../../dom/customelement.mjs"; -import { LogStyleSheet } from "./stylesheet/log.mjs"; -import { Entry } from "./log/entry.mjs"; -import { validateInstance } from "../../types/validate.mjs"; +import {LogStyleSheet} from "./stylesheet/log.mjs"; +import {Entry} from "./log/entry.mjs"; +import {validateInstance} from "../../types/validate.mjs"; import "./state.mjs"; -export { Log }; +export {Log}; /** * @private @@ -71,118 +71,138 @@ const emptyStateElementSymbol = Symbol("emptyStateElement"); * @memberOf Monster.Components.State * @summary Log is a control to show a log message. */ + + +/** + * A Log component + * + * @fragments /fragments/components/layout/collapse/ + * + * @example /examples/components/layout/collapse-simple + * + * @since 3.74.0 + * @copyright schukai GmbH + * @summary A Log component to show a log message. + */ class Log extends CustomElement { - /** - * - * @return {Monster.Components.State.State} - */ - [assembleMethodSymbol]() { - super[assembleMethodSymbol](); - - initControlReferences.call(this); - initEventHandler.call(this); - } - - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/component-state/log"); - } - - /** - * 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 {Object} labels Labels - * @property {string} labels.nothingToReport Label for empty state - */ - get defaults() { - return Object.assign({}, super.defaults, { - templates: { - main: getTemplate(), - }, - - labels: { - nothingToReport: "There is nothing to report yet.", - }, - - entries: [], - }); - } - - connectedCallback() { - super.connectedCallback(); - - const slottedElements = getSlottedElements.call(this); - if (slottedElements.size > 0) { - this[emptyStateElementSymbol].style.display = "none"; - } - } - - /** - * Clear the log - * - * @return {Log} - */ - clear() { - this[logElementSymbol].innerHTML = ""; - this[emptyStateElementSymbol].style.display = "block"; - return this; - } - - addEntry(entry) { - validateInstance(entry, Entry); - - const entries = this.getOption("entries"); - entries.push(entry); - - /** this field is not used, but triggers a change event */ - this.setOption("length", entries.length - 1); - - return this; - } - - /** - * Add a log message - * - * @param {string} message - * @return {Log} - */ - addMessage(message, date) { - if (!date) { - date = new Date(); - } - - this.addEntry( - new Entry({ - message: message, - date: date, - }), - ); - - return this; - } - - /** - * - * @return {string} - */ - static getTag() { - return "monster-log"; - } - - /** - * @return {CSSStyleSheet[]} - */ - static getCSSStyleSheet() { - return [LogStyleSheet]; - } + /** + * @return {void} + */ + [assembleMethodSymbol]() { + super[assembleMethodSymbol](); + + initControlReferences.call(this); + initEventHandler.call(this); + } + + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/components/state/log@@instance"); + } + + /** + * 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 {Object} labels Labels + * @property {string} labels.nothingToReport Label for empty state + */ + get defaults() { + return Object.assign({}, super.defaults, { + templates: { + main: getTemplate(), + }, + + labels: { + nothingToReport: "There is nothing to report yet.", + }, + + entries: [], + }); + } + + /** + * @return {void} + */ + connectedCallback() { + super.connectedCallback(); + + const slottedElements = getSlottedElements.call(this); + if (slottedElements.size > 0) { + this[emptyStateElementSymbol].style.display = "none"; + } + } + + /** + * Clear the log + * + * @return {Log} + */ + clear() { + this[logElementSymbol].innerHTML = ""; + this[emptyStateElementSymbol].style.display = "block"; + return this; + } + + /** + * Add an entry to the log + * @param entry + * @returns {Log} + */ + addEntry(entry) { + validateInstance(entry, Entry); + + const entries = this.getOption("entries"); + entries.push(entry); + + /** this field is not used, but triggers a change event */ + this.setOption("length", entries.length - 1); + + return this; + } + + /** + * Add a log message + * @param message + * @param date + * @returns {Log} + */ + addMessage(message, date) { + if (!date) { + date = new Date(); + } + + this.addEntry( + new Entry({ + message: message, + date: date, + }), + ); + + return this; + } + + /** + * + * @return {string} + */ + static getTag() { + return "monster-log"; + } + + /** + * @return {CSSStyleSheet[]} + */ + static getCSSStyleSheet() { + return [LogStyleSheet]; + } } /** @@ -191,43 +211,37 @@ class Log extends CustomElement { * @throws {Error} no shadow-root is defined */ function initControlReferences() { - if (!this.shadowRoot) { - throw new Error("no shadow-root is defined"); - } - - this[logElementSymbol] = this.shadowRoot.querySelector( - "[data-monster-role=control]", - ); - this[emptyStateElementSymbol] = this.shadowRoot.querySelector( - "[data-monster-role=empty-state]", - ); + if (!this.shadowRoot) { + throw new Error("no shadow-root is defined"); + } + + this[logElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=control]", + ); + this[emptyStateElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=empty-state]", + ); } /** * @private */ function initEventHandler() { - if (!this.shadowRoot) { - throw new Error("no shadow-root is defined"); - } - - this.shadowRoot.addEventListener("slotchange", (event) => { - const slottedElements = getSlottedElements.call(this); - - if (slottedElements.size > 0) { - this[emptyStateElementSymbol].style.display = "none"; - } else { - this[emptyStateElementSymbol].style.display = "block"; - } - }); - - // self[buttonEventHandlerSymbol] = (event) => { - // self.toggle(); - // } - // - // self[buttonElementSymbol].addEventListener('click', self[buttonEventHandlerSymbol]); - - return this; + if (!this.shadowRoot) { + throw new Error("no shadow-root is defined"); + } + + this.shadowRoot.addEventListener("slotchange", (event) => { + const slottedElements = getSlottedElements.call(this); + + if (slottedElements.size > 0) { + this[emptyStateElementSymbol].style.display = "none"; + } else { + this[emptyStateElementSymbol].style.display = "block"; + } + }); + + return this; } /** @@ -235,8 +249,8 @@ function initEventHandler() { * @return {string} */ function getTemplate() { - // language=HTML - return ` + // language=HTML + return ` <template id="entry"> <li data-monster-role="entry"> <span></span> diff --git a/source/components/state/state.mjs b/source/components/state/state.mjs index 02b8dc5732f29acd7ee0d931875769bd77d56706..30401ab19116b27541c8b07430804e3fb5824e45 100644 --- a/source/components/state/state.mjs +++ b/source/components/state/state.mjs @@ -29,44 +29,20 @@ export { State }; export const stateElementSymbol = Symbol("state"); /** - * States tell users that there’s a state. that s it! + * A state component * - * <img src="./images/state.png"> + * @fragments /fragments/components/state/state/ * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-state />` directly in the HTML or using - * Javascript via the `document.createElement('monster-state');` method. - * - * ```html - * <monster-state></monster-state> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import {State} from '@schukai/component-state/source/state.js'; - * document.createElement('monster-state'); - * ``` - * - * @externalExample ../../../example/components/state/state.mjs - * @startuml state.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * CustomControl <|-- State - * @enduml + * @example /examples/components/state/state-simple * * @since 1.5.0 * @copyright schukai GmbH - * @memberOf Monster.Components.State - * @summary States tell users that there’s a state. that s it! - */ + * @summary States tell users that there’s a state. That's it! + * @summary The state control is used in the log control, among other things. + **/ class State extends CustomControl { /** - * - * @return {Monster.Components.State.State} + * @return {void} */ [assembleMethodSymbol]() { super[assembleMethodSymbol](); @@ -77,7 +53,7 @@ class State extends CustomControl { * @returns {symbol} */ static get [instanceSymbol]() { - return Symbol.for("@schukai/component-state/state"); + return Symbol.for("@schukai/monster/components/state/state@@instance"); } /**