Something went wrong on our end
Select Git revision
09_server.go
-
Volker Schukai authoredVolker Schukai authored
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);