Skip to content
Snippets Groups Projects
Select Git revision
  • 4132c09d965d94d2dfe7c7203a093162bf41fd77
  • master default protected
  • 1.2.4
  • 1.2.3
  • 1.2.2
  • 1.2.1
  • 1.2.0
  • v1.1.0
8 results

09_server.go

Blame
  • state-button.mjs 5.36 KiB
    /**
     * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
     * Node module: @schukai/monster
     * This file is licensed under the AGPLv3 License.
     * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
     */
    import { instanceSymbol } from "../../constants.mjs";
    import { registerCustomElement } from "../../dom/customelement.mjs";
    import { isInteger } from "../../types/is.mjs";
    import { validateInstance, validateString } from "../../types/validate.mjs";
    import { Button } from "./button.mjs";
    import { StateButtonStyleSheet } from "./stylesheet/state-button.mjs";
    import { getStateInstanceFor, State } from "./types/state.mjs";
    
    export { StateButton };
    
    /**
     * This CustomControl creates a button element with a variety of options.
     *
     * <img src="./images/state-button.png">
     *
     * 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-button />` directly in the HTML or using
     * Javascript via the `document.createElement('monster-state-button');` method.
     *
     * ```html
     * <monster-state-button></monster-state-button>
     * ```
     *
     * Or you can create this CustomControl directly in Javascript:
     *
     * ```js
     * import {StateButton} from '@schukai/component-form/source/state-button.js';
     * document.createElement('monster-state-button');
     * ```
     *
     * The `data-monster-button-class` attribute can be used to change the CSS class of the button.
     *
     * @startuml state-button.png
     * skinparam monochrome true
     * skinparam shadowing false
     * HTMLElement <|-- CustomElement
     * CustomElement <|-- CustomControl
     * CustomControl <|-- Button
     * Button <|-- StateButton
     * @enduml
     *
     * @since 1.5.0
     * @copyright schukai GmbH
     * @memberOf Monster.Components.Form
     * @summary A state button with icons
     */
    class StateButton extends Button {
    	/**
    	 * This method is called by the `instanceof` operator.
    	 * @returns {symbol}
    	 * @since 2.1.0
    	 */
    	static get [instanceSymbol]() {
    		return Symbol.for(
    			"@schukai/monster/components/form/state-button@@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} states Available status
    	 * @property {Monster.Components.Form.Types.State} states.successful= successful
    	 * @property {Monster.Components.Form.Types.State} states.activity= activity
    	 * @property {Monster.Components.Form.Types.State} states.failed= failed
    	 * @property {Monster.Components.Form.Types.State} current current status
    	 * @property {Monster.Components.Form~exampleActionCallback} actions.click
    	 * @extends {Button}
    	 * @see {@link https://github.com/twbs/icons/blob/main/LICENSE.md|Bootstrap icons license}
    	 */
    	get defaults() {
    		return Object.assign({}, super.defaults, {
    			templates: {
    				main: getTemplate(),
    			},
    			states: {
    				successful: getStateInstanceFor("successful"),
    				activity: getStateInstanceFor("activity"),
    				failed: getStateInstanceFor("failed"),
    			},
    			current: getStateInstanceFor("stateless"),
    		});
    	}
    
    	/**
    	 * This method sets the current state of the button.
    	 * If a timeout is set, the state is automatically removed after the
    	 * specified time.
    	 *
    	 * @since 3.18.0 a previously set timeout is cleared
    	 *
    	 * @param {state} state
    	 * @param {number} timeout
    	 * @return {Monster.Components.Form.StateButton}
    	 * @throws {TypeError} value is not a string
    	 * @throws {TypeError} value is not an instance
    	 */
    	setState(state, timeout) {
    		const timeoutSymbol = Symbol.for("timeout");
    		if (this[timeoutSymbol] !== undefined) {
    			clearTimeout(this[timeoutSymbol]);
    			delete this[timeoutSymbol];
    		}
    
    		const obj = this.getOption(`states.${validateString(state)}`);
    		if (obj === undefined) {
    			throw new Error("not found");
    		}
    
    		this.setOption("current", validateInstance(obj, State));
    
    		if (isInteger(timeout) && timeout > 0) {
    			this[timeoutSymbol] = setTimeout(() => {
    				this.removeState();
    				delete this[timeoutSymbol];
    			}, timeout);
    		}
    
    		return this;
    	}
    
    	/**
    	 *
    	 * @return {Monster.Components.Form.StateButton}
    	 */
    	removeState() {
    		this.setOption("current", getStateInstanceFor("stateless"));
    		return this;
    	}
    
    	/**
    	 * @return {Monster.Components.Form.Types.State|undefined}
    	 */
    	getState() {
    		return this.getOption("current");
    	}
    
    	/**
    	 *
    	 * @return {string}
    	 */
    	static getTag() {
    		return "monster-state-button";
    	}
    
    	/**
    	 *
    	 * @return {Array<CSSStyleSheet>}
    	 */
    	static getCSSStyleSheet() {
    		const styles = Button.getCSSStyleSheet();
    		styles.push(StateButtonStyleSheet);
    		return styles;
    	}
    }
    
    /**
     * @private
     * @return {string}
     */
    function getTemplate() {
    	// language=HTML
    	return `<div data-monster-role="control" part="control">
        <button data-monster-attributes="disabled path:disabled | if:true, class path:classes.button"
                data-monster-role="button"
                part="button">
            <div data-monster-role="label" data-monster-replace="path:labels.button"></div>
            <div data-monster-role="state"
    			 data-monster-attributes="class path:current.state"
    			 data-monster-replace="path:current.presentation"></div>
        </button>
    </div>`;
    }
    
    registerCustomElement(StateButton);