Welcome to the Monster Saga

Imagine you’re in the middle of a coding quest, navigating through a labyrinth of JavaScript and CSS. Just when the complexity seems to be a never-ending loop, along comes Monster, your new coding ally, ready to streamline your frontend adventure.

For those eager to start, begin your journey here.

Access the API Documentation here and explore the full source code here.

Introducing Monster

Monster isn’t just another JavaScript library. It’s the sidekick you didn’t know you needed, ready to enhance your frontend endeavors. It’s designed to blend seamlessly into your project, empowering you without overshadowing your existing setup.

Why Monster?

Embark on a journey with Monster, and there’s no turning back to the mundane. In the ‘Getting Started’ section, we’ll unveil how to welcome Monster into your project, transforming your frontend development journey.

Embrace Freedom

Monster is not just free; it’s liberating. It’s customizable to its core, adaptable to any project you’re working on, be it an e-commerce platform or a personal portfolio.

Flexibility and Compatibility

Monster’s true beauty lies in its adaptability. It stands strong on its own with no dependencies but also collaborates smoothly with other libraries and frameworks, such as jQuery and Bootstrap.

Core Design Promises

Monster comes with a set of core design goals that it pledges to uphold:

  • Reusability: Craft web components once and reuse them across your application, minimizing code duplication and boosting maintainability.

  • Modularity: Assemble complex UIs from smaller, modular components, enhancing the development process.

  • Interoperability: Built on web standards, Monster ensures compatibility across different technologies and frameworks, facilitating integration into existing projects.

  • Performance: Monster is lightweight yet powerful, designed for swift rendering and updates, enhancing your application’s performance.

  • Adaptability: With widespread adoption and standards compliance, you’ll find a robust support community and ample resources for guidance.

  • Flexibility: Free from framework constraints, Monster allows you to choose the best tools for your project needs.

With MonsterJS and its web components, you’re set to elevate the scalability, maintainability, and performance of your web applications.

Ready to revolutionize your frontend development experience with Monster? Stay tuned and embark on this transformative coding journey!

Now, let’s dive into the Getting Started section to.

Getting Started

Embarking on your Monster journey requires a basic understanding of HTML, CSS, and JavaScript. If you’re new to frontend development, consider having a beginner’s guide handy as you explore Monster.

For additional support, join the conversation on Stack Overflow by tagging your queries with “javascript” and “monster”. Alternatively, engage with our community right here in this ChatGPT Monster Chat for tailored assistance.

Monster in Your Browser

Dive into Monster with just a text editor and a browser. Start by crafting an index.html file with the following snippet:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Monster Magic!</title>
</head>
<body>

<div>Monster Version:
    <span id="version"></span>
</div>

<script type="module">
    import { Version } from 
           'https://cdn.skypack.dev/@schukai/monster@latest/source/types/version.js';
    document.getElementById('version')
            .textContent = new Version('1.0.0').toString();
</script>

</body>
</html>

Launch this file in your browser to see Monster’s ‘Version’ class in action, displaying a version number on your page.

Well done! You’ve just harnessed a slice of Monster’s capabilities. Each Monster component operates independently, allowing you to cherry-pick the features you need. Or, you can embrace Monster in its entirety for a comprehensive toolkit.

Monster is accessible through CDNs like jsDelivr and Skypack or can be integrated via NPM or git repositories, offering versatility without dependencies, making it compatible with frameworks like Bootstrap or jQuery.

Monster via NPM

To install Monster with NPM, ensure you have Node.js and NPM installed:

  1. Launch your terminal or command prompt.
  2. Execute: npm install @schukai/monster

This command fetches the latest Monster version. To target a specific release, append @version_number to the package name.

After installation, you can incorporate Monster modules into your project as follows:

import {Version} from '@schukai/monster/source/types/version.js';
document.getElementById('version')
        .textContent = new Version('1.0.0').toString();

Feel free to use yarn or pnpm as alternatives to NPM for your package management needs.

Style

The CSS Style guide for Monster is a set of guidelines and best practices for writing and organizing CSS code. It is designed to help developers maintain a consistent and organized codebase, making it easier to read, understand, and modify. The style guide covers a wide range of topics, including naming conventions, code organization, and performance optimization. Following the guidelines in this style guide will help ensure that your CSS code is clean, maintainable, and efficient.

The following example shows how to include the stylesheets independently of the rest of the document.

<!-- here we define the desired content -->
<template id="contenttemplate">
    <p>this is an example</p>
</template>

<script type="module">

    // here we import the stylesheets
    import {NormalizeStyleSheet} from
                '@schukai/monster@latest/source/components/stylesheet/normalize.mjs';
    import {PropertyStyleSheet} from 
                '@schukai/monster@latest/source/components/stylesheet/property.mjs';
    import {ColorStyleSheet} from 
                '@schukai/monster@latest/source/components/stylesheet/color.mjs';
    import {ThemeStyleSheet} from 
                '@schukai/monster@latest/source/components/stylesheet/theme.mjs';
    
    // we create a node
    const node = document.createElement('div');
    
    // we attach the shadow root to the node
    const shadow = node.attachShadow({ mode: 'open' });
    
    // we clone the template and attach it to the shadow root
    const template = document.getElementById('contenttemplate');
    shadow.appendChild(template.content.cloneNode(true));
     
    // we attach the stylesheets to the shadow root
    shadow.adoptedStyleSheets = [
        NormalizeStyleSheet, 
        PropertyStyleSheet,
        ColorStyleSheet,
        ThemeStyleSheet
    ];
    
    // we attach the node to the body
    document.body.appendChild(node);

</script>

Typography

This page is a demonstration of the elements that can be formatted using Monster. It is not intended to be a comprehensive guide to typography, but rather a reference of the styles that are available.

Level (z-index)

The z-index property specifies the stack order of an element. An element with greater stack order is always in front of an element with a lower stack order.

CSS-Properties

Property
--monster-z-index-default
--monster-z-index-outline
--monster-z-index-dropdown
--monster-z-index-dropdown-overlay
--monster-z-index-sticky
--monster-z-index-sticky-overlay
--monster-z-index-fixed
--monster-z-index-fixed-overlay
--monster-z-index-modal-backdrop
--monster-z-index-modal-backdrop-overlay
--monster-z-index-offcanvas
--monster-z-index-offcanvas-overlay
--monster-z-index-modal
--monster-z-index-modal-overlay
--monster-z-index-popover
--monster-z-index-popover-overlay
--monster-z-index-tooltip
--monster-z-index-tooltip-overlay

Media Queries (Breakpoints)

Media queries are used to apply different styles to a document depending on the size of the screen. Media queries are defined in the @media rule. The @media rule is used inside a style sheet to apply different styles for different media types/devices.

More information about media queries can be found on MDN.

In Monster we use the following media queries:

ClassFromTo
viewport00480px
viewport-40480px
viewport-70768px
viewport-90992px
viewport-1201200px
viewport4480px
viewport7768px
viewport9992px
viewport121200px
viewport4-7480px768px
viewport7-9768px992px
viewport9-12992px1200px

In the following graphic you can see the different media queries and the corresponding mixins.

Skeleton (loading animation)

Skeleton is a CSS class that provides a loading animation for elements. It can be used to indicate that an element is loading or that the user has to wait for the content to be loaded. The monster-skeleton-col-xxx classes define the look of the skeleton. The xx defines the width of the skeleton in percent. monster-skeleton-col-100 is the widest skeleton and monster-skeleton-col-10 is the narrowest skeleton.

The monster-skeleton-animated class defines the animation.

<div class="monster-skeleton-col-100 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-90 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-80 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-70 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-60 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-60 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-40 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-30 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-20 monster-skeleton-animated">.</div>
<div class="monster-skeleton-col-10 monster-skeleton-animated">.</div>

Icons

IconClassDescription
monster-icon-primary-1-infoInfo icon
monster-icon-primary-1-positivPositiv icon
monster-icon-primary-1-negativNegativ icon
monster-icon-primary-1-warningWarning icon
monster-icon-primary-1-neutralNeutral icon
monster-icon-primary-1-questionQuestion icon
monster-icon-primary-1-plusPlus icon
monster-icon-primary-1-dashDash icon
monster-icon-primary-1-gearGear icon
monster-icon-primary-1-homeHome icon
monster-icon-primary-1-counterclockwiseCounterclockwise icon
monster-icon-secondary-1-infoInfo icon
monster-icon-secondary-1-positivPositiv icon
monster-icon-secondary-1-negativNegativ icon
monster-icon-secondary-1-warningWarning icon
monster-icon-secondary-1-neutralNeutral icon
monster-icon-secondary-1-questionQuestion icon
monster-icon-secondary-1-plusPlus icon
monster-icon-secondary-1-dashDash icon
monster-icon-secondary-1-gearGear icon
monster-icon-secondary-1-homeHome icon
monster-icon-secondary-1-counterclockwiseCounterclockwise icon
monster-icon-tertiary-1-infoInfo icon
monster-icon-tertiary-1-positivPositiv icon
monster-icon-tertiary-1-negativNegativ icon
monster-icon-tertiary-1-warningWarning icon
monster-icon-tertiary-1-neutralNeutral icon
monster-icon-tertiary-1-questionQuestion icon
monster-icon-tertiary-1-plusPlus icon
monster-icon-tertiary-1-dashDash icon
monster-icon-tertiary-1-gearGear icon
monster-icon-tertiary-1-homeHome icon
monster-icon-tertiary-1-counterclockwiseCounterclockwise icon
monster-icon-success-1Success icon
monster-icon-success-2Success icon
monster-icon-success-3Success icon
monster-icon-success-4Success icon
monster-icon-warning-1Warning icon
monster-icon-warning-2Warning icon
monster-icon-warning-3Warning icon
monster-icon-warning-4Warning icon
monster-icon-error-1Error icon
monster-icon-error-2Error icon
monster-icon-error-3Error icon
monster-icon-error-4Error icon

Usage

This is an <span class="monster-icon-primary-1-info"></span>-Icon.

Create own icon with mixin

@import "@schukai/monster/source/components/style/mixin/icon.pcss";

@mixin icon my-icon {
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' " +
        "width='16' height='16' fill='currentColor' class='bi bi-dash-circle' " +
        "viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0" +
        "1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/%3E%3Cpath d='M4 8a.5.5 0 0 1 " +
        ".5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z'/%3E%3C/svg%3E");
}

Spacing (margin, padding)

CSS-Properties

ClassValue
--monster-space-00
--monster-space-12px
--monster-space-24px
--monster-space-36px
--monster-space-410px
--monster-space-516px
--monster-space-626px
--monster-space-742px

Classes

  • monster-margin-<0, 1, 2, 3, 4, 5, 6, 7>
  • monster-padding-<0, 1, 2, 3, 4, 5, 6, 7>
  • monster-margin-<start, end, top, bottom>-<0, 1, 2, 3, 4, 5, 6, 7>
  • monster-padding-<start, end, top, bottom>-<0, 1, 2, 3, 4, 5, 6, 7>

Examples

<div class="monster-padding-5"></div>
<div class="monster-padding-start-5"></div>

Form

The form is the most important element for user interaction. It is used to collect data from the user and send it to the server.

In the following example, the form is styled with the monster components.

<main class="monster-color-primary-1">
    <form class="monster-form">
        <label for="msg">Your message:
            <textarea id="msg2" name="user_message"></textarea>
        </label>
        <fieldset>
            <legend>Personal Information</legend>
            <label for="name">from
                <input type="text" id="na3me" name="user_name"/></label>
            <label for="mail">reply:
                <input type="email" id="ma3il" name="user_email"/>
            </label>
            <label for="msg">Your message:
                <textarea id="ms1g" name="user_message"></textarea>
            </label>
        </fieldset>
        <fieldset>
            <legend>Detasil Information</legend>
            <div id="from">
                <label for="name">from:</label>
                <input type="text" id="name" name="user_name"/>
            </div>
            <div id="reply">
                <label for="mail">reply:</label>
                <input type="email" id="mail" name="user_email"/>
            </div>
            <div id="message">
                <label for="msg">Your message:</label>
                <textarea id="msg" name="user_message"></textarea>
            </div>
            <div class="button">
                <button type="submit">Send your message</button>
            </div>
        </fieldset>
    </form>
</main>

Here you can see the result in the browser:

Personal Information
Detasil Information

Spinner

The spinner is a CSS class that provides a loading animation. So that the spinner can be used in different situations, it is possible to set the size and the theme and the spinner is not a component.

Usage

<div class="monster-spinner"></div>

Size

You must set the width and height of the spinner.

<div class="monster-spinner" style="width: 100px; height: 100px;"></div>

Themes

Therefor the spinner can be used in different themes.

<div style="display: flex; justify-content: space-around; align-items: center;">
    <div class="monster-spinner monster-theme-primary-1" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-primary-2" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-primary-3" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-primary-4" style="width: 100px; height: 100px;"></div>
</div>

This will result in the following output:

The themes can be used in combination with the monster-theme class.

<div class="monster-theme-secondary-4" style="display: flex; justify-content: space-around; align-items: center;">
    <div class="monster-spinner monster-theme-secondary-1" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-secondary-2" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-secondary-3" style="width: 100px; height: 100px;"></div>
    <div class="monster-spinner monster-theme-secondary-4" style="width: 100px; height: 100px;"></div>
</div>

Info

To ensure that the spinner also works well in dark mode, the right combination must always be selected.

Table

A table is a good way to display data in a structured way.


<div class="monster-table-container">
    <table class="monster-table">
        <thead>
        <tr>
            <th>Name</th>
            <th>Number</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>Jackie</td>
            <td>012345</td>
        </tr>
        <tr>
            <td>Lucy</td>
            <td>112346</td>
        </tr>
        <tr>
            <td>David</td>
            <td>493029</td>
        </tr>
        <tr>
            <td>Kerry</td>
            <td>395499</td>
        </tr>
        <tr>
            <td>Steve</td>
            <td>002458</td>
        </tr>
        </tbody>
    </table>
</div>

Now you can see the result in the browser:

Name Number
Jackie 012345
Lucy 112346
David 493029
Kerry 395499
Steve 002458

Color

Color is part of the visual language of a design system. It is used to communicate meaning, organize elements, and create visual interest in designs. Color is also used to create contrast between elements, so that users can easily scan and interact with content.

Theme Colors

The theme colors are listed below. The values must be prefixed with monster-theme-. The colors contain a definition for the background and the text. The color scheme is optimized for display in light and dark mode.

primary-1
primary-2
primary-3
primary-4
primary-disabled-1
primary-disabled-2
primary-disabled-3
primary-disabled-4
secondary-1
secondary-2
secondary-3
secondary-4
tertiary-1
tertiary-2
tertiary-3
tertiary-4
destructive-1
destructive-2
destructive-3
destructive-4
success-1
success-2
success-3
success-4
warning-1
warning-2
warning-3
warning-4
error-1
error-2
error-3
error-4
selection-1
selection-2
selection-3
selection-4

Special colors

<div class="monster-color-neutral-1"></div>

The special colors are listed below. The values must be prefixed with monster-color-. The colors contain a definition for the background or the text.

neutral-1
neutral-2
neutral-3 + bg-color-primary-3
neutral-4 + bg-color-primary-4
neutral-1 + bg-color-secondary-1
neutral-1 + bg-color-secondary-2
neutral-1 + bg-color-secondary-3
neutral-4 + bg-color-secondary-4
neutral-1 + bg-color-secondary-1 + border-primary
neutral-1 + bg-color-secondary-2 + border-color-2
neutral-1 + bg-color-secondary-3 + border-color-3
neutral-4 + bg-color-secondary-4 + border-color-4

Border colors

<div class="monster-border-primary-1"></div>

The border colors are listed below. The values must be prefixed with monster-. The colors contain a definition for the border including the border width and the border style.

border-primary-1
border-primary-2
border-primary-3
border-primary-4
border-secondary-1
border-secondary-2
border-secondary-3
border-secondary-4
border-tertiary-1
border-tertiary-2
border-tertiary-3
border-tertiary-4

Color Properties

References

Cards

A card is a flexible and extensible content container.

<div class="cards">
    <div class="card">
        <img src="./bg.jpg" alt="">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
            labore et dolore magna aliquyam erat, sed diam voluptua.</p>
        <button>button</button>
    </div>
    <div class="card">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
            labore et dolore magna aliquyam erat, sed diam voluptua.</p>
        <button>button</button>
    </div>
    <div class="card">
        <button>button</button>
        <img src="./bg.jpg" alt="">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
            labore et dolore magna aliquyam erat, sed diam voluptua.</p>
        <button>button</button>
    </div>
    <div class="card">
        <h1>Lorem ipsum </h1>
        <button>button</button>
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
            labore et dolore magna aliquyam erat, sed diam voluptua.</p>
        <button>button</button>
    </div>
</div>

Button


Button group

A button group is a vertical list of buttons. It is used to group buttons together.

<div class="monster-button-group">
    <button class="">button</button>
    <button class="monster-button-outline-primary">
        monster-button-outline-primary
    </button>
</div>

Button bar

A button bar is a horizontal list of buttons. It is used to group button groups together.

<div class="monster-button-bar">
    <div class="monster-button-group">
        <button class="">button</button>
        <button class="monster-button-outline-primary">
            monster-button-outline-primary
        </button>
    </div>
    <div class="monster-button-group monster-margin-start-4">
        <button class="monster-button-outline-secondary">
            monster-button-outline-secondary
        </button>
        <button class="monster-button-outline-tertiary">
            monster-button-outline-tertiary
        </button>
    </div>
</div>

Badge

Badges are used to highlight an item’s status for quick recognition. They can be used to indicate the status of an item or to draw attention to an item.

monster-badge-primary
monster-badge-primary-pill
monster-badge-secondary
monster-badge-secondary-pill
monster-badge-tertiary
monster-badge-tertiary-pill
monster-badge-destructive
monster-badge-destructive-pill
monster-badge-success
monster-badge-success-pill
monster-badge-warning
monster-badge-warning-pill
monster-badge-error
monster-badge-error-pill

Display & Visibility

The following classes can be used to set the display and visibility properties of an element.

ClassProperty
.blockdisplay: block;
.inlinedisplay: inline;
.inline-blockdisplay: inline-block;
.griddisplay: grid;
.inline-griddisplay: inline-grid;
.flexdisplay: flex;
.inline-flexdisplay: inline-flex;
.hidden, .none, .hidedisplay: none;
.visiblevisibility: visible;
.invisiblevisibility: hidden;

Build CSS styles

The styles are defined as PostCSS files. For this reason, you must parse these files with PostCSS to generate CSS or Javascript files from them.

The following tool is recommended for this purpose: PostCSS.

The following plugins are used in the build script:

#!/usr/bin/env node

import fs from 'fs';
import postcss from 'postcss'; // https://postcss.org/

// https://github.com/postcss/postcss-import
import importCss from 'postcss-import';

// https://github.com/postcss/postcss-mixins
import mixins from 'postcss-mixins';

// https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting
import nesting from 'postcss-nesting';

// https://github.com/csstools/postcss-normalize
import normalize from 'postcss-normalize';

// https://github.com/notiv-nt/postcss-fluid
import fluid from 'postcss-fluid';

// https://github.com/antyakushev/postcss-for
import forStruct from 'postcss-for';

// https://github.com/madeleineostoja/postcss-responsive-type
import responsiveType from 'postcss-responsive-type';

// https://github.com/postcss/autoprefixer
import autoprefixer from 'autoprefixer';

// https://cssnano.co/
import cssnano from 'cssnano'; 

const sourceFile = 'source/main.pcss';

fs.readFile(sourceFile, (err, css) => {
    postcss([
        importCss(), // This plugin should probably 
                     // be used as the first plugin 
                     // of your list.
        mixins,
        nesting(),

        normalize,
        fluid,

        forStruct,
        responsiveType,
        autoprefixer,
        cssnano,
    ])
        .process(css, {from: sourceFile})
        .then(result => {
           console.log(result.css)
        }).catch(err => {
           console.log(err)
        })
})

The plugins do different things. For example, the postcss-normalize creates a CSS file that contains the CSS reset.

By using of the import plugin you can use the CSS instructions and mixin from monster.

@import "@schukai/monster/source/components/style/mixin/button.pcss";

button {
    @mixin button;
}

Read the documentation for each plugin for more details.

You can also use postcss-cli.

npm i -D postcss postcss-cli
postcss src/app.css -o dest/app.css -m

References

  • https://github.com/postcss/postcss-cli
  • https://postcss.org/
  • https://github.com/postcss/postcss-import
  • https://github.com/postcss/postcss-mixins
  • https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting
  • https://github.com/csstools/postcss-normalize
  • https://github.com/notiv-nt/postcss-fluid
  • https://github.com/antyakushev/postcss-for
  • https://github.com/madeleineostoja/postcss-responsive-type
  • https://github.com/postcss/autoprefixer
  • https://cssnano.co/

DOM

The Document Object Model (DOM) is a programming interface for HTML and XML documents. It represents the structure of a document as a tree-like structure, where each node in the tree represents an element, attribute, or text content in the document.

JavaScript provides a set of functions and classes for working with the DOM, including methods for creating, modifying, and querying elements, as well as handling events.

JavaScript’s DOM functions and classes can be divided into several categories:

  • Document: this includes the Document object, which represents the entire HTML or XML document and provides methods for manipulating the structure and content of the document.
  • Element: This includes classes such as HTMLElement, which represent an HTML element and provide methods for manipulating the attributes, content, and style of the element.
  • Event: This includes classes such as Event and EventTarget, which provide methods for processing and responding to events such as clicks, mouse movements, and keystrokes.
  • Node: This includes classes such as Node, which represent a node in the DOM tree and provide methods for processing the node’s parent and child nodes.
  • Selector: These include functions such as document.getElementById(), document.querySelector(), and document.querySelectorAll(), which are used to select elements from the DOM by their ID, class, or tag name.

By using these functions and classes, developers can create dynamic and interactive web pages and develop a variety of web applications.

In this section, we will delve deeper into the functions and classes provided by Monster and provide examples of their usage for manipulating the DOM and handling events.

Form Handling

Forms can be bound to a structure just like other structures via the updater class.

Suppose we have an html form with some controls.

<div>
    <form id="form1">
        <input type="checkbox" name="checkbox">
        <input type="text" name="text">
        <input type="radio" name="radio">

        <select name="select">
            <option>value1</option>
            <option>value2</option>
        </select>

        <textarea name="textarea">
        </textarea>

        <input type="button" name="button">

    </form>
</div>

A new updater is created in this case via the following call.

const updater = new Updater(document.getElementById('form1'));

With the method Updater.getSubject() you can get the structure of the updater. If you want to use an already defined structure, you can pass it to the updater as a second parameter.

let subject =  updater.getSubject();
console.log(subject);

Now we want a click on the checkbox to be mapped in the data structure.

To do this we need to extend the html with the data-monster-bind attribute.

The values or states of controls are mapped to the data structure via this binding.

<div>
    <form id="form1">
        <!-- data-monster-bind added -->
        <input type="checkbox" name="checkbox" data-monster-bind="path:state">
    </form>
</div>

In this case the status of the checkbox is mapped to the key state. If the checkbox is selected the field state contains the value on , otherwise state is undefined.

If you want to use another value instead of on, you can set the attribute value.

<input type="checkbox" name="checkbox" value="checked" data-monster-bind="path:state">

To see the magic the handling must still be switched on.

updater.enableEventProcessing()

Monster Templating

Welcome to the Monster Templating Guide, where we explore the dynamic and intuitive DOM-based templating system designed to enhance your HTML with powerful, data-driven components. Monster leverages modern web technologies to offer a seamless integration between your data and the document object model (DOM), enabling real-time updates and manipulations with minimal code.

Getting Started

Importing the Updater Class

To utilize Monster’s templating features, begin by importing the Updater class from Monster’s CDN:

import {Updater} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js';

Preparing the HTML Document

You can integrate Monster’s data-binding attributes directly into your HTML or dynamically via JavaScript. Here’s how you can dynamically insert an HTML element with Monster’s data-binding attribute:

const body = document.querySelector('body');
const headline = document.createElement('h1');
headline.setAttribute('data-monster-replace', 'path:headline');
body.appendChild(headline);

Alternatively, insert the following tag directly into your HTML document:

<h1 data-monster-replace="path:headline"></h1>

Setting Up Data Binding

Define the data structure you want to bind to your HTML element:

let obj = {
    headline: "Go!",
};

Initialize the updater with your document’s body (or any parent HTML element) and the data object:

const updater = new Updater(body, obj);

To monitor and reflect changes in the data structure in real-time, retrieve the proxy object:

const subject = updater.getSubject();

Activate the updater to start data synchronization:

updater.run();

Demonstrate dynamic data updates with an example:

setTimeout(() => {
    subject['headline'] = "Hello!";
}, 1000);

Templating Features

Monster’s templating engine supports a variety of operations to manipulate the DOM based on your data.

Content Replacement

To replace the content of an HTML element, use the data-monster-replace attribute. This attribute accepts a path to your data or static values, optionally applying transformations:


<div data-monster-replace="static:HELLO | tolower"></div>

This results in:


<div>hello</div>

Attribute Manipulation

Add or modify HTML attributes through the data-monster-attributes attribute, specifying the attribute name followed by a pipe (|) and the desired operations:


<div data-monster-attributes="id static:myid, class static:myclass">hello</div>

Element Removal

Use data-monster-remove to permanently remove an HTML element from the document:


<div data-monster-remove></div>

Dynamic Element Insertion

Insert elements dynamically with data-monster-insert, specifying a template ID and data path:


<ol data-monster-insert="myid path:a"></ol>

Define a corresponding template:


<template id="myid">
    <li data-monster-replace="path:myid | index:id | tostring | prefix:x"></li>
</template>

Data Binding for Input Elements

Bind input elements to your data structure with data-monster-bind, ensuring real-time synchronization:

<input type="text" data-monster-bind="path:a.b">

Specify the data type with data-monster-bind-type for accurate data representation:

<input type="number" data-monster-bind="path:a.b" data-monster-bind-type="number">

Let’s incorporate the missing details on data binding and add a comprehensive table to summarize the attribute types and their functionalities, enhancing the documentation’s completeness and usability.

Enhanced Data Binding

The data-monster-bind attribute allows for two-way data binding between HTML input elements and the JavaScript data model. This powerful feature ensures that changes in the input field automatically update the data model and vice versa, keeping your UI and data model in sync.

Usage Example:

Bind an input field to a property in your data object:

<input type="text" data-monster-bind="path:a.b">

To correctly handle different data types, specify the type of data with the data-monster-bind-type attribute:

<input type="number" data-monster-bind="path:a.b" data-monster-bind-type="number">

Attribute Summary Table

To clarify the usage and functionalities of Monster’s data-binding attributes, the following table provides a quick reference:

AttributeDescriptionExample
data-monster-replaceReplaces the content of an element with the specified data path or static value.<div data-monster-replace="path:headline"></div>
data-monster-attributesAdds or modifies attributes of an element based on specified data paths or static values.<div data-monster-attributes="id static:myid"></div>
data-monster-removeRemoves an element from the DOM.<div data-monster-remove></div>
data-monster-insertDynamically inserts elements based on a template and data path.<ol data-monster-insert="myid path:a"></ol>
data-monster-bindBinds the value of an input field to a data structure, enabling two-way data binding.<input type="text" data-monster-bind="path:a.b">
data-monster-bind-typeSpecifies the type of data bound to an input field (e.g., number, boolean).<input type="number" data-monster-bind="path:a.b" data-monster-bind-type="number">

To complete the documentation, let’s include the detailed explanation of data types supported by the data-monster-bind-type attribute. This addition ensures a thorough understanding of how to accurately bind various data types from your model to your UI elements.

Detailed Explanation of Data Types

When binding data to input elements using data-monster-bind, it’s crucial to specify the type of data being bound. This ensures that the data is correctly interpreted and manipulated within your application. The data-monster-bind-type attribute supports several data types, each with specific behavior and formatting requirements.

Supported Data Types:

TypeAliasDescription
numberint,
float,
integer
Binds numeric values, supporting
both integers and floating-point numbers.
booleanbool,
checkbox
Binds boolean values, useful
for checkboxes and toggle switches.
arraylistInterprets a comma-separated
string as an array, binding list-like data.
objectjsonBinds a JSON string, allowing
complex data structures to be manipulated.

Usage Examples:

To bind a numeric value:

<input type="number" data-monster-bind="path:a.b" data-monster-bind-type="number">

For a boolean value, particularly useful with checkboxes:

<input type="checkbox" data-monster-bind="path:a.b" data-monster-bind-type="boolean">

Binding an array (list) from a comma-separated input:

<input type="text" data-monster-bind="path:a.b" data-monster-bind-type="array">

Binding a JSON object:

<input type="text" data-monster-bind="path:a.b" data-monster-bind-type="object">

CustomElement

Overview

The CustomElement class in MonsterJS is a foundational class for creating new HTML elements using the Web Components Custom Elements API. It enables developers to define new HTML tags with custom behavior and appearance, encapsulating functionality in a reusable component.

Key Features

  • Easy Element Creation: Create instances of custom elements using document.createElement() or by including the tag directly in HTML.
  • Lifecycle Callbacks: Utilize standard custom element lifecycle callbacks like connectedCallback, disconnectedCallback, etc., to manage the element’s lifecycle effectively.
  • Attribute Observers: Monitor changes to attributes and react accordingly using the attributeChangedCallback method.
  • Shadow DOM Support: Encapsulate your element’s styles and markup using the shadow DOM, with support for open and closed shadow modes.
  • Styling Integration: Integrate CSS styling directly into your custom elements, ensuring encapsulation and avoiding style leakage.
  • Event Handling: Define and handle custom events, making your element interactive and responsive to user actions.
  • Extensibility: Extend from HTMLElement to create complex controls with rich functionality.
  • Declarative Configuration: Configure elements declaratively using HTML attributes or programmatically via JavaScript.

Methods and Properties

Constructor

The constructor initializes the element, setting up options and the shadow root if necessary. It is not intended to be called directly but is triggered when an instance of the element is created.

Lifecycle Callbacks

  • connectedCallback(): Invoked when the element is added to the DOM.
  • disconnectedCallback(): Invoked when the element is removed from the DOM.
  • adoptedCallback(): Invoked when the element is moved to a new document.
  • attributeChangedCallback(attrName, oldVal, newVal): Invoked when one of the element’s attributes is changed.

Observers

  • addAttributeObserver(attribute, callback): Adds an observer for an attribute.
  • removeAttributeObserver(attribute): Removes an observer for an attribute.

Options Management

  • getOption(path, defaultValue): Retrieves an option value.
  • setOption(path, value): Sets an option value.
  • setOptions(options): Sets multiple options.

Update and Rendering

  • updateI18n(): Updates the internationalization labels for the element.
  • getInternalUpdateCloneData(): Returns a clone of the internal data for advanced manipulation.
  • [updaterPipeCallbacksSymbol](): Integrates custom functions with Element Updaters.

[updaterPipeCallbacksSymbol]()

To integrate custom functions with Element Updaters, a control must implement the [updaterPipeCallbacksSymbol] method. This method should return an object containing key-value pairs, where the key is a unique name for the callback, and the value is the function itself.

Example Implementation

Here’s an example of how you can define a custom function within a control using [updaterPipeCallbacksSymbol]:

class MyClass extends CustomElement {
    [updaterPipeCallbacksSymbol]() {
        return {
            "my-callback-doing": (value) => {
                switch (typeof value) {
                    case "string":
                        return value + "!";
                    case "number":
                        return value + 1;
                    default:
                        return value;
                }
            }
        }
    }
}

In this example, the my-callback-doing function checks the type of the input value and modifies it based on its type:

  • If the value is a string, it appends an exclamation mark.
  • If the value is a number, it increments the value by one.
  • For other types, it returns the value unmodified.
Using Custom Functions in Templates

Once you’ve defined your custom functions, you can invoke them in your control’s template using the call command within the data binding expression.

Template Integration Example

Here’s how you can incorporate the my-callback-doing function into a control’s template:

<div data-monster-replace="path:options | index:label | call:my-callback-doing" 
     part="option-label"></div>

In this template snippet, the data-monster-replace attribute is used to dynamically update the content of the <div>. The call:my-callback-doing part specifies that the my-callback-doing function should be applied to the value obtained from path:options | index:label.

Utility Methods

  • hasNode(node): Checks if a node is a child of the element.
  • callCallback(name, args): Calls a defined callback function.

Static Methods

  • getTag(): Returns the tag name for the element.
  • getCSSStyleSheet(): Returns the CSS styles for the element.

Examples

Creating a new custom element:

class MyElement extends CustomElement {
    static getTag() {
        return 'my-element';
    }

    connectedCallback() {
        super.connectedCallback();
        console.log('MyElement added to the page.');
    }
}

registerCustomElement(MyElement);

Using the element in HTML:

<my-element></my-element>

CustomControl

Overview

The CustomControl class in MonsterJS extends the CustomElement class, offering additional capabilities specific to form-associated custom elements. It leverages the ElementInternals API to integrate custom elements into HTML forms, enabling them to participate in form submission, validation, and other form-related behaviors.

Key Features

  • Form Association: Integrates custom elements with forms using attachInternals(), enabling them to behave like standard form elements.
  • Validation: Supports standard HTML validation mechanisms and custom validation logic through the ElementInternals API.
  • Value Handling: Provides a framework for getting and setting the value of the control, which is essential for form elements.
  • Form Lifecycle Callbacks: Reacts to form-related events like reset and restore, allowing for custom behavior in response to form interactions.

Methods and Properties

Constructor

Initializes the custom control, setting up internals for form association and observing attribute changes.

Lifecycle Callbacks

Inherits all lifecycle callbacks from CustomElement and introduces form-associated callbacks:

  • formAssociatedCallback(form): Invoked when the element is associated with a form.
  • formDisabledCallback(disabled): Invoked when the associated form’s disabled state changes.
  • formStateRestoreCallback(state, mode): Invoked during state restoration, such as when navigating back to a form with preserved state.
  • formResetCallback(): Invoked when the form is reset.

Form Integration

  • value: Gets or sets the value of the control. Must be overridden in derived classes.
  • labels: Provides access to associated label elements.
  • name: Reflects the name attribute, used for form submission.
  • type: Returns the type of control, typically the tag name.
  • validity: Returns the ValidityState object for the control, indicating its validation state.
  • validationMessage: Provides a localized message describing validation errors.
  • willValidate: Indicates whether the control will be validated.
  • form: References the associated form element.
  • setFormValue(value, state): Sets the value of the control for form submission.
  • setValidity(flags, message, anchor): Sets custom validity messages for the control.
  • checkValidity(): Checks whether the control satisfies its constraints.
  • reportValidity(): Displays the validation message to the user if the control is invalid.

Utility Methods

  • formAssociatedCallback(form): Associates or dissociates the control with a form.
  • formDisabledCallback(disabled): Enables or disables the control based on the form’s state.
  • formStateRestoreCallback(state, mode): Handles state restoration for the control.
  • formResetCallback(): Resets the control’s value during form reset.

Examples

Creating a new custom control:

class MyCustomControl extends CustomControl {
    static getTag() {
        return 'my-custom-control';
    }

    get value() {
        // Custom logic to retrieve the control's value
    }

    set value(value) {
        // Custom logic to set the control's value
    }
}

registerCustomElement(MyCustomControl);

Using the control in an HTML form:

<form>
    <my-custom-control name="myControl"></my-custom-control>
</form>

The CustomControl class empowers developers to create complex, form-associated custom elements, enhancing the capabilities of web forms with custom logic and behaviors.

FocusManager

Overview

FocusManager is a class within MonsterJS designed to manage and manipulate focus within a document. It provides methods to store, restore, and shift focus among elements, facilitating enhanced keyboard navigation and focus management in web applications.

Key Features

  • Focus Storage: Allows storing the current focus state and retrieving it later, which is particularly useful for modal interactions or complex UI transitions.
  • Focus Navigation: Enables moving focus to the next or previous focusable element within a context, supporting accessible keyboard navigation.
  • Focus Control: Offers methods to programmatically focus or query focusable elements, enhancing dynamic interaction and responsiveness in user interfaces.

Methods and Properties

Constructor

Initializes the focus manager with optional configurations, setting up the internal stack to track focus states.

Instance Methods

  • storeFocus(): Stores the current focus in the stack.
  • restoreFocus(): Restores the most recently stored focus state from the stack.
  • focus(element, preventScroll): Focuses on the specified element, optionally preventing scrolling into view.
  • getActive(): Returns the currently focused element in the document.
  • getFocusable(query): Retrieves all focusable elements within the specified context or document, optionally filtered by a query selector.
  • focusNext(query): Moves focus to the next focusable element, optionally filtered by a query selector.
  • focusPrev(query): Moves focus to the previous focusable element, optionally filtered by a query selector.

Properties

  • defaults: Returns the default configuration for the focus manager, including the document and context.

Examples

Creating and using a FocusManager instance:

const focusManager = new FocusManager();

// Store the current focus before opening a modal
focusManager.storeFocus();

// ... open modal and interact with it ...

// Restore focus after closing the modal
focusManager.restoreFocus();

Navigating focus programmatically:

// Focus the next focusable element in the document
focusManager.focusNext();

// Focus the previous input element
focusManager.focusPrev('input');

The FocusManager class is a powerful tool for developers to enhance accessibility and user experience by providing robust focus management capabilities in web applications.

Components

Web components are a set of technologies that allow developers to create custom, reusable elements for use in Web pages and Web applications. in Web pages and Web applications. These elements, called custom elements, can be created using JavaScript, HTML, and CSS, and are fully functional and can be used just like any other standard HTML element.

Web components are a key aspect of web development because they allow developers to create reusable, modular code that can be easily shared and integrated. code that can be easily shared and integrated with other projects. In addition, because Web Components are part of the Web platform and not tied to a specific framework or library, they are highly portable and can be used in a variety of environments. Overall, Web Components provide a powerful and flexible way to way to build Web applications and create custom, reusable elements for Web pages.

Create your own web component

This section is about how to create your own
Web Component.

Using classes and functions from Monster.

First, we create a class derived from CustomControl. The parent class
CustomControl already implements some functions that will make life in the following
easier.

class Button extends CustomControl {
}

The next step determines which tag the control should get in the HTML.

class Button extends CustomControl {
    static getTag() {
        return "monster-button";
        
    }
}

To be able to configure the control later, we have to create the possibility,
to be able to create options. We can use the structures of the class
CustomControl and only need to create a separate property default.

class Button extends CustomControl {

    // ..... other implementations
    
    get defaults() {
        return Object.assign({}, super.defaults, {})
    }

}

The templates of the control are also defined via this structure. In this way one can the control with a standard and give the user of the control the possibility to adapt the templates. Customize the templates.

So, now let’s get to work on the appearance of the control and create a template for it. We want the button to use a simple HTML5 button.

<button>Hello!</button>

The main template of the button is maintained via the templates.main option.

So, we have to insert the HTML into the default structure introduced above. We can
specify the HTML directly here.

return Object.assign({}, super.defaults, {
    templates: {
        main: `<button>Hello!</button>`
    },
})

With templateMapping we can map key values to the HTML template.

return Object.assign({}, super.defaults, {
    templateMapping: {
        a: "b"
    },
})

To maintain an overview of larger templates, you can alternatively
template into a function and only call up the function here.

return Object.assign({}, super.defaults, {
    templates: {
        main: getTemplate()
    },
})

If we now insert the HTML tag <monster-button></monster-button> into an HTML file we get so far so unspectacular a button.

Screenshot

Now comes the magic. In the DOM there are two important methods that are called when a control is included and removed. When a control is removed.

If a control is hooked into the DOM, the method
connectedCallback is called.

When a control is removed from the DOM, on the other hand, the method disconnectedCallback is called

We implement both methods in our new class.

class Button extends CustomControl {

    // ..... other implementations

    connectedCallback() {
        super.connectedCallback();
    }

    disconnectedCallback() {
        super.disconnectedCallback();
    }
} 

Within these two methods, we can now initialize structures or add and remove event handlers. Adding and removing event handlers.

The CustomControl has two other important methods that can be overridden to initialize, they can be overridden to initialize the control. These two methods have no direct method name, but are hidden behind a symbol key. symbol key.

import {
    assembleMethodSymbol,
    initMethodSymbol,
} from "@schukai/monster/dist/modules/dom/customelement.js";

class Button extends CustomControl {

    // ..... other implementations

    [initMethodSymbol]() {
        super[initMethodSymbol]();
    }

    [assembleMethodSymbol]() {
        super[assembleMethodSymbol]();
    }
} 

The method initMethodSymbol is called directly from the constructor and is used for one-time initialization of internal structures. internal structures.

The method assembleMethodSymbol is called the first time the control is included in the
DOM. If the control is removed and re-included, the assembleMethodSymbol method is called. assembleMethodSymbol` is not called again.

Configure a Monster Control

Many of the components of the Monster Control can be configured. Components are created either by a tag in the HTML code or by the document.createElement method.

Example

The following example shows how to configure the Monster Control.

// Create a new Monster Control
var monster = document.createElement('monster-control');

Configuration

Mittels JavaScript können die Monster Controls über die Methode setOption konfiguriert werden. Dazu muss der Name der Option und der Wert übergeben werden.

monster.setOption('optionName', 'optionValue');

A list of available options can be found in the respective documentation of the component or can be read out using the default property.

const control = document.createElement('monster-control');
console.log(control.default);

There are three ways to configure a Monster Control via HTML.

JSON via an attribute

You can simply pass the JSON as a string to the data-monster-options attribute.

<monster-control data-monster-options='{"optionName": "optionValue"}'></monster-control>

If the JSON is too long or contains special characters, it can be converted to a data URL.

new Monster.Types.DataUrl(btoa(JSON.stringify({
    "optionName": "optionValue"
})),'application/json',true).toString()

JSON via a script tag

But the preferred way is to use a script tag.

<script id="id-for-this-config" type="application/json">
    {
        "optionName": "optionValue"
    }
</script>

<monster-control data-monster-options-selector="#id-for-this-config"></monster-control>

Options via attributes

Almost every option can also be set via an attribute. The name of the attribute begins with data-monster-option- and ends with the name of the option. The value of the attribute is the value of the option.

The name of the option is converted to a property path. It replaces the dashes with dots to form the property path. For example, the attribute ‘data-monster-option-url’ maps to the ‘url’ property in the options object.

With the mapping parameter, the attribute value can be mapped to a different value. For example, the attribute ‘data-monster-option-foo’ maps to the ‘bar’ property in the options object.

The mapping object would look like this:

{
'foo': (value) => value + 'bar'
// the value of the attribute 'data-monster-option-foo' is appended with 'bar'
// and assigned to the 'bar' property in the options object.
// e.g. <div data-monster-option-foo="foo"></div>
'bar.baz': (value) => value + 'bar'
// the value of the attribute 'data-monster-option-bar-baz' is appended with 'bar'
// and assigned to the 'bar.baz' property in the options object.
// e.g. <div data-monster-option-bar-baz="foo"></div>
}

Here is an example of how to configure a Monster Control via attributes.

<monster-my-control data-monster-option-bar-baz="foo"></monster-my-control>

Datatable Components

The datatable component is a component that allows you to display data in a table.

Dataset

The dataset component is a component that allows you to display a data row from a datasource.

Usage

The dataset component needs a datasource to get the data that should be displayed in the table. The datasource can be configured via the data-monster-datasource-selector attribute. The value of the attribute is a selector that points to the datasource component.

<monster-dataset data-monster-datasource-selector="#data1"></monster-dataset>

Overview

ArgumentTypeDefaultDescription
data-monster-indexstring0The index of the row in the datasource.
data-monster-datasource-selectorstringThe selector of the datasource component.

Datatable

The datatable component is a component that allows you to display data in a table. The datatable is build with the css grid system and is therefore very flexible.

Installation

To install the Monster-Datatable custom control, run the following command:

Usage

pnpm i @schukai/monster

Registering the Control

To register the control, import the datatable.mjs file:

import "@schukai/monster/source/components/datatable/datatable.mjs";

This will create an empty datatable without any columns or data.

Adding Columns

To add columns, insert a template with an ID:

<monster-datatable>
    <template id="this-is-a-row-id">
        <div data-monster-mode="fixed" data-monster-sortable="oid" data-monster-head="OID">
            <a data-monster-attributes="href path:this-is-a-row-id.oid | tostring | prefix:#"
               data-monster-replace="path:this-is-a-row-id.oid | tostring">Link</a>
        </div>
        <div>
            <button data-monster-replace="static:doit">Click</button>
        </div>
    </template>
</monster-datatable>
  • The top-level div elements in the template define the columns.
  • The template’s ID must be used in the path: attribute.

Header Attributes

  • data-monster-mode="fixed": Specifies that the column cannot be removed or hidden.
  • data-monster-attributes="href path:this-is-a-row-id.oid | tostring | prefix:#": Adds an href attribute to the element with the value from this-is-a-row-id.oid. The value is passed through the pipe | to tostring and converted to a string. Then, the prefix # is added.
  • data-monster-replace: Replaces the child nodes of an element with the value from the specified path.
  • data-monster-sortable="number": Indicates that the column is sortable by the number property. You can add asc or desc as a second parameter. This allows you to preset a specific sort order.
  • data-monster-head="Number": Sets the header for the column to the specified name (e.g., “Number”).

Control Options

The Monster-Datatable control accepts various options in the form of a JSON object:

{
  "templates": {
    "main": getTemplate(),
            "emptyState": getEmptyTemplate()
  },
  "datasource": {
    "selector": null
  },
  "mapping": {
    "data": "dataset"
  },
  "data": [],
          "headers": [],
          "responsive": {
    "breakpoint": 800
  },
  "labels": {
    "theListContainsNoEntries": "The list contains no entries"
  },
  "features": {
    "settings": true,
            "footer": true
  },
  "templateMapping": {
    "row-key": null,
            "filter-id": null
  }
}

Here is a description of each option:

  • templates: An object that specifies the main template and the empty state template.

    • main: The main template for the datatable, usually provided by a function such as getTemplate().
    • emptyState: The template to display when the datatable has no data, usually provided by a function such as getEmptyTemplate().
  • datasource: An object that defines the datasource for the datatable.

    • selector: The selector for the datasource, set to null by default.
  • mapping: An object that maps the datatable properties.

    • data: Maps the property name for the dataset, default is “dataset”.
  • data: An array of data objects for the datatable.

  • headers: An array of header objects for the datatable.

  • responsive: An object that defines responsive behavior for the datatable.

    • breakpoint: The pixel width at which the datatable switches to responsive mode, default is 800.
  • labels: An object that defines labels for the datatable.

    • theListContainsNoEntries: The label to display when the datatable has no data, default is “The list contains no entries”.
  • features: An object that enables or disables certain datatable features.

    • settings: Enables or disables the settings feature, default is true.
    • footer: Enables or disables the footer feature, default is true.
  • templateMapping: An object that defines template mapping properties.

    • row-key: The row key mapping, set to null by default.
    • filter-id: The filter ID mapping, set to null by default.

You can also add a footer to the Monster-Datatable by including a div element with a slot=“footer” attribute. Here’s the updated section of the guide:

To add a footer to the Monster-Datatable, insert a div element with the slot=“footer” attribute and the desired content:

<div slot="footer" class="monster-button-group">
    <monster-button>Aktion 1</monster-button>
    <monster-button>Aktion 2</monster-button>
    <monster-button>Aktion 3</monster-button>
</div>

This example creates a footer with a button group containing three buttons labeled “Aktion 1”, “Aktion 2”, and “Aktion 3”. Customize the footer content as needed for your specific use case.

Adding a Pagination Control

To add a pagination control to the Monster-Datatable, insert a div element with the slot=“bar” attribute and a monster-embedded-pagination element:

<div slot="bar" class="monster-button-group">
  <monster-embedded-pagination
          data-monster-datasource-selector="#data1"></monster-embedded-pagination>
</div>

This example adds a pagination control that uses a datasource selector with the ID data1. Customize the datasource selector and other attributes as needed for your specific use case.

Adding a Filter Button and Filter Area

To add a filter button and a filter area to the Monster-Datatable, insert a monster-datatable-filter-button element within the div element with the slot="bar" attribute:

<div slot="bar" class="monster-button-group">
    <monster-embedded-pagination
        data-monster-datasource-selector="#data1"></monster-embedded-pagination>

    <monster-datatable-filter-button data-monster-reference="#my-collapse" data-monster-role="filter-button">Filter</monster-datatable-filter-button>
</div>

This filter button opens a section that contains a filter when clicked. Define the filter area using a monster-collapse element with the appropriate ID and a data-monster-role=“filter-collapse” attribute:

<monster-collapse id="my-collapse" data-monster-role="filter-collapse">
  <div class="flex">
    <monster-datatable-filter id="listfilter1" slot="filter">
      <label data-monster-label="OID" data-monster-template="${value | call:range:oid}" style="display:none">OID <input name="value" type="text"></label>
    </monster-datatable-filter>
  </div>
</monster-collapse>

This example creates a filter area with an input field for filtering by “OID”. Customize the filter area and other attributes as needed for your specific use case.

Adding Data

The datatable component needs a datasource to get the data that should be displayed in the table. The datasource can be configured via the data-monster-datasource-selector attribute. The value of the attribute is a css selector that points to the datasource component.

<monster-datatable data-monster-datasource-selector="#data1"></monster-datatable>

Overview

ArgumentTypeDefaultDescription
idstringThe id of the datatable (necessary for saving the configuration).
data-monster-datasource-selectorstringThe selector of the datasource component.
data-monster-responsive-breakpointstringThe breakpoint at which the table should be responsive.

Columns

The columns of the datatable are defined via a template element. The template element must have the id attribute with the value row.

Every column is defined via a div element. The div element can configure the following attributes:

The headlines of the table are defined via the data-monster-head attribute. The value of the attribute is a json


<div data-monster-head="ID"></div>

The columns of the data table can be localized. For this purpose, the prefix i18n: must be specified in the title attributes data-monster-head.


<div data-monster-head="i18n:myKey"></div>

The alignment of the column is defined via the data-monster-align attribute. The value of the attribute is a css.


<div data-monster-align="center"></div>

When a column is sortable, the data-monster-sortable attribute must be set. The value of the attribute is the name of the column in the datasource.


<div data-monster-sortable="id"></div>

The mode of the datatable can be set via the data-monster-mode attribute. The value of the attribute is a string that can be fixed, visible or hidden. The default value is visible.


<div data-monster-mode="fixed"></div>

Fixed means that the column is always visible. Visible means that the column is visible as long as nothing else has been configured. Hidden means that the column is hidden as long as nothing else has been configured.

The visibility of the columns can be specified when defining the table. The user can show and hide all non-fixed columns.

The settings can be stored in the client if a monster-host component is available on the page.

The data is stored in the indexedDB. Additionally, the datatable needs an ID. This is set via the attribute ‘id’.

<monster-datatable id="my-table"></monster-datatable>

The localization is done via the i18n functions of the monster library.

<div style="overflow:visible">

For columns that open a popup monster-message-state-button, for example, the button must be embedded in a container with overflow:visible.

Overview

ArgumentTypeDefaultDescription
data-monster-headstringindex of columnThe headline of the column.
data-monster-grid-templatestring1frThe css grid template for the column. it is important that the column has a fraction unit.
data-monster-alignstringstartThe css grid align for the column. Valid values are start, center and end.
data-monster-sortablestringThe name of the column in the datasource.
data-monster-modestringvisibleThe mode of the column. Valid values are fixed, visible and hidden.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

#select1::part(popper) {
    background-color: white;
}

The individual parts are shown in the following picture.

Datatable Filter

The <monster-datatable-filter> HTML control is used to define filters for a data table. Within the control, you can create one or more labels, each representing a filter. These labels must be placed inside the control and can include any HTML controls.

Here is an example of a <monster-datatable-filter> control:

<monster-datatable-filter  id="my-filter" slot="filter">
    <label data-monster-label="OID" 
           data-monster-template="${value | call:range:oid}" style="display:none">
      OID <input name="value" type="search"></label>
</monster-datatable-filter>

This defines a filter that can be used to filter data by OID. The filter is hidden by default, but can be selected from the dropdown menu in the data table. The following image shows the filter.

Defining Filter Names

The data-monster-label attribute is used to specify the name of the filter as it will appear in the dropdown menu where users can select filters. In the example above, the data-monster-label attribute is set to “OID”.

Creating Query Parts with Data-Monster-Template

The data-monster-template attribute is used to define how the key and input value are combined to create a query part. For example, using data-monster-template="oid=${value}" and entering the value 1425 would result in the query oid=1425.

In the example provided, the data-monster-template attribute is set to "${value | call:range:oid}", which calculates a range. If a user enters “1425-1430”, the resulting query would be oid>=1425 AND oid<=1430.

This expression takes the input range and converts it into a query that includes both the lower and upper bounds of the range.

Hiding the Filter by Default

The style="display:none" attribute is used to hide the filter initially. This ensures that the filter is not visible until the user selects it from the dropdown menu.

Positioning the Filter in the Data Table

To position the filter within the filter area of the data table, you can include the slot="filter" attribute. This attribute ensures that the filter is displayed in the correct location within the data table.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

Datatable Filter

The <monster-datatable-status> HTML control is used to display the status of a datasource. The status can display the loading state and the error state. The loading state is displayed when the datasource is request data. The error state is displayed when the datasource has an error.

Usage

The <monster-datatable-status> HTML control is used to display the status of a datasource. It should be placed inside the <monster-datatable> HTML control.

<div slot="bar" class="monster-button-group">
   <monster-datasource-status 
           data-monster-option-datasource-selector="#data1"></monster-datasource-status>
   <monster-embedded-pagination
            data-monster-datasource-selector="#data1"></monster-embedded-pagination>
                <monster-datatable-filter-button data-monster-reference="#my-collapse"
                                                 data-monster-role="filter-button">Filter
                </monster-datatable-filter-button>
            </div>
        </div>
    </div>

The data-monster-option-datasource-selector attribute is used to set the datasource. The value of the attribute is a CSS selector. The selector must point to a Monster Datasource HTML control.

Internationalization

The error status can be translated into different languages. Therefore, the monster-datatable-status' component component implements the i18n transformer. For example, if you have the following status: Failed to fetch`, which is usually thrown by the in the datasource, you can add a translation by adding the following code to your HTML file.

<script type="application/json" data-monster-role="translations">
{
  "Failed to fetch": "This is an error message"
}
</script>

Pagination

The dataset pagination component is a component that can be used to paginate the data that is displayed in a datatable component.

Usage

The pagination component needs a datasource to get the data that should be used to calculate the pagination. The datasource can be configured via the data-monster-datasource-selector attribute. The value of the attribute is a selector that points to the datasource component.

<monster-pagination data-monster-datasource-selector="#datasource">
</monster-pagination>

Embedded Pagination

The embedded dataset pagination component is a component that can be used to paginate the data that is displayed in a datatable component. It is derived from the pagination component and can be used in the same way. The only difference is that it has an embedded style.

Usage

The pagination component needs a datasource to get the data that should be used to calculate the pagination. The datasource can be configured via the data-monster-datasource-selector attribute. The value of the attribute is a selector that points to the datasource component.

<monster-embedded-pagination data-monster-datasource-selector="#datasource">
</monster-embedded-pagination>

Datatable Example

The following example shows how to use the datatable component to display data from a REST API.

The rest api is a Monster component that allows you to make REST calls to a REST API.

<script id="id-for-this-config" type="application/json">
    {
        "read": {
            "url": "https://example.com/api/commerce/orders/search?page=${page}",
            "init": {
                "method": "GET",
                "headers": {
                    "Authorization": "Basic secret",
                    "Accept": "application/json"
                }
            },
            "credentials": "include"
        }
    }

</script>
<monster-datasource-rest id="data1" 
                         data-monster-options-selector="#id-for-this-config">
    
</monster-datasource-rest>

After the datasource is configured, the datatable can be configured. The reference to the datasource is made via the data-monster-datasource-selector attribute.

The headlines of the table are defined via the data-monster-head attribute. If no value is defined, the number of the column is used as the headline.

The grid template width is defined via the data-monster-grid-template attribute. The default value is 1fr.

With the data-monster-align attribute, the alignment of the content can be defined. Values are start, center and end. Additionally, the alignment should be defined in the CSS class for the column.

<monster-datatable data-monster-datasource-selector="#data1">
    <template id="row">
        <div data-monster-head="OID" 
             data-monster-grid-template="1fr"
             data-monster-replace="path:row.oid | tostring | 
             prefix:<a href=/> | suffix:</a>"></div>
        <div data-monster-head="ERP" 
             data-monster-replace="path:row.erpCreation"></div>
        <div class="center" data-monster-align="center" 
             data-monster-replace="path:row.orderState"></div>
        <div class="end" data-monster-align="end"
             data-monster-replace="path:row.orderState | tostring 
                       | prefix:<span class=monster-badge-secondary-pill>|
                       suffix:</span>"></div>
        <div data-monster-replace="path:row.orderState"></div>
        <div data-monster-replace="static:this is a static value"></div>
    </template>
</monster-datatable>

If you want to use the i18n component, you can define the translations in a script tag with the data-monster-role attribute.

<script type="application/json" data-monster-role="translations">
    {
        "head1": "Headline 1",
        "head2": "Headline 2",
    }

</script>

In the html template, the data-monster-head attribute is used to define the location of the headline.

<template id="row">
    <div data-monster-head="i18n:head1"></div>
    <div data-monster-head="i18n:head2"></div>
</template>

And now the datatable is ready to use. The pagination can be used to load more data. The reference to the datasource is made via the data-monster-datasource-selector attribute.

<monster-pagination data-monster-datasource-selector="#data1"></monster-pagination>

You also need to include the javascript and css files for the datatable component.

import "@schukai/monster/source/components/datatable/datasource/rest.mjs";
import "@schukai/monster/source/components/datatable/pagination.mjs";
import "@schukai/monster/source/components/datatable/datatable.mjs";

The datatable component uses the following css classes.

import "@schukai/monster/source/components/style/style/color.pcss";
import "@schukai/monster/source/components/style/style/theme.pcss";
import "@schukai/monster/source/components/style/style/table.pcss";
import "@schukai/monster/source/components/style/style/property.pcss";
import "@schukai/monster/source/components/style/style/badge.pcss";
import "@schukai/monster/source/components/style/style/link.pcss";
import "@schukai/monster/source/components/style/style/data-grid.pcss";
import "@schukai/monster/source/components/style/style/property.pcss";

Layout Components

The Layout components are used to layout the content of a page.

Split Screen

Display an Icon with a tooltip.

Overview

The split screen component is used to divide the screen into two parts. The user can adjust the size of the two parts by dragging the separator.

You can cascade the split screen component to create a multi-panel layout.

Key Features

  • Horizontal and vertical split type
  • Adjustable dimension of the start panel
  • Customizable templates

Methods and Properties

Constructor

The constructor initializes the split screen with default.

Lifecycle Methods

  • [assembleMethodSymbol](): Sets up the button’s internals and event handlers during initialization.

Defaults

Provides default settings for templates, classes, and dimension.

Behavior Methods

  • fullStartScreen(): Sets the start panel to full screen.
  • fullEndScreen(): Sets the end panel to full screen.
  • resetScreen(): Sets the start panel to the initial dimension.

Static Methods

  • getTag(): Returns the tag name used for the button (monster-split-screen).
  • getCSSStyleSheet(): Provides the CSS stylesheets associated with the split screen.

Events

The following events are fired by the component.

Examples

The SplitScreen html tag can be used to create a split screen with two panels. In the example below, the split screen is divided vertically with a 70% dimension for the start panel.

<monster-split-screen data-monster-option-splittype="vertical">
    <div slot="start"
         style="background-color: rgba(227,13,147,0.21); padding: 10px; display: flex; height: calc( 100% - 20px );  align-items: stretch;">
        <h2>Left Content</h2>
    </div>
    <div slot="end"
         style="background-color: #9b410e;padding: 10px; padding: 10px; display: flex; height: calc( 100% - 20px );  align-items: stretch;">
        <h2>Right Content</h2>
    </div>
</monster-split-screen>

The result of the above example:

As a developer, you are responsible for how the content of the two panes behaves. You can set overflow or define a fixed height.

Options

AttributeDescriptionTypeAccepted ValuesDefault
splitTypeThe type of the split screen.Stringhorizontal, verticalhorizontal
dimension.initialThe initial dimension of the start panel in percentage.String60%
dimension.minThe minimum dimension of the start panel in percentage.String20%
dimension.maxThe maximum dimension of the start panel in percentage.String80%
templates.mainThe template of the componentString

Layout

The split screen control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

#select1::part(handle) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

parts

Tabs

Usage

The Tabs component allows the user to switch between multiple contents based on a navigation bar. The text for the buttons is formed from the content of the divs. No tab is active.

// tabs        
const tabs = document.createElement('monster-tabs');

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this is tab 1';
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tabs.appendChild(tab2)

// append to document
document.getElementById('example-tzxoiPwe').appendChild(tabs);
<monster-tabs>
    <div>this is tab 1</div>
    <div>this is tab 2</div>
</monster-tabs>

Active Tab

To set a tab active, you need to give the desired div the css class active`.

// tabs        
const tabs = document.createElement('monster-tabs');

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this is tab 1';
// this tab should be active
tab1.classList.add('active')
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tabs.appendChild(tab2)

// append to document
document.getElementById('example').appendChild(tabs);
<monster-tabs>
  <div class=&quot;active&quot;>this is tab 1</div>
  <div>this is tab 2</div>
</monster-tabs>

Tabs with label and icon

To use an explicit text for the button, you can use the data-monster-button-label attribute. If you also want to specify an icon, the attribute data-monster-button-icon` is available.

// tabs        
const tabs = document.createElement('monster-tabs');

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this is tab 1';
tab1.classList.add('active')
tab1.setAttribute('data-monster-button-label','FIRST');
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tab2.setAttribute('data-monster-button-label','SECOND');
tab2.setAttribute('data-monster-button-icon',
    'https://monsterjs.org/monster.png');
tabs.appendChild(tab2)

// append to document
document.getElementById('example').appendChild(tabs);
<monster-tabs>
    <div class=&quot;active&quot; data-monster-button-label=&quot;FIRST&quot;>this is tab 1</div>
    <div data-monster-button-label=&quot;SECOND&quot; 
            data-monster-button-icon=&quot;https://monsterjs.org/monster.png&quot;>
        this is tab 2</div>
</monster-tabs>

Prefix and suffix

If you want to add content before or after the navigation buttons, you can do so using the start and end slots.

// tabs        
const tabs = document.createElement('monster-tabs');

// prefix
const prefix = document.createElement('div');
prefix.innerHTML='this is a <b>prefix</b>';
prefix.setAttribute('slot','start')
tabs.appendChild(prefix);
            
// suffix
const suffix = document.createElement('div');
suffix.innerHTML='this is a <b>suffix</b>';
suffix.setAttribute('slot','end')
tabs.appendChild(suffix);

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this is tab 1';
tab1.classList.add('active')
tab1.setAttribute('data-monster-button-label','FIRST');
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tab2.setAttribute('data-monster-button-label','SECOND');
tabs.appendChild(tab2)

// append to document
document.getElementById('example').appendChild(tabs);
<monster-tabs>
    <div class=&quot;active&quot; data-monster-button-label=&quot;FIRST&quot;>this is tab 1</div>
    <div data-monster-button-label=&quot;SECOND&quot;>this is tab 2</div>
    <div slot=&quot;start&quot;>this is a <b>prefix</b></div>
    <div slot=&quot;end&quot;>this is a <b>suffix</b></div>
</monster-tabs>

Remove tabs

Tabs can be removed from the DOM. To do this, the desired content must have the attribute data-monster-removable. If you add multiple tabs and there is no space for newer tabs, they will be moved to a popup. You can see this by the sign.

// tabs        
const tabs = document.createElement('monster-tabs');

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this is tab 1';
tab1.classList.add('active')
tab1.setAttribute('data-monster-button-label','FIRST');
tab1.setAttribute('data-monster-removable','true');
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tab2.setAttribute('data-monster-button-label','SECOND');
tab2.setAttribute('data-monster-removable','true');
tabs.appendChild(tab2)

// append to document
document.getElementById('example').appendChild(tabs);
<monster-tabs>
    <div class=&quot;active&quot; 
         data-monster-button-label=&quot;FIRST&quot; 
         data-monster-removable=&quot;true&quot;>this is tab 1</div>
    <div data-monster-button-label=&quot;SECOND&quot; 
         data-monster-removable=&quot;true&quot;>this is tab 2</div>
</monster-tabs>

Fetch tab content

The content of a tab can also be fetched by specifying the attribute data-monster-url with the url of the desired content. The tab is loaded only once. If you want to load the tab fresh from the server for each show, you can specify the attribute data-monster-reload.

It is important to follow the CORS guidelines.

// tabs        
const tabs = document.createElement('monster-tabs');

// tab1
const tab1 = document.createElement('div');
tab1.innerHTML = 'this tab will be reloaded';
tab1.classList.add('active')
tab1.setAttribute('data-monster-button-label','FIRST');
tab1.setAttribute('data-monster-url','https://monsterjs.org/assets/15-forms-tabs-content1.html');
tabs.appendChild(tab1)

// tab2
const tab2 = document.createElement('div');
tab2.innerHTML = 'this is tab 2';
tab2.setAttribute('data-monster-button-label','SECOND');
tab2.setAttribute('data-monster-removable','true');
tabs.appendChild(tab2)

// append to document
document.getElementById('example').appendChild(tabs);
<monster-tabs>
    <div class=&quot;active&quot;
         data-monster-button-label=&quot;FIRST&quot;
         data-monster-url=&quot;https://monsterjs.org/assets/15-forms-tabs-content1.html&quot;>this tab will be reloaded</div>
    <div data-monster-button-label=&quot;SECOND&quot;
         data-monster-removable=&quot;true&quot;>this is tab 2</div>
</monster-tabs>

Events

The following events are fired by the component.

Layout

The tabs control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

#select1::part(popper) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

parts

Form component

Web forms are a way for users to enter and submit data on a web page. They are created using HTML and can include a variety of input elements such as text fields, checkboxes, radio buttons, and more.

Web forms are a critical aspect of many websites because they allow users to interact with the site and provide information such as login credentials, contact information, and more.

Create form

Usage

The Form component allows the user to create a form and in interaction with a datasource to change data.

// create element
const form = document.createElement('monster-form');

Input controls

A form needs input fields. These can be easily defined within the tag. Either via Javascript directly or via the markup.

const input = document.createElement('input')
input.setAttribute('name','field');
form.appendChild(input);

via markup

<monster-form>
    <input name="field">
</monster-form>

The formula field ➊ are included as slotted elements in the shadow root ➋.

Datasource

One of the more interesting features of the form is the ability to connect the form to a data source. A datasource has a simple API to read and write an object (see Monster Framework under Datasources).

In this example we use a RestAPI datasource, but other datasources work as well. The example url httpbin.org is a service that provides a simple api with data. This is for this example only. You can of course specify your own api here.

const datasource =  new RestAPI({
  url: 'https://httpbin.org/get'
},{
  url: 'https://httpbin.org/post'
});
form.setOption('datasource', datasource)

In order to see the data as a value in the input field, we must specify the attribute data-monster-attributes.

const input = document.createElement('input')
input.setAttribute('name','field');
input.setAttribute('data-monster-attributes','value path:headers.Host');
form.appendChild(input);

Now we have to report the data back to the datasource. For this we use the attribute data-monster-bind. In this example we write the value in the same field, but we can also choose another field if for example the POST api has a different structure.

input.setAttribute('data-monster-bind','path:headers.Host');

Actions

What is a form without action? To be able to send the changed data we can add a button.

const button = document.createElement('monster-state-button');
// let's give the button a text
button.setOption('labels.button','click!')
// this attribute ensures that the form sets an action handler in the button.
button.setAttribute('data-monster-datasource-handler','write')

button.setOption('actions.click', undefined);

form.appendChild(button);

If we now click on the button, the modified dataset will be sent to the url previously specified in the RestAPI datasource.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

#select1::part(popper) {
    background-color: white;
}

The individual parts are shown in the following picture.

Button Documentation

Overview

The Button class in MonsterJS extends the CustomControl class, providing a customizable button element. It supports various configurations, such as labels, actions, and visual effects like ripples, making it a versatile component for any web application.

Key Features

  • Customizable Appearance: Configure the button’s appearance using CSS classes and templates.
  • Action Handling: Define custom click actions to handle user interactions.
  • Accessibility: Inherits accessibility features from CustomControl, ensuring the button is accessible and usable in various contexts.
  • Form Association: Can be used within forms, with support for value handling and form-associated behaviors.
  • Visual Effects: Supports visual effects like ripple on click, enhancing the user experience.

Methods and Properties

Constructor

Initializes the button with default or provided options, setting up internal references and event handlers.

Lifecycle Methods

  • [assembleMethodSymbol](): Sets up the button’s internals and event handlers during initialization.

Interaction Methods

  • click(): Programmatically simulates a click on the button.
  • focus(options): Sets focus on the button, with optional parameters to control focus behavior.
  • blur(): Removes focus from the button.

Attribute Observers

Overrides observedAttributes to include additional attributes specific to the button, like data-monster-button-class.

Form Association

  • value: Gets or sets the button’s value, useful in form-associated contexts.
  • formAssociated: Indicates that the button is form-associated.

Defaults

Provides default settings for templates, labels, classes, disabled state, actions, and effects.

Static Methods

  • getTag(): Returns the tag name used for the button (monster-button).
  • getCSSStyleSheet(): Provides the CSS stylesheets associated with the button, including styles for the button and ripple effect.

Examples

The Button class can be used to create custom buttons with various configurations.

<monster-button data-monster-button-class="my-custom-button">Click Me</monster-button>

Alternatively, you can create a button programmatically and set its options using JavaScript.

const button = document.createElement('monster-button');
button.setOption('actions.click', () => alert('Button clicked!'));
document.body.appendChild(button);

The button control encapsulates a button and serves as a basis for derived controls.

// create element
const button = document.createElement('monster-button');

// insert element into the DOM
document.getElementById('body').appendChild(button);
<monster-button></monster-button>

Slotted Button

The text of the button can be defined either by the option labels.button.

// create element
const button = document.createElement('monster-button');

// insert element into the DOM
document.getElementById('body').appendChild(button);

// Label
button.setOption('labels.button','My Button');

Or by a slot.

<monster-button>My Button</monster-button>

Action

Standard HTML buttons can listen to different events. Since the standard button sits in a shadowRoot the click event is accessible via an option. The component button uses a callback to listen for click events.

To do this, you must pass a callback to the actions.click option.

const button = document.querySelector('monster-button');
button.setOption('actions.click',(event)=>{
  console.log('clicked!');
});

State-Button

The status button is a special form of the button and has an icon to display the status.

You can also define your own statuses. these must be specified in the options.

// create element
const button = document.createElement('monster-state-button');

// insert element into the DOM
document.getElementById('body').appendChild(button);

// Label
button.setOption('labels.button','My Button');

// set state: successful, activity or failed
button.setState('successful');

Or by a slot.

<monster-state-button>My Button</monster-state-button>

Layout

The button control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-button::part(button) {
    background-color: white;
}

The color scheme of the button can be set using CSS class via the options. You should always use a light color scheme for the status button, so that the icon is the icon is clearly visible. When using the standard design, you should always use the Outline variant should always be used.

const button = document.querySelector('monster-button');
button.setOption('classes.button','monster-button-outline-secondary');

if you want to use the standard classes, you have to include the properties, this can be done for example with postcss.

import  "@schukai/monster/source/components/style/style/color.pcss";
import  "@schukai/monster/source/components/style/style/theme.pcss";
import  "@schukai/monster/source/components/style/style/property.pcss";

The individual parts and slots are shown in the following picture.

This documentation outlines the capabilities and configuration options of the Button class, enabling developers to integrate and customize button elements effectively in their web applications.

Confirm button

Usage

The ConfirmButton component enables the display of a confirmation prompt before the final execution of an action.

// create element
const button = document.createElement('monster-confirm-button');
// set label
button.setOption('labels.button', 'click me!');

// insert element into the DOM
document.getElementById('body').appendChild(button);

Add confirm action

The confirm button can be given a function via the actions.confirm option.

button.setOption('actions.confirm', function (event) {
    console.log('confirm');
    button.hideDialog();
});

Add confirm action with state

The state is realized via a process queue.

button.setOption('actions.confirm', function (event) {

    const self = this;
    new Processing(() => {
        self.setState('activity'); // set state
        button.setOption('disabled', true);
    }, 2000, () => { // delay 2000 milliseconds 
        button.hideDialog();
    }).run().then(() => {
        button.setOption('disabled', undefined); // remove state
    });

});

Layout

The confirm-button control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-confirm-button::part(popper) {
    background-color: white;
}

The nested parts can each be addressed via the part name and the subpart name. So the part button is addressable from the confirm button via confirm-button.

monster-confirm-button::part(confirm-button) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

Popper button

Usage

The PopperButton component enables the display of a form or other content in a pop-up window.

// create element
const button = document.createElement('monster-popper-button');
// set label
button.setOption('labels.button', 'click me!');

// insert element into the DOM
document.getElementById('body').appendChild(button);

Layout

The popper-button control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-confirm-button::part(popper) {
    background-color: white;
}

Message State button

Usage

The MessageStateButton button can be used to display a button with a message. The message is displayed when the method showMessage() is called. The message is hidden when the method hideMessage() is called.

// create element
const button = document.createElement('monster-message-state-button');
// set label
button.setOption('labels.button', 'click me!');

Set Message

The message can be set via the method setMessage(). The message can be a string or an HTML element.

// create element
const button = document.createElement('monster-message-state-button');
// set label
button.setOption('labels.button', 'click me!');
// set message
button.setMessage('This is a message');
// show message
button.showMessage();

Layout

The message-state-button control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-message-state-button::part(popper) {
    background-color: white;
}

The nested parts can each be addressed via the part name and the subpart name. So the part button is addressable from the confirm button via message-state-button.

monster-message-state-button::part(message-state-button) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

Reload

Usage

The Reload component allows the user to reload a content via URL. The content is reloaded only when the element is in the viewport. The IntersectionObserver API is used.

Im Standard wird der Inhalt nur einmal geladen. Möchte man den Inhalt immer wieder neu Laden, so muss die Option data-monster-reload auf “always” gesetzt werden.

It is important to follow the CORS guidelines.

// reload element
const reload = document.createElement('monster-reload');

// loader content
const defaultContent = document.createElement('div');
defaultContent.setAttribute('data-monster-role','container');
defaultContent.innerHTML='load'
reload.appendChild(defaultContent);

// fetch follow url
reload.setAttribute('data-monster-url',
    'https://monsterjs.org/assets/16-forms-reload-content.html')

// append element 
document.getElementById('example').appendChild(reload);


<monster-reload>
  <div data-monster-role="container">
    LOADER ...
  </div>
</monster-reload>

If the child element has the attribute data-monster-role="container", then the content is replaced with the fetched content.

Events

The following events are fired by the component.

Layout

The tabs control can be customized to your own needs. For this purpose, the control can be designed via css.

The different parts of the control can be designed using CSS.

By default, the Shadow DOM is disabled for this component. You can enable it by setting the option shadowMode: false, to open or closed.

Since the internals of the component are optionally encapsulated in a shadow tree, access is via css pseudo-element parts.

#reload::part(container) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

Select

Overview

The Select class in MonsterJS extends CustomControl, providing a rich, customizable select element. It supports advanced features like filtering, multiple selection, lazy loading of options, and customizable templates for displaying options and selections.

Key Features

  • Rich Configuration: Supports a wide array of options for customization, including filtering, lazy loading, and multiple selection types.
  • Dynamic Option Loading: Capable of fetching options from a remote source or populating them dynamically.
  • Custom Templates: Allows defining custom templates for options and selections, enhancing the UI’s flexibility and interactivity.
  • Form Association: Integrates seamlessly with forms, supporting both single and multiple selections.
  • Accessibility: Adheres to accessibility standards, ensuring that the control is usable for all users.

Methods and Properties

Constructor

Initializes the select control with optional configurations, setting up internal structures and event handlers.

Instance Methods

  • click(): Toggles the visibility of the option list.
  • focus(options): Sets focus on the select control, with optional parameters to control focus behavior.
  • blur(): Removes focus from the select control.
  • fetch(url): Fetches options from a specified URL or the configured URL.
  • importOptions(data): Imports options from a given dataset, which can be an array, object, Map, or Set.

Attribute Observers

Overrides observedAttributes to monitor changes to relevant attributes for dynamic updates.

Form Association

  • value: Gets or sets the current selection(s), which can be a single value or an array of values for multiple selections.
  • formAssociated: Indicates the control’s form-associated behavior.

Defaults

Provides default settings, including templates, labels, classes, option configurations, and more.

Static Methods

  • getTag(): Returns the tag name used for the select control (monster-select).
  • getCSSStyleSheet(): Returns the CSS stylesheets associated with the select control.

Examples

The control can be created and used in various ways, including declarative HTML, JavaScript creation, and event handling.

This shows a basic example of creating a select control using HTML.

<monster-select></monster-select>

And this is an example of creating a select control using JavaScript.

const select = document.createElement('monster-select');
select.importOptions([{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }]);
document.body.appendChild(select);

Event handling:

select.addEventListener('monster-selected', (e) => {
  console.log('Selection changed:', e.detail);
});

Select component allows user to pick any amount of option from the given data:

// create element
const select = document.createElement('monster-select');

// set multiselect
select.setOption('type', 'checkbox');

// set options
select.setOption('options', [
    {
        value: 'en', label: 'United Kingdom &lt;img width=20
        src = "https://raw.githubusercontent.com/lipis/flag-icon-css/master/flags/4x3/gb.svg" &gt; '},
    {
        value: 'se', label: 'Sverige &lt;img width=20
        src = "https://raw.githubusercontent.com/lipis/flag-icon-css/master/flags/4x3/se.svg" &gt; '},
    {
        value: 'de', label: 'Deutschland &lt;img width=20
        src = "https://raw.githubusercontent.com/lipis/flag-icon-css/master/flags/4x3/de.svg" &gt; '}
]);

// insert element into the DOM
document.getElementById('body').appendChild(select);

Single select

Radios are used for the single selection.

select.setOption('type', 'radio');

Multiselect

Checkboxes are used for multiple selection.

select.setOption('type', 'checkbox');

Import data

The options can be imported from an object. The object can be read in either directly via Select.importOptions() or indirectly via a URL. In the example, a json file is imported via https://monsterjs.org/assets/world.json`.

select.setOption('url', 'https://monsterjs.org/assets/world.json')

Alternatively, the data can also be imported from an object.

select.importOptions([
    {
        "name": "United Kingdom",
        "alpha-2": "GB",
        "country-code": "826",
    },
    {
        "name": "Sweden",
        "alpha-2": "SE",
        "country-code": "752",

    },
    {
        "name": "Germany",
        "alpha-2": "DE",
        "country-code": "276",
    }
]);

The mapping of the data to the options is done using the values defined in the mappings key.

select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')

If you want to specify a deeper structure, you can do so via selector`.

{
    a: {
        b: {
            c: [
                ....
        ]
        }
    }
}

select.setOption('mapping.selector', 'a.b.c')

It is also possible to filter values. This is done via the filter parameter. Further details on the structure of the map can be found in the Monster documentation.

There is also an example.

select.setOption('mapping.filter', function (value, key) {
    return (value['id'] >= 20) ? true : false
})

Options via DIV elements

The options can also be defined via HTML. The following example shows how to define the options. Important is the monster-value attribute. This is used to define the value of the option. The label is defined by the content of the div.

<monster-select>
    <div data-monster-value="value1">label-1</div>
    <div data-monster-value="value2">label-2</div>
    <div data-monster-value="value3">label-3</div>
</monster-select>

Display selected options

There are two predefined templates for displaying the selected options. The first is the default template.

import {getSelectionTemplate} 
    from '@schukai/monster/source/dom/select.mjs';

select.setOption('templateMapping.selected', 
    getSelectionTemplate())

Selection

The second is the summary template. This template is used to display the selected options in a summary. To configure the summary, the templateMapping.summary option can be used.

Summary

The template can be changed via the templateMapping.selected option should be filled with the template.

import {getSummaryTemplate} from '@schukai/monster/source/dom/select.mjs';

select.setOption('templateMapping.selected', 
    getSummaryTemplate())

You can also define your own template.

select.setOption('templateMapping.selected', 
    "<div>Selected: ...</div>")

With the attribute data-monster-selected-template you can also define the template directly in the HTML. Available templates are summary and selected.

<monster-select data-monster-selected-template="summary">
    
</monster-select>

Features

With the features option, the behavior of the component can be changed. The following features are available.

closeOnSelect

The closeOnSelect feature closes the select control after an option has been selected.

select.setOption('features.closeOnSelect', true)

clearAll

The clearAll feature shows a button to clear all selected options.

select.setOption('features.clearAll', true)

clear

The clear feature shows a button to clear

select.setOption('features.clear', true)

lazyLoad

The lazyLoad feature loads the data when the select control is opened.

select.setOption('features.lazyLoad', true)

emptyValueIfNoOptions

This can be used to control whether values that are not in the options are deleted. The default behavior is now that undefined values are also displayed.

select.setOption('features.emptyValueIfNoOptions', true)

Events

The following events are fired by the component.

I18n

The component can be translated into different languages. For this you simply have to translate the corresponding labels. This can be done using the Select.setOption() method.

select.setOption('labels', {
    'cannot-be-loaded': 'The data cannot be loaded',
    'no-options-available': 'No options available'
});

You can also use the translation function. Therefore, the component can be translated via the Select.updateI18n() methods.

const selects = document.querySelector('monster-select')
select.updateI18n();

To see the keys of the translations, you can look at the default values under the labels key.

selects.getOption('labels')
// ↦ { .... }

Plural rules are available for the selection text. These can be set via the labels.summary-text option.

In the following example, the locales are set via an embed provider. First the keys are defined:

<script type="application/json" data-monster-role="translations">
    {
        "summary-text": {
            "zero": "Non sono state selezionate voci",
            "one": ",<span class='monster-badge-primary-pill'>1</span> voce è stata selezionata",
            "other": "Sono state selezionate <span class='monster-badge-primary-pill'>${count}</span> voci"
        }
    }
</script> 

The translations are then assigned to the component.

Embed.assignTranslationsToElement().then(() => {
  select.updateI18n();
});

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-select::part(popper) {
    background-color: white;
}

The individual parts are shown in the following picture.

This documentation outlines the Select class’s capabilities and configuration options, enabling developers to incorporate sophisticated select controls into their web applications.

State button

Usage

The StateButton button can be used to display a button with a state. The state is displayed when the method setState() is called. The state is hidden when the method removeState() is called.

// create element
const button = document.createElement('monster-state-button');
// set label
button.setOption('labels.button', 'click me!');

Set State

The state can be set via the method setState(). The sate is a string defined in the option. Currently, the following states are defined: activity, successful and failed. More states can be defined in the option.

// create element
const button = document.createElement('monster-state-button');
// set state
button.setState('activity');

The second parameter of the method setState() can be used to define a timeout after which the state is removed. If the timeout is not set, the state is not removed automatically.

// create element
const button = document.createElement('monster-state-button');
// set state
button.setState('activity', 1000);

In this example, the state is removed after 1000 milliseconds.

Remove State

The state can be removed via the method removeState().

// create element
const button = document.createElement('monster-state-button');
// set state
button.setState('activity');
// remove state
button.removeState();

Layout

The state-button control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

Toggle Switch

Overview

The Toggle Switch in MonsterJS extends CustomControl, providing a rich, customizable switch element. This allows you to select two states for example: on or off / yes or no / active or inactive .

A practical use case would be confirming the terms and conditions on a website by clicking on the Toggle Switch.

Key Features

  • Form Association: Integrates seamlessly with forms with customizable design.
  • Accessibility: Adheres to accessibility standards, ensuring that the control is usable for all users.

Examples

The control can be created and used in various ways, including declarative HTML, JavaScript creation, and event handling.

This shows a basic example of creating a select control using HTML.

<monster-toggle-switch></monster-toggle-switch>
import  "@schukai/monster/source/components/form/toggle-switch.mjs";

import  "@schukai/monster/source/components/style/style/form.pcss";
import  "@schukai/monster/source/components/style/style/common.pcss";
import  "@schukai/monster/source/components/style/style/color.pcss";
import  "@schukai/monster/source/components/style/style/property.pcss";

// create element
const switch = document.createElement('monster-toggle-switch');

// insert element into the DOM
document.getElementById('body').appendChild(switch);

Usage

The following example shows how to use the Toggle Switch in a form.

Configuration

The following configurations can be made for the component.

Defaults

There is one template templates.main available for this component.

Disabled

The Toggle Switch can be set on disabled like every other form element.

Object classes

The options can be used to control which value is to be used for on and which for off.
The default values of the classes are:

statevalue
trueon
falseoff
<monster-toggle-switch data-monster-option-values-on="true" data-monster-option-values-off="false" ></monster-toggle-switch>

Value init

The standard value of the element is off if it’s not selected.

The value can be changed via the standard attribute value.

<monster-toggle-switch value="on"></monster-toggle-switch>

The value must match the value for on. If this is not the case, the element is disabled.

I18n

The component can be translated into different languages. For this you simply have to translate the corresponding labels.

The two different labels of Toggle Switch are using the method.updateI18n().

Layout

The toggle switch control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

The following colors are used for the states:

  • “on”: “monster-theme-primary-3”
  • “off”: “monster-theme-primary-2”

The individual parts are shown in the following picture.

Context Error

Display an Icon with a tooltip for error messages.

Usage

The error message can be displayed in two modes: auto and manual. In auto mode, the error message is displayed when the user hovers the icon. In manual mode, the help message is displayed when the you call the showDialog method.

This is a text with a <monster-context-error id="error">
    <div>This is an error message</div>
</monster-context-error> error message.
Hover the icon to see the tooltip.

The result of the above example:

This is a text with a
error message. Hover the icon to see the tooltip.

The message can be set manually by calling the setErrorMessage(msg, show) method.

const error = document.getElementById('error');
error.setErrorMessage('This is an error message').showDialog();

// or

error.setErrorMessage('This is an error message', true);
// the message will be displayed immediately and will not be hidden

// or

error.setErrorMessage('This is an error message', 5000); 
// 5000 is the duration in ms, after which the message will be hidden

If you want to hide the message manually, you can call the resetErrorMessage method.

const error = document.getElementById('error');
error.resetErrorMessage();

To check if the message is currently displayed, you can call the hasErrorMessage method. This do not check if the message is visible, but if the message is set.

const error = document.getElementById('error');
error.hasErrorMessage(); // returns true or false

The control is derived from the popper component, so you can use all the attributes and methods of the popper component.

Internationalization

The error message can be translated into different languages. Therefore, the monster-context-error' component implements the implements the i18n transformer. For example, if you have the following error message: Failed to fetch`, you can add by adding the following code to your HTML file.

<script type="application/json" data-monster-role="translations">
{
  "Failed to fetch": "This is an error message"
}
</script>

Options

AttributeDescriptionTypeAccepted ValuesDefault
modeThe mode of the componentStringauto, manualauto
classes.buttonThe class of the buttonStringmonster-theme-error-2
templates.mainThe template of the componentStringmonster-context-error

Context Help

Display an Icon with a tooltip.

Usage

The help message can be displayed in two modes: auto and manual. In auto mode, the help message is displayed when the user hovers the icon. In manual mode, the help message is displayed when the you call the showDialog method.

This is a text with a <monster-context-help id="help">
    <div>This is a help message</div>
</monster-context-help> help message icon.
Hover the icon to see the tooltip.

The result of the above example:

This is a text with a
help message. Hover the icon to see the tooltip.

Options

AttributeDescriptionTypeAccepted ValuesDefault
modeThe mode of the componentStringauto, manualauto
classes.buttonThe class of the buttonStringmonster-theme-error-2
templates.mainThe template of the componentStringmonster-context-error

Searchable tree select

Usage

The TreeSelect control is derived from Select and therefore inherits all properties and functions. It extends the control by the display of hierarchical data.

const treeselect = document.createElement('monster-tree-select');

// URL
treeselect.setOption('url', 
     'https://monsterjs.org/assets/14-forms-treeselect-data.json');

// Multiselect
treeselect.setOption('type', 'checkbox');

// search for data in dataset
treeselect.setOption('mapping.selector', 'dataset.*');

// define label and key
treeselect.setOption('mapping.labelTemplate', '${localeLabel | index:en}');
treeselect.setOption('mapping.valueTemplate', '${cid | tostring }');

// wich field is the parent ID?
treeselect.setOption('mapping.parentTemplate', 'parentCID');
treeselect.setOption('mapping.idTemplate', 'cid');

// append
document.getElementById('container').appendChild(treeselect);            

Events

The following events are fired by the component.

Layout

The tree select control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

#tab::part(popper) {
    background-color: white;
}

The individual parts are shown in the following picture.

Popper

The popper component is a component that can be used to display a tooltip or a popover.

Usage

<monster-popper id="popper"></monster-popper>

Host Components

The host components are used to create a host for the application. The host is the main container for the web application. it offers several central functions, such as the loading configuration or the loading of the application translations.

Collapse

The collapse component allows you to display a a detailed description. The description is hidden by default and can be displayed by clicking on a button. The button is not part of the component. It must be created by the user.

Usage

Collapse component can be used to display a detailed description. The description is hidden by default.

// create element
const collapse = document.createElement('monster-collapse');

// insert element into the DOM
document.getElementById('body').appendChild(collapse);

Details-Content

The content of the details is defined by the user. The content can be defined as a child element of the collapse component.

<monster-collapse>
    <p>I am the content of the overlay.</p>
</monster-collapse>

It is also possible to load the content from an external file. For this purpose, the reload component is used.

<monster-collapse>
    <monster-reload data-monster-url="./nav.html"></monster-reload>
</monster-collapse>

Accordion

Combine multiple details into one Accordion.

<monster-collapse>
    <div>lorem ipsum dolor st amet, consteitur sadpselit, sed dam noum eiimocie naboeyminvit ut</div>
</monster-collapse>
<monster-collapse>
    <div>ineimad imnimevinam, qusi nostrud exerci tation ullacmorper susicpti lobrotis nsil uta lquiip</div>
</monster-collapse>

If you do not want to use the accordion, you can set the feature flag features.accordion to false.

Events

The following events are fired by the component.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

Call Button

The call button component can be used to call a function of a component. The function is called when the button is clicked.

Usage

The call button component search an element with the given reference and calls the function with the given name.

<div id="my-function-host"></div>
<script type="module">
    document.getElementById('my-function-host').myFunction = function () {
        console.log('myFunction called');
    }
</script>
<monster-call-button data-monster-reference="#my-function-host" data-monster-call="myFunction">
    call myFunction
</monster-call-button>

Layout

The call control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

Details

The details component allows you to display a summary and a detailed description.

Usage

Details component can be used to display a summary and a detailed description.

// create element
const details = document.createElement('monster-details');

// insert element into the DOM
document.getElementById('body').appendChild(details);

In order to display the summary, the attribute data-monster-button-label must be set.

Details-Content

The content of the overlay can be set via slotted content. The content is displayed in the body of the summary. In this example, the content is a simple text.

<monster-details>
    <p>I am the content of the overlay.</p>
</monster-details>

It is also possible to load the content from an external file. For this purpose, the reload component is used.

<monster-details>
    <monster-reload data-monster-url="./nav.html"></monster-reload>
</monster-details>

Accordion

Combine multiple details into one Accordion.

<monster-details>
    <div>lorem ipsum dolor st amet, consteitur sadpselit, sed dam noum eiimocie naboeyminvit ut </div>
</monster-details>
<monster-details>
    <div>ineimad  imnimevinam,  qusi nostrud exerci tation ullacmorper susicpti lobrotis nsil uta lquiip</div>
</monster-details>

If you do not want to use the accordion, you can set the feature flag features.accordion to false.

Events

The following events are fired by the component.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

To change the color of the open button, the following CSS can be used.

details::part(container) {
    border: 1px solid red;
}

The individual parts are shown in the following picture.

Toggle Button

The toggle button component is a special button that can be used to toggle between two states. The button is derived from the call button component and can be used in the same way.

Usage

The toggle button component search an element with the given reference and calls the function toggle. This is very helpful in combination with the collapse component.

<monster-collapse id="my-collapse">
  <monster-reload data-monster-url="./nav.html"></monster-reload>
</monster-collapse>

<monster-call-button data-monster-reference="#my-collapse">
    toggle
</monster-call-button>

Layout

The toggle control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

Overlay

The overlay component is used to display a modal dialog. It is used by the host component to display the login dialog. Im Standard wird oben links, absolute positioniert, ein Button angezeigt, der das Overlay öffnet. Das Overlay kann auch über den Aufruf der Methode open() geöffnet werden.

Usage

Overlay component allows user to display a modal dialog:

// create element
const select = document.createElement('monster-overlay');

// insert element into the DOM
document.getElementById('body').appendChild(select);

Overlay-Content

The content of the overlay can be set via slotted content. The content is displayed in the body of the overlay. In this example, the content is a simple text.

<monster-overlay>
    <p>I am the content of the overlay.</p>
</monster-overlay>

It is also possible to load the content from an external file. For this purpose, the reload component is used.

<monster-overlay>
    <monster-reload data-monster-url="./nav.html"></monster-reload>
</monster-overlay>

Multiple Overlay-Content

It is also possible to embed multiple overlays. The buttons are positioned absolute, therefore the containing div must be positioned relative.

<div style="position:relative">
    <monster-overlay>
        <monster-reload data-monster-url="./nav.html"></monster-reload>
    </monster-overlay>
</div>

<div style="position:relative">
    <monster-overlay>
        <p>I am the content of the overlay.</p>
    </monster-overlay>
</div>

Events

The following events are fired by the component.

Layout

The select control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

To change the color of the open button, the following CSS can be used.

monster-overlay::part(open) {
    border: 1px solid red;
}

The result is shown in the following picture.

The individual parts are shown in the following picture.

Host

The simple host component is used to create a host for the application. The host is the main container for the web application. This component has no visual representation. It offers several central functions, such as the loading configuration or the loading of the application translations.

Usage

You can embed the host component in your HTML document with the following code.

<monster-host></monster-host>

To add a navigation and a notification area, you can use the following code.

<monster-host>
    <monster-overlay>
        <monster-reload data-monster-url="./nav.html"></monster-reload>
    </monster-overlay>
    <monster-notify></monster-notify>
</monster-host>

onReady

The onReady method can be used to execute code after the host component has been initialized.

const host = document.querySelector('monster-host');
host.onReady(() => {
    console.log('Host is ready');
});

FocusManager

The host component offers a interface to the focus manager. The focus manager is used to manage the focus of the application.

const host = document.querySelector('monster-host');
host.focusManager.focusNext();

ResourceManager

The host component offers a interface to the resource manager. The resource manager is used to load resources such as translations or configuration files.

const host = document.querySelector('monster-host');
host.resourceManager.addStylesheet('https://example.com/style.css');

Translations

The has a interface to get the locale of the application. The locale is used to load the translations of the application.

const host = document.querySelector('monster-host');
host.locale 
// ↦ 'de'

The translations hold the translations of the application.

const host = document.querySelector('monster-host');
host.translations
// ↦ ...

Notifications

With the Host.pushNotification("example") method, you can add a notification to the notification area. The notification area is defined in the HTML document.

To use the notification area, you have to add the following code to your HTML document.

<monster-host>
    <monster-notify></monster-notify>
</monster-host>

Layout

The host control has no visual representation.

Notify Component

The notify component is a simple notification component.

Notify

The notify component encapsulates the notify message component.

Usage

The notify component is a simple graphical display that specifies a notification.

Layout

The notify control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-notify::part(action) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

Messages

The notify message component is a simple notification message.

Usage

The notify component is a simple graphical display that specifies a notification.

Layout

The message control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-notify-message::part(remove) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

State component

The components in this group are used to manage the state of an application.

State component

The state component is a simple state display component. It is used to display the current state of the application.

Usage

The status component is a simple graphical display that specifies a structure of elements. The aim of this component is to enable a uniform representation of such displays.

The component is composed of a visual, a heading and a text. Actions (buttons) can also be displayed.

import '@schukai/monster/source/components/form/button.mjs';
import '@schukai/monster/source/components/state/state.mjs';

// state element
const state = document.createElement('monster-state');
state.innerHTML = `  
<svg slot="visual" >...</svg>
<h1>This is a headline</h1>
<p>loreLorem ipsum dolor sit amet, consetetur sadipscing elitr, 
sed diam nonumy eirmod tempor invidunt 

ut labore et dolore magna aliquyam erat, sed diam voluptua. 

At vero eos et accusam et justo duo</p>
<monster-button slot="action" class="monster-button-primary">
  Button
</monster-button>
<monster-button slot="action">Button</monster-button>`;

<monster-state>
    <svg slot="visual" version="1.1" viewBox="0 0 612.41 583.39" xml:space="preserve"
         xmlns="http://www.w3.org/2000/svg">...</svg>
    <h1>This is a headline</h1>
    <p>loreLorem ipsum dolor sit amet, consetetur sadipscing elitr, 
        sed diam nonumy eirmod tempor invidunt ut labore et
        dolore magna aliquyam erat, sed diam voluptua. 
        At vero eos et accusam et justo duo</p>
    <monster-button slot="action" class="monster-button-primary">
        Button
    </monster-button>
    <monster-button slot="action">Button</monster-button>
    `;
</monster-state>

Layout

The state control can be customized to your own needs. For this purpose, the control can be designed via CSS.

The different parts of the control can be designed using CSS. Since the internals of the component are in a shadow tree, access is via css pseudo-element parts.

monster-state::part(action) {
    background-color: white;
}

The individual parts and slots are shown in the following picture.

Log component

The log component can be used to display log messages in the browser.

If no log messages are displayed, then a status dialog appears.

As log messages are added, they are displayed in the log component.

log.addEntry(new Entry({
    message: "add some entries",
    date: "2020-01-01",
    title: "the first title",
    user: "the user",
}))

If you have only one message, you can add it with the log.addMessage(message, date) method.

log.addMessage("this is a log message", "2020-01-01");
// if no date is specified, the current date is used
log.addMessage("this is a log message");

Example

<monster-log id="my-log"></monster-log>

<script>
    const log = document.getElementById("my-log");

    log2.addEntry(new Entry({
      message:"add some entries",
      date: "2020-01-01",
      title: "the first title",
      user: "the user",
    }))
    log2.addEntry(new Entry({
      message:"I have been doing it" ,
      date: "2021-12-12 16:15:14",
      title: "next title",
      user: "administrator",
    }))
    log2.addEntry(new Entry({
      message:"an entrie that is very long ...",
      date: "2023-01-01 12:12:12",
      title: "this is the title",
      user: "a customer",
    }))

    log2.addMessage("this is a log message");
</script>

Data

Functions and classes in this section are used to handle data.

Pathfinder

Overview

Pathfinder is a pivotal class in MonsterJS, designed to navigate and manipulate data within nested object structures. It provides a straightforward way to access or modify deeply nested values using a concise path notation.

Key Features

  • Deep Access: Quickly retrieve or set values at any depth within an object or array.
  • Path Notation: Utilize a dot-separated string or an array of keys/indices to specify paths.
  • Flexibility: Works with objects, arrays, and even complex nested structures.
  • Wildcards: Supports wildcard characters to apply operations across multiple paths.

Methods and Properties

Constructor

Initializes a Pathfinder instance with a target object to operate on.

getVia(path)

Retrieves the value at the specified path within the object. Throws an error if the path is invalid or does not exist.

setVia(path, value)

Sets the value at the specified path. If the path doesn’t exist, it creates the necessary structure.

deleteVia(path)

Removes the value at the specified path, adjusting the structure if necessary.

exists(path)

Checks if a value exists at the specified path without throwing errors.

Examples

Accessing a nested value:

import { Pathfinder } from '@schukai/monster/source/data/pathfinder.mjs';

const data = {
    a: { b: { c: 10 } }
};
const pathfinder = new Pathfinder(data);
console.log(pathfinder.getVia('a.b.c')); // Outputs: 10

Setting a nested value:

pathfinder.setVia('a.b.d', 20);
console.log(data.a.b.d); // Outputs: 20

Checking for the existence of a path:

console.log(pathfinder.exists('a.b.c')); // Outputs: true
console.log(pathfinder.exists('a.x.y')); // Outputs: false

Pathfinder enhances data manipulation in MonsterJS, making it easier to work with complex data structures through its intuitive API and versatile path navigation capabilities.

Pipe

Streamlining Data Processing with the Pipe Class in MonsterJS.

Overview

The Pipe class in MonsterJS is a powerful tool for chaining data processing functions, streamlining multiple operations into a coherent workflow. This class is particularly useful when direct JavaScript embedding isn’t viable, such as in HTML contexts. Instead of sequentially calling functions in JavaScript, Pipe allows developers to define a series of transformations through a simple string. This approach is ideal for HTML attributes or similar situations where only string definitions make sense, offering a neat and efficient way to articulate complex data processing logic without cluttering the markup.

Key Features

  • Flexible Data Processing: Easily chain multiple functions together to process data in a streamlined and readable manner.
  • Pathfinder Integration: Utilizes the Pathfinder class to access nested data within objects, providing a straightforward way to retrieve and manipulate deep values.
  • Transformer Utilization: Leverages the Transformer class to apply various transformations to the data as it moves through the pipe.

How It Works

  1. Initialization: Create a Pipe instance by specifying a string that defines the sequence of operations, separated by the pipe symbol |.
  2. Execution: Call the run method on your Pipe instance, passing in the initial data. The data will be processed through the series of functions you’ve defined.

Example Usage

import { Pipe } from '@schukai/monster/source/data/pipe.mjs';

let data = {
    a: {
        b: {
            c: {
                d: "hello"
            }
        }
    }
};

let pipe = new Pipe('path:a.b.c.d | toupper | prefix:Hello, ');
console.log(pipe.run(data)); // Outputs: "Hello, HELLO"

In this example, the Pipe instance first retrieves the value at the specified path within the object, converts it to uppercase, and then prefixes it with “Hello, “.

Methods and Properties

  • constructor(pipe): Initializes a new Pipe instance with the specified processing sequence.
  • setCallback(name, callback, context): Allows you to define custom callbacks within the pipe’s sequence.
  • run(value): Executes the pipe’s sequence of functions on the input value, returning the transformed result.

Transformer

The Transformer class is used to transform data. The transformation is defined as a string.

import {Transformer} from '@schukai/monster/source/data/transformer.mjs';

const transformer = new Transformer("tolower")
console.log(transformer.run("HELLO"))
// ↦ hello

The following transformations are available:

commandparameteraliasdescription
callfunction:param1:param2:…Calling a callback function. The function can be defined in three places: either globally, in the context addCallback or in the passed object
concatpath or static:path or static:…This function concatenates the values of the passed paths. If no value in the path is found, the path is used as a static value.
containsChecks if an array or string contains a value (since 3.17)
currencymaximumFractionDigits:roundingIncrementmoneyConvert a currency and amount to a local string (since 3.17)
dateConvert a date string to a localized date string (since 3.16)
datetimeConvert a date string to a localized date-time string (since 3.17)
dayReturns the day of a date (since 3.16)
debugThe passed value is output (console) and returned
defaultvalue:type??If the value is undefined the first argument is returned, otherwise the value. The third optional parameter specifies the desired type. If no type is specified, string is used. Valid types are bool, string, int, float, undefined and object. An object default value must be specified as a base64 encoded json string. (since 1.12)
element-by-idplainAll HTML tags are removed (*)
emptyReturn empty String “”
equalsvalueCompare the comparison value with the specified value and return true if they match.
first-keydefaultCan be applied to objects and returns the value of the first key. All keys of the object are fetched and sorted. (since 1.23)
from-base64atobConverts the value from base64
fromjsonType conversion from a JSON string (since 1.12)
has-entrieshasentriesChecks whether an array or an object has elements. (since 3.17)
hourshourReturns the hours of a date (since 3.16)
ifstatement1:statement2?Is the ternary operator, the first parameter is the valid statement, the second is the false part. To use the current value in the queue, you can set the value keyword. On the other hand, if you want to have the static string “value”, you have to put one backslash \ in front of it and write value. the follow values are true: ‘on’, true, ‘true’. If you want to have a space, you also have to write \ in front of the space.
indexkey:defaultproperty, keyFetches a value from an object, an array, a map or a set
is-arrayisarrayChecks if the value is a array (since 3.17)
is-floatisfloatChecks if the value is a float (since 3.17)
is-nullisnullChecks if the value is null (since 3.17)
is-numberisnumberChecks if the value is a number (since 3.17)
is-objectisobjectChecks if the value is a object (since 3.17)
is-setissetChecks if the value is undefined and not null (since 3.17)
is-undefinedisundefinedChecks if the value is undefined (since 3.17)
last-keydefaultCan be applied to objects and returns the value of the last key. All keys of the object are fetched and sorted. (since 1.23)
lengthcountLength of the string or entries of an array or object
mapkey:value:key:value….Map a value with an existing mapping (since 3.16)
minutesminuteReturns the minutes of a date (since 3.16)
monthReturns the month of a date (since 3.16)
nopDo nothing
notConverts a bolian value into the opposite one (since 3.17)
nth-keyindex:defaultCan be applied to objects and returns the value of the nth key. All keys of the object are fetched and sorted. (since 1.23)
nth-last-keyindex:defaultCan be applied to objects and returns the value of the nth key from behind. All keys of the object are fetched and sorted. (since 1.23)
path-existspathCheck if the specified path is available in the value (since 1.24)
pathpathThe access to an object is done via a Pathfinder object
plaintextplainAll HTML tags are removed (*)
prefixtextAdds a prefix
rawurlencodeURL coding
secondssecondReturns the seconds of a date (since 3.16)
set-toggleset:delimiterToggle the set in the value. The delimiter is used to separate the values. The default delimiter ist the space char. (since 3.57.0)
set-setset:delimiterSet the set in the value. The delimiter is used to separate the values. The default delimiter ist the space char. (since 3.57.0)
set-removeset:delimiterRemove the set in the value. The delimiter is used to separate the values. The default delimiter ist the space char. (since 3.57.0)
staticnoneThe Arguments value is used and passed to the value. Special characters \ and : can be quotet by a preceding .
substringstart:lengthReturns a substring
suffixtextAdds a suffix
timeConvert a date string to a localized time string (since 3.16)
timestampConvert a date string to a time stamp (since 3.16)
to-base64base64, btobConverts the value to base64
tointegerType conversion to an integer value
tojsonType conversion to a JSON string (since 1.8)
tolowerstrtolower, tolowercaseThe input value is converted to lowercase letters
tostringType conversion to a string.
toupperstrtoupper, touppercaseThe input value is converted to uppercase letters
translationkey:defaulti18nTranslations can be applied. The translations must be stored in the DOM. (*) To use the current value as key the first parameter must be set to undefined.
trimRemove spaces at the beginning and end
ucfirstFirst character large
ucwordsAny word beginning large
undefinedReturn undefined
uniqidCreates a string with a unique value (**)
weekdayReturns the day of the week of a date (since 3.16)
yearConvert a date string to a year (since 3.16)

(*) for this functionality the extension jsdom must be loaded in the nodejs context.

 // polyfill
if (typeof window !== "object") {
    const {window} = new JSDOM('', {
        url: 'http://example.com/',
        pretendToBeVisual: true
    });

    [
        'self',
        'document',
        'Node',
        'Element',
        'HTMLElement',
        'DocumentFragment',
        'DOMParser',
        'XMLSerializer',
        'NodeFilter',
        'InputEvent',
        'CustomEvent'
    ].forEach(key => (global[key] = window[key]));
}

(**) for this command the crypt library is necessary in the nodejs context.

import * as Crypto from "@peculiar/webcrypto";

global['crypto'] = new Crypto.Crypto();

With the method setCallback(name, callback, context) you can define your own transformation functions.

The context parameter is optional and can be used to define the context in which the callback function is called. If no context is specified, the global context is used. In the pipe the name of the callback function is used by prefixing it with a call:.

import {Transformer} from '@schukai/monster/source/data/transformer.mjs';

const transformer = new Transformer("call:myCallback");
transformer.setCallback("myCallback", function (value) {
    return value + " world";
});
console.log(transformer.run("hello")); // hello world

Internationalization

The localization classes and functions support you in dealing with
translations and country-specific settings.

Locale

The Locale class is used to determine the language and country settings.

The method parseLocale() parses a locale string and returns a Locale object.

import {parseLocale} from '@schukai/monster/source/i18n/locale.mjs';
var locale = parseLocale("en-US");
console.log(locale.language); // "en"
console.log(locale.country); // "US"

The Method getLocaleOfDocument() returns the Locale object of the current document.

import {getLocaleOfDocument} from '@schukai/monster/source/dom/locale.mjs';
var locale = getLocaleOfDocument();
console.log(locale.language); // "en"
console.log(locale.country); // "US"

In an HTML document you can set the language and country with the lang attribute.

<html lang="en-US">

The method getLocaleOfDocument() checks for the lang attribute first and takes the browser locale as fallback. If no locale is available, English is taken.

Formatter & Translations

We need the Formatter and Translations class and the parseLocale() function to handle translations.
In the context of the DOM we can also use the getLocaleOfDocument() method.

import {Translations} from '@schukai/monster/source/i18n/translations.mjs';
import {Formatter} from '@schukai/monster/source/text/formatter.mjs';
import {parseLocale} from '@schukai/monster/source/i18n/locale.mjs';
import {getLocaleOfDocument} from '@schukai/monster/source/dom/locale.mjs';

Let’s start with the function parseLocale(). This function can create a Locale object from a string.

So we can create the corresponding Locale object from the string en_GB.

const locale = parseLocale('en_GB')
// ↦ Locale {}

If we move in the browser, so we can also use the function getLocaleOfDocument().
This function returns a locale object as a result.

This function looks if the HTML tag <html lang="en"> has a lang attribute.
If no locale is defined, the default value is assumed to be en.

We now need an object with the translations. For this, we use the Translations class.

We can either define the translations ourselves or load them via an API.

// define translations
const translation = new Translations(parseLocale('en-GB'));
translation.assignTranslations({
           text1: 'hello world!',
           text2: {
             'one': 'click once',
             'other': 'click ${n | tostring} times' // this is where the pipe comes in
           }
        });

// fetch from API
const translation = new Fetch('https://example.com/${language}.json')
    .getTranslation('en-GB');
// ↦ https://example.com/en.json 

If we now have a translation, we can now read the desired strings. For this
we use the method Translation.getText() or the method Translation.getPluralRuleText()
for texts with more than one number.

const message = translation.getText('text1');
// -> hello world

To translate texts with number references, enter the desired number.

let n=1;
const message1 = translation.getPluralRuleText('text2', n);
// -> click once

n=2
const message2 = translation.getPluralRuleText('text2', n);
// -> click ${n} times

To replace the placeholder now, the formatter is used.

const text = new Formatter({n}).format(message2); 
console.log(text)
// ↦ click 2 times

Finally, let’s take a look at the formatter class from the i18n module.

import {Formatter} from 
    "@schukai/monster/source/text/formatter.mjs";

A translation object can be passed directly to this class.

There is also the possibility to pass values in the format string.

// define translation
const translations = new Translations('en')
    .assignTranslations({
        // text with placeholder
        message: "${animal} has eaten the ${food}!"
    });

// without marker and inline values
new Formatter({}, translations).format("message::animal=dog::food=cake")
// ↦ dog has eaten the cake!     

Translation

The Translation class encapsulates strings for a specific locale. It is used to translate strings into a specific language and country.

import {Translation} from '@schukai/monster/source/i18n/translation.mjs';

const translation = new Translation("en-US");
translation.set("hello", "Hello World!");

// plural rules
translation.setText("text6", {
    "zero": "There are no files on Disk.",
        "one": "There is one file on Disk.",
        "other": "There are files on Disk.",
    "default": "There are files on Disk."
});

If you want to assign a complete translation object, you can use the assignTranslations() method.

translation.assignTranslations({
    "hello": "Hello World!",
    "text6": {
        "zero": "There are no files on Disk.",
        "one": "There is one file on Disk.",
        "other": "There are files on Disk.",
        "default": "There are files on Disk."
    }
});

The getText() method returns the translated string for a given key.

translation.getText("hello"); // "Hello World!"

There are also methods for plural rules. The getPluralRuleText() method returns the translated string for a given key and a given number.

translation.getPluralRuleText("text6", 0); // "There are no files on Disk."
translation.getPluralRuleText("text6", 1); // "There is one file on Disk."
translation.getPluralRuleText("text6", 2); // "There are files on Disk."

Document Translation

First, you have to create a new script element with the data-monster-role="translations" and the type="application/json" attribute. The content of the element must be a JSON object.

<script type="application/json" data-monster-role="translations">
    {
        "key1": "translation1",
        "key2": {
            "other": "translation2"
        }
    }
</script> 

Then you have to assign the translations to the document. This can be done with the assignTranslationsToDocument() method. This static method returns a promise. Than you can use the getDocumentTranslations() method to get the translations. Finally, you can use the getText() method to get the translated string.

import { Embed } from "@schukai/monster/source/i18n/providers/embed.mjs";
import { getDocumentTranslations } from "@schukai/monster/source/i18n/translations.mjs";

Embed.assignTranslationsToElement().then(() => {

    const translations = getDocumentTranslations();

    translations.getText('no-key','with-default')
    // ↦ with-default

    translations.getText('key1')
    // ↦ translation1

}).catch((e) => {
// ...
})

Provider

The abstract Provider class is used to provide translations to the application.

import {Provider} from '@schukai/monster/source/i18n/provider.mjs';

Fetch Provider

The FetchProvider class is used to provide translations from a remote server.

import {Fetch} from '@schukai/monster/source/i18n/providers/fetch.mjs';
const provider = new Fetch(
    'https://example.com/translations${language}.json',
    {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
    }
);
provider.getTranslations('en-US').then(translations => {
    console.log(translations);
});

The URL can contain the placeholder ${language}, ${script}, ${region}, ${variants}, ${extlang} and ${privateUse}. The placeholders will be replaced with the language, country and locale of the current document.

import {Fetch} from '@schukai/monster/source/i18n/providers/fetch.mjs';

const provider = new Fetch(
    'https://example.com/translations/${language}/${region}.json',
    {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
    }
);
provider.getTranslations('en-US').then(translations => {
    console.log(translations);
});

Embed Provider

The EmbedProvider class is used to provide translations from a local tag.

You must add a script tag with the type application/json. This Tag must contain a JSON object with the translations.

<script id="mmylocale" type="application/json">
{
        "key": "translation"
}
</script>

Now you can use the EmbedProvider to get the translations.

import {Embed} from '@schukai/monster/source/i18n/providers/embed.mjs';

const provider = new Embed('mmylocale');
provider.getTranslations('en-US').then(translations => {
    console.log(translations);
});

Text

Functions and classes in this section are used to handle text.

Formatter

The Formatter class allows you to format messages by replacing placeholders with values from an object. It supports nested placeholders, callbacks, and custom markers. The class is part of the Monster.Text module.

Installation

npm install @schukai/monster

Usage

import {Formatter} from '@schukai/monster/source/text/formatter.mjs';

Basic Usage

Create an instance of the Formatter class by passing an object containing the values to be used for formatting. Then, call the format method with a string containing placeholders.

const formatter = new Formatter({
    key: 'value',
    nested: {
        key: 'nested value',
    },
});

const formattedText = formatter.format('This is a ${key} and this is a ${nested.key}');
console.log(formattedText); // Output: "This is a value and this is a nested value"

Nested Placeholders

Placeholders can be nested, allowing you to use the value of an inner placeholder as a key for an outer placeholder.

const text = '${mykey${subkey}}';
const obj = {
    mykey2: '1',
    subkey: '2',
};

const formatter = new Formatter(obj);
console.log(formatter.format(text)); // Output: "1"

Callbacks

You can adjust the values in a formatter using callbacks.

const formatter = new Formatter({x: '1'}, {
    callbacks: {
        quote: (value) => {
            return '"' + value + '"';
        },
    },
});

console.log(formatter.format('${x | call:quote}')); // Output: "\"1\""

Custom Markers

You can customize the markers for the placeholders by calling the setMarker method.


formatter.setMarker('#'); // both open and close markers are #
formatter.setMarker('[', ']');
formatter.setMarker('i18n{', '}');

generateRangeComparisonExpression

This documentation describes the generateRangeComparisonExpression function, its parameters, return value, and an example usage.

generateRangeComparisonExpression(expression, valueName, options = {}) generates a comparison expression for a comma-separated string of ranges and single values.

Parameters

  • expression (string): The string expression containing comma-separated ranges and single values to generate the comparison for.
  • valueName (string): The name of the value to compare against in the generated expression.
  • options (Object, optional): The optional parameters for the function. Defaults to an empty object.
  • urlEncode (boolean, optional): Whether to encode comparison operators for use in a URL. Defaults to false.
  • andOp (string, optional): The logical AND operator to use. Defaults to ‘&&’.
  • orOp (string, optional): The logical OR operator to use. Defaults to ‘||’.
  • eqOp (string, optional): The comparison operator for equality to use. Defaults to ‘==’.
  • geOp (string, optional): The comparison operator for greater than or equal to use. Defaults to ‘>=’.
  • leOp (string, optional): The comparison operator for less than or equal to use. Defaults to ‘<’.

Returns

(string): The generated comparison expression.

Throws

Error: If the input expression contains invalid ranges or values.

Example

const expression = "1,3,5-7";
const valueName = "x";
const comparisonExpression = generateRangeComparisonExpression(expression, valueName);
console.log(comparisonExpression); // "(x==1) || (x==3) || (x>=5 && x<=7)"

Extra Topics

Compatibility

In the monster library, we use current functions and objects for the implementation.
Some functions may not run on older runtimes.

There are several ways to increase compatibility.

One way is Babel and the @babel/preset-env preset.

More information about the browsers supported by Babel can be found in the browserslist project.

Polifyll

As a design decision, we decided against any kind of polyfill in our code. This not only benefits the codebase, but also makes testing easier.

A more effective way to compensate for incompatibilities is to add missing functionality via external polyfills.

To avoid having to search for and include every polyfill yourself, you can use services like polyfill.io. These can inject the missing functions and objects for each browser.

The URL builder can be used to compile the desired polyfills.

You can also automate the creation of the URL. For this you can install the tool create-polyfill-service-url.

With the following call the tool analyzes your script and throws out the desired URL.

npm i create-polyfill-service-url

With the following call the tool analyzes your script and throws out the desired URL.

npx create-polyfill-service-url analyse --file bundle.js

bundle.js is here the file that contains your code.

The result is a URL that you can easily paste into your HTML web page.

For Monster, the following code can currently be used in the header of an HTML page.

Firefox also needs the polyfill construct-style-sheets-polyfill for the monster components for the constructable stylesheets.

<script id="polyfill"
        src="https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.entries,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.map,document,Event,fetch,IntersectionObserver,JSON,Map,MutationObserver,Object.assign,Object.entries,Promise,ResizeObserver,Set,String.prototype.trim,Symbol,Symbol.iterator,URL,WeakMap,WeakSet"
        crossorigin="anonymous"
        referrerpolicy="no-referrer"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es-module-shims.min.js"
        referrerpolicy="no-referrer"
        crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/adoptedStyleSheets.min.js"
        referrerpolicy="no-referrer"
        crossorigin="anonymous"></script>

References

Contribution Guidelines

General Principles

  • Company-Wide Contributions: We encourage every member of the company to contribute to this main project. Your insights and code make us better.
  • Derived Projects: If you are working on a project derived from this main project and have developed features or fixes beneficial to the main project, please create an issue and submit a merge request.
  • Always Operational: The main project should always be in a fully functional state. This allows any team member to clone the repository and start working without extensive setup.
  • No Half-Baked Submissions: Please only submit completed and thoroughly tested work. If your changes are stable, tag a new version.
  • Documentation: Prior to contributing, please read through the available documentation to understand how the project functions.

Steps for Contributing

  • Create an Issue: Before starting any work, create an issue describing the feature, fix, or improvement. Link the issue to any corresponding projects or discussions as necessary.
  • Branching: Always create a new branch for each issue you are working on.
  • Code Review: Submit a merge request for code review. Make sure your code adheres to our style and quality standards.
  • Tagging: After merging and ensuring stability, tag a new version.

By following these guidelines, we maintain a high standard of quality, reduce the margin of error, and work more cohesively as a team.

Thank you for your contributions.

Troubleshooting

I can’t find the package.json file

The package.json file is located in the root directory of the project. If you can’t find it, you are probably in the wrong directory.

Imprint

Responsible for the content

schukai GmbH
Eichenstraße 26
82290 Landsberied
Germany

[email protected]
+49-8141-5098888
schukai.com