From d0680c3a9658600eca29496064faff8d6cc768c6 Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Mon, 1 Apr 2024 18:27:49 +0200
Subject: [PATCH] chore: update template and create showroom section

---
 .config/silicon.cfg                           |   4 +
 .gitlab/issue_templates/bug.md                |  46 ++++
 .gitlab/issue_templates/default.md            |  17 ++
 Taskfile.yml                                  |   8 +-
 development/issues/182.html                   |   8 +-
 devenv.nix                                    |  10 +
 nbproject/project.properties                  |   3 -
 nbproject/project.xml                         |   9 -
 showroom/mock/demo.js                         | 202 ++++++++++++++++++
 .../video/monster-width-toggle/index.html     |  45 ++++
 .../video/monster-width-toggle/script.mjs     |  51 +++++
 .../video/monster-width-toggle/style.pcss     |  11 +
 showroom/vite.config.js                       |  99 +++++++++
 .../components/layout/style/width-toggle.pcss |  27 ++-
 .../layout/stylesheet/width-toggle.mjs        |   2 +-
 source/components/layout/width-toggle.mjs     | 129 +++++------
 16 files changed, 585 insertions(+), 86 deletions(-)
 create mode 100644 .config/silicon.cfg
 create mode 100644 .gitlab/issue_templates/bug.md
 create mode 100644 .gitlab/issue_templates/default.md
 delete mode 100644 nbproject/project.properties
 delete mode 100644 nbproject/project.xml
 create mode 100644 showroom/mock/demo.js
 create mode 100644 showroom/video/monster-width-toggle/index.html
 create mode 100644 showroom/video/monster-width-toggle/script.mjs
 create mode 100644 showroom/video/monster-width-toggle/style.pcss
 create mode 100644 showroom/vite.config.js

diff --git a/.config/silicon.cfg b/.config/silicon.cfg
new file mode 100644
index 000000000..958e1c65d
--- /dev/null
+++ b/.config/silicon.cfg
@@ -0,0 +1,4 @@
+--shadow-color '#555'
+--background '#fff'
+--shadow-blur-radius 30
+--no-window-controls
\ No newline at end of file
diff --git a/.gitlab/issue_templates/bug.md b/.gitlab/issue_templates/bug.md
new file mode 100644
index 000000000..f29f01e33
--- /dev/null
+++ b/.gitlab/issue_templates/bug.md
@@ -0,0 +1,46 @@
+<!--- 
+
+Creating an issue file in the directory `monster/development/issues` is mandatory!
+
+Provide a general summary of the issue in the Title above 
+
+You can erase any parts of this template
+not applicable to your Issue.
+
+-->
+
+## Expected Behavior
+
+<!--- Tell us what should happen -->
+
+## Current Behavior
+
+<!--- Tell us what happens instead of the expected behavior -->
+
+## Possible Solution
+
+<!--- Not obligatory, but suggest a fix/reason for the bug, -->
+
+## Steps to Reproduce
+
+<!--- Create a file in the issue folder `monster/development/issues` with the name -->
+<!--- of the issue number and provide an unambiguous set of steps to -->
+<!--- reproduce this bug. Include code to reproduce, if relevant -->
+1.
+2.
+3.
+4.
+
+## Context (Environment)
+
+<!--- How has this issue affected you? What are you trying to accomplish? -->
+<!--- Providing context helps us come up with a solution that is most useful in the real world -->
+<!--- Provide a general summary of the issue in the Title above -->
+
+## Detailed Description
+
+<!--- Provide a detailed description of the change or addition you are proposing -->
+
+## Possible Implementation
+
+<!--- Not obligatory, but suggest an idea for implementing addition or change -->
\ No newline at end of file
diff --git a/.gitlab/issue_templates/default.md b/.gitlab/issue_templates/default.md
new file mode 100644
index 000000000..9972529eb
--- /dev/null
+++ b/.gitlab/issue_templates/default.md
@@ -0,0 +1,17 @@
+## Summary
+
+<!---
+
+* [ ] Can you reproduce the problem in playgrounds?
+* [ ] Are you running the latest version?
+* [ ] Did you check the FAQs?
+* [ ] Are you reporting to the correct repository?
+* [ ] May you report a bug? Use the template for bugs.
+
+You can erase any parts of this template 
+not applicable to your Issue. 
+
+-->
+
+
+<!--- Start here -->
\ No newline at end of file
diff --git a/Taskfile.yml b/Taskfile.yml
index ac7164e88..2fc89ddad 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -20,10 +20,14 @@ tasks:
   run-dev:
     silent: true
     desc: Start and run the development server
-    aliases:
-      - pg
     cmds:
       - run-development
+      
+  run-showroom:
+    silent: true
+    desc: Start and run the showroom server
+    cmds:
+      - run-showroom
 
   build-doc:
     silent: true
diff --git a/development/issues/182.html b/development/issues/182.html
index d83e2fe33..ccf2c9a02 100644
--- a/development/issues/182.html
+++ b/development/issues/182.html
@@ -20,8 +20,8 @@
     </ul>
 
 
-    <monster-width-toggle>
-        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+    <monster-width-toggle >
+        <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
             Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
             adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
             Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
@@ -36,7 +36,7 @@
             Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
             Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
             adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
-        </p>
+        </div>
 
 
     </monster-width-toggle>
@@ -47,4 +47,4 @@
 </main>
 
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/devenv.nix b/devenv.nix
index a26f9f7e0..38c93d890 100644
--- a/devenv.nix
+++ b/devenv.nix
@@ -47,6 +47,7 @@ in {
     meld
     memcached
     netcat
+    silicon
     nodePackages.pnpm
     php82Extensions.xdebug
     plantuml-c4
@@ -213,6 +214,15 @@ in {
     fi
 
 
+  '';
+  scripts.run-showroom.exec = ''
+
+    if ! ${pkgs.nodePackages.pnpm}/bin/pnpx vite --config "${config.devenv.root}/showroom/vite.config.js"; then
+        echo "ERROR: Vite build failed, check your JS!"
+        exit 1
+    fi
+
+
   '';
   scripts.create-polyfill.exec = ''
 
diff --git a/nbproject/project.properties b/nbproject/project.properties
deleted file mode 100644
index da97eba56..000000000
--- a/nbproject/project.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-files.encoding=UTF-8
-site.root.folder=
-source.folder=
diff --git a/nbproject/project.xml b/nbproject/project.xml
deleted file mode 100644
index 6f4991f03..000000000
--- a/nbproject/project.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.web.clientproject</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/clientside-project/1">
-            <name>@schukai/monster</name>
-        </data>
-    </configuration>
-</project>
diff --git a/showroom/mock/demo.js b/showroom/mock/demo.js
new file mode 100644
index 000000000..3331b64d4
--- /dev/null
+++ b/showroom/mock/demo.js
@@ -0,0 +1,202 @@
+
+const json = 
+    `{
+                "dataset": [
+                {
+                    "erpID": "",
+                    "type": "order",
+                    "erpName": "mix up erp9",
+                    "erpNumber": "",
+                    "erpLastUpdate": "2020-01-16T10:27:18",
+                    "erpCreation": "2020-01-16T10:27:18",
+                    "archived": false,
+                    "oid": 88,
+                    "orderDate": "2019-01-16T10:27:18",
+                    "orderState": 57,
+                    "orderLastStatusChange": "2019-01-16T10:38:53",
+                    "customerUID": 30,
+                    "customerNotice": "",
+                    "billingAddressAID": 16,
+                    "deliveryAddressAID": 16,
+                    "deliveryNotice": "",
+                    "paymentPID": 101,
+                    "assigndTickets": "",
+                    "resubmissionDate": "1970-01-01T12:00:00",
+                    "resubmissionInfo": "",
+                    "acquisitionPartnerID": 0,
+                    "acquisitionInfo": "",
+                    "acquisitionRedirect": null,
+                    "acquisitionDate": "1970-01-01T12:00:00",
+                    "shippingNotice": "",
+                    "shippingDCID": 2,
+                    "retoureRID": 0,
+                    "companySHID": 1,
+                    "salesmanUID": 0,
+                    "channelOrderID": "",
+                    "channelOrderState": "0",
+                    "channelOrderDate": null,
+                    "channelOrderData": {}
+                },
+                {
+                    "erpID": "",
+                    "type": "retoure",
+                    "erpName": "erp 2",
+                    "erpNumber": "",
+                    "erpLastUpdate": "2020-01-16T10:27:18",
+                    "erpCreation": "2020-01-16T10:27:18",
+                    "archived": true,
+                    "oid": 1000,
+                    "orderDate": "2019-01-16T10:27:18",
+                    "orderState": 57,
+                    "orderLastStatusChange": "2019-01-16T10:38:53",
+                    "customerUID": 30,
+                    "customerNotice": "",
+                    "billingAddressAID": 16,
+                    "deliveryAddressAID": 16,
+                    "deliveryNotice": "",
+                    "paymentPID": 101,
+                    "assigndTickets": "",
+                    "resubmissionDate": "1970-01-01T12:00:00",
+                    "resubmissionInfo": "",
+                    "acquisitionPartnerID": 0,
+                    "acquisitionInfo": "",
+                    "acquisitionRedirect": null,
+                    "acquisitionDate": "1970-01-01T12:00:00",
+                    "shippingNotice": "",
+                    "shippingDCID": 2,
+                    "retoureRID": 0,
+                    "companySHID": 1,
+                    "salesmanUID": 0,
+                    "channelOrderID": "",
+                    "channelOrderState": "0",
+                    "channelOrderDate": null,
+                    "channelOrderData": {}
+                },
+                {
+                    "erpID": "",
+                    "type": "shipping",
+                    "erpName": "erp4",
+                    "erpNumber": "",
+                    "erpLastUpdate": "2020-01-16T10:27:18",
+                    "erpCreation": "2020-01-16T10:27:18",
+                    "archived": false,
+                    "oid": 1001,
+                    "orderDate": "2019-01-16T10:27:18",
+                    "orderState": 57,
+                    "orderLastStatusChange": "2019-02-16T10:38:53",
+                    "customerUID": 30,
+                    "customerNotice": "",
+                    "billingAddressAID": 16,
+                    "deliveryAddressAID": 16,
+                    "deliveryNotice": "",
+                    "paymentPID": 101,
+                    "assigndTickets": "",
+                    "resubmissionDate": "1970-01-01T12:00:00",
+                    "resubmissionInfo": "",
+                    "acquisitionPartnerID": 0,
+                    "acquisitionInfo": "",
+                    "acquisitionRedirect": null,
+                    "acquisitionDate": "1970-01-01T12:00:00",
+                    "shippingNotice": "",
+                    "shippingDCID": 2,
+                    "retoureRID": 0,
+                    "companySHID": 1,
+                    "salesmanUID": 0,
+                    "channelOrderID": "",
+                    "channelOrderState": "0",
+                    "channelOrderDate": null,
+                    "channelOrderData": {}
+                },
+                {
+                    "erpID": "",
+                    "erpName": "erpedsdf",
+                    "erpNumber": "",
+                    "erpLastUpdate": "2020-01-16T10:27:18",
+                    "erpCreation": "2020-01-16T10:27:18",
+                    "archived": false,
+                    "oid": 1002,
+                    "orderDate": "2019-01-16T10:27:18",
+                    "orderState": 57,
+                    "orderLastStatusChange": "2019-03-16T10:38:53",
+                    "customerUID": 30,
+                    "customerNotice": "",
+                    "billingAddressAID": 16,
+                    "deliveryAddressAID": 16,
+                    "deliveryNotice": "",
+                    "paymentPID": 101,
+                    "assigndTickets": "",
+                    "resubmissionDate": "1970-01-01T12:00:00",
+                    "resubmissionInfo": "",
+                    "acquisitionPartnerID": 0,
+                    "acquisitionInfo": "",
+                    "acquisitionRedirect": null,
+                    "acquisitionDate": "1970-01-01T12:00:00",
+                    "shippingNotice": "",
+                    "shippingDCID": 2,
+                    "retoureRID": 0,
+                    "companySHID": 1,
+                    "salesmanUID": 0,
+                    "channelOrderID": "",
+                    "channelOrderState": "0",
+                    "channelOrderDate": null,
+                    "channelOrderData": {}
+                }
+            ],
+            "sys": {
+                "pagination": {
+                    "currentPage": 1,
+                        "nextOffset": 3,
+                        "pages": 1,
+                        "prevOffset": null,
+                        "offset": 0,
+                        "objectsPerPage": 20,
+                        "total": 3
+                },
+                "message": "200 OK",
+                    "code": 200
+            }}`
+
+const data = JSON.parse(json)
+
+
+const requestDelay = 1000
+
+
+export default [
+    {
+        url: '/demo/bind-with-datasource/data.json',
+        method: 'get',
+        rawResponse: async (req, res) => {
+            res.setHeader('Content-Type', 'application/json')
+            res.statusCode = 200
+
+            setTimeout(function() {
+                res.end(json)
+            }, requestDelay);
+
+
+        },
+        
+    },
+    {
+        url: '/demo/bind-with-datasource/data.json',
+        method: 'post',
+        rawResponse: async (req, res) => {
+            let reqbody = ''
+            await new Promise((resolve) => {
+                req.on('data', (chunk) => {
+                    reqbody += chunk
+                })
+                req.on('end', () => resolve(undefined))
+            })
+            res.setHeader('Content-Type', 'application/json')
+            res.statusCode = 200
+
+            setTimeout(function() {
+                res.end("{}")
+            }, requestDelay);
+            
+           
+        },
+    },
+];
\ No newline at end of file
diff --git a/showroom/video/monster-width-toggle/index.html b/showroom/video/monster-width-toggle/index.html
new file mode 100644
index 000000000..3ff8e0754
--- /dev/null
+++ b/showroom/video/monster-width-toggle/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0">
+
+    <title>Monster</title>
+    <script src="./script.mjs" type="module"></script>
+</head>
+<body>
+
+
+<main>
+
+    <h1>Width Toggle Control</h1>
+
+
+    <monster-width-toggle> 
+        <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
+            adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
+            adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
+            adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
+            adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem sit amet consectetur adipisicing elit.
+            Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur
+            adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit
+        </div>
+
+
+    </monster-width-toggle>
+
+
+
+
+</main>
+
+</body>
+</html>
diff --git a/showroom/video/monster-width-toggle/script.mjs b/showroom/video/monster-width-toggle/script.mjs
new file mode 100644
index 000000000..87a1edd6d
--- /dev/null
+++ b/showroom/video/monster-width-toggle/script.mjs
@@ -0,0 +1,51 @@
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/normalize.pcss";
+// import "../../../source/components/style/color.pcss";
+// import "../../../source/components/style/link.pcss";
+// import "../../../source/components/style/button.pcss";
+// import "../../../source/components/style/theme.pcss";
+import "../../../source/components/style/typography.pcss";
+import "../../../source/components/form/select.mjs";
+
+import "../../../source/components/form/button.mjs";
+import "../../../source/components/host/overlay.mjs";
+import "../../../source/components/datatable/datatable.mjs";
+import "../../../source/components/datatable/dataset.mjs";
+import "../../../source/components/datatable/datasource/dom.mjs";
+import "../../../source/components/datatable/datasource/rest.mjs";
+import "../../../source/components/datatable/save-button.mjs";
+
+import "../../../source/components/style/color.pcss";
+import "../../../source/components/style/theme.pcss";
+import "../../../source/components/style/table.pcss";
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/badge.pcss";
+import "../../../source/components/style/button.pcss";
+import "../../../source/components/style/link.pcss";
+import "../../../source/components/style/data-grid.pcss";
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/typography.pcss";
+import "../../../source/components/style/display.pcss";
+import "../../../source/components/datatable/datasource/rest.mjs";
+import "../../../source/components/datatable/filter.mjs";
+import "../../../source/components/datatable/filter-button.mjs";
+import "../../../source/components/datatable/embedded-pagination.mjs";
+import "../../../source/components/datatable/datatable.mjs";
+import "../../../source/components/datatable/dataset.mjs";
+import "../../../source/components/datatable/status.mjs";
+import "../../../source/components/datatable/save-button.mjs";
+import "../../../source/components/datatable/change-button.mjs";
+import "../../../source/components/datatable/filter/range.mjs";
+import "../../../source/components/datatable/filter/select.mjs";
+import "../../../source/components/datatable/filter/input.mjs";
+import "../../../source/components/datatable/filter/date-range.mjs";
+import {windowReady} from "../../../source/dom/ready.mjs";
+import "../../../source/components/host/host.mjs";
+import "../../../source/components/form/button.mjs";
+import "../../../source/components/form/button-bar.mjs";
+import "../../../source/components/form/popper-button.mjs";
+import "../../../source/components/layout/tabs.mjs";
+import "../../../source/components/layout/width-toggle.mjs";
+
+import "./style.pcss";
+
diff --git a/showroom/video/monster-width-toggle/style.pcss b/showroom/video/monster-width-toggle/style.pcss
new file mode 100644
index 000000000..c35f7a1ae
--- /dev/null
+++ b/showroom/video/monster-width-toggle/style.pcss
@@ -0,0 +1,11 @@
+
+
+
+main {
+    margin-top: 5rem;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+
+}
\ No newline at end of file
diff --git a/showroom/vite.config.js b/showroom/vite.config.js
new file mode 100644
index 000000000..12b702194
--- /dev/null
+++ b/showroom/vite.config.js
@@ -0,0 +1,99 @@
+// vite.config.js
+import {basename, resolve, join} from 'path'
+import {defineConfig} from 'vite'
+import {existsSync} from 'fs'
+import banner from 'vite-plugin-banner'
+import pkg from '../package.json'
+
+import cssnano from 'cssnano';
+import normalizeCss from 'postcss-normalize';
+import postcssFluid from 'postcss-fluid';
+import importCss from 'postcss-import';
+import postcssNesting from 'postcss-nesting';
+import postcssFor from 'postcss-for';
+import autoprefixer from 'autoprefixer';
+import postcssMixins from 'postcss-mixins';
+import postcssResponsiveType from 'postcss-responsive-type';
+
+import {ViteMinifyPlugin} from 'vite-plugin-minify'
+
+import { viteMockServe } from 'vite-plugin-mock';
+
+
+import directoryIndex from 'vite-plugin-directory-index';
+
+function getAppRootDir() {
+    let currentDir = __dirname
+    while (!existsSync(join(currentDir, 'package.json'))) {
+        currentDir = join(currentDir, '..')
+    }
+    return currentDir
+}
+
+const rootDir = getAppRootDir()
+const showRoomDir = join(rootDir, 'showroom')
+
+export default defineConfig({
+    clearScreen: false,
+
+    appType: 'mpa',
+    root: showRoomDir,
+    mode: 'development',
+    logLevel: 'info',
+    esbuild: {
+        minifyIdentifiers: true,
+        minifySyntax: true,
+        minifyWhitespace: true,
+        target: 'es2015',
+        legalComments: 'none'
+    },
+    plugins: [
+        banner(
+            `/**\n * name: ${pkg.name}\n * version: v${pkg.version}\n * description: ${pkg.description}\n * author: ${pkg.author}\n * homepage: ${pkg.homepage}\n */`
+        ),
+
+        ViteMinifyPlugin(),
+        // directoryPlugin({
+        //     baseDir: __dirname
+        // }),
+        directoryIndex({    }),
+
+    viteMockServe({
+        mockPath:showRoomDir+ "/mock", 
+    })
+    ],
+    css: {
+        postcss: {
+            plugins: [
+                importCss(),
+                normalizeCss,
+                postcssMixins,
+                postcssNesting(),
+                postcssFor,
+                postcssFluid({
+                    // Defaults:
+                    min: '320px', // Min media size
+                    max: '1800px', // Max media size
+                    functionName: 'fluid', // function name, may be anything
+                }), // https://github.com/notiv-nt/postcss-fluid
+                autoprefixer,
+                cssnano,
+                postcssResponsiveType
+            ]
+        }
+    },
+
+    server: {
+
+        port: 8070,
+        host: "localhost",
+        https: false,
+        debug: true,
+        ssl: {
+            key: resolve(__dirname, 'ssl/localhost.key'),
+            cert: resolve(__dirname, 'ssl/localhost.crt'),
+        }
+    },
+
+
+})
diff --git a/source/components/layout/style/width-toggle.pcss b/source/components/layout/style/width-toggle.pcss
index 1d26fa83a..5c55cedb0 100644
--- a/source/components/layout/style/width-toggle.pcss
+++ b/source/components/layout/style/width-toggle.pcss
@@ -10,17 +10,34 @@
     background-size: cover;
     width: 1rem;
     height: 1rem;
+    position: absolute;
+    right: 0;
+    top: -1rem;
+    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3C/svg%3E");
+    cursor: pointer;
+    transition: right 0.5s ease-in-out;
 }
 
 [data-monster-role="toggle"][data-monster-state="wide"] {
-    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-arrows-angle-contract' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M.172 15.828a.5.5 0 0 0 .707 0l4.096-4.096V14.5a.5.5 0 1 0 1 0v-3.975a.5.5 0 0 0-.5-.5H1.5a.5.5 0 0 0 0 1h2.768L.172 15.121a.5.5 0 0 0 0 .707M15.828.172a.5.5 0 0 0-.707 0l-4.096 4.096V1.5a.5.5 0 1 0-1 0v3.975a.5.5 0 0 0 .5.5H14.5a.5.5 0 0 0 0-1h-2.768L15.828.879a.5.5 0 0 0 0-.707'/%3E%3C/svg%3E")
+    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M.172 15.828a.5.5 0 0 0 .707 0l4.096-4.096V14.5a.5.5 0 1 0 1 0v-3.975a.5.5 0 0 0-.5-.5H1.5a.5.5 0 0 0 0 1h2.768L.172 15.121a.5.5 0 0 0 0 .707M15.828.172a.5.5 0 0 0-.707 0l-4.096 4.096V1.5a.5.5 0 1 0-1 0v3.975a.5.5 0 0 0 .5.5H14.5a.5.5 0 0 0 0-1h-2.768L15.828.879a.5.5 0 0 0 0-.707'/%3E%3C/svg%3E")
 }
 
 [data-monster-role="toggle"][data-monster-state="small"] {
-    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-arrows-angle-expand' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707'/%3E%3C/svg%3E");
+    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707'/%3E%3C/svg%3E");
 }
 
-[data-monster-role="container"] {
+[data-monster-role=container] {
     box-sizing: border-box;
-    transition: width 0.5s ease-in-out;
-}
\ No newline at end of file
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    
+    & [data-monster-role="inside"] {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        transition: width 0.5s ease-in-out;
+    }
+    
+}
diff --git a/source/components/layout/stylesheet/width-toggle.mjs b/source/components/layout/stylesheet/width-toggle.mjs
index c0b3315cd..716d61466 100644
--- a/source/components/layout/stylesheet/width-toggle.mjs
+++ b/source/components/layout/stylesheet/width-toggle.mjs
@@ -20,7 +20,7 @@ const WidthToggleStyleSheet = new CSSStyleSheet();
 try {
   WidthToggleStyleSheet.insertRule(`
 @layer widthtoggle { 
- 
+[data-monster-role=toggle]{background-color:var(--monster-bg-color-primary-4);background-position:50%;background-repeat:no-repeat;background-size:cover;cursor:pointer;height:1rem;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'/%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'/%3E\");position:absolute;right:0;top:-1rem;transition:right .5s ease-in-out;width:1rem}[data-monster-role=toggle][data-monster-state=wide]{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M.172 15.828a.5.5 0 0 0 .707 0l4.096-4.096V14.5a.5.5 0 1 0 1 0v-3.975a.5.5 0 0 0-.5-.5H1.5a.5.5 0 0 0 0 1h2.768L.172 15.121a.5.5 0 0 0 0 .707M15.828.172a.5.5 0 0 0-.707 0l-4.096 4.096V1.5a.5.5 0 1 0-1 0v3.975a.5.5 0 0 0 .5.5H14.5a.5.5 0 0 0 0-1h-2.768L15.828.879a.5.5 0 0 0 0-.707'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M.172 15.828a.5.5 0 0 0 .707 0l4.096-4.096V14.5a.5.5 0 1 0 1 0v-3.975a.5.5 0 0 0-.5-.5H1.5a.5.5 0 0 0 0 1h2.768L.172 15.121a.5.5 0 0 0 0 .707M15.828.172a.5.5 0 0 0-.707 0l-4.096 4.096V1.5a.5.5 0 1 0-1 0v3.975a.5.5 0 0 0 .5.5H14.5a.5.5 0 0 0 0-1h-2.768L15.828.879a.5.5 0 0 0 0-.707'/%3E%3C/svg%3E\")}[data-monster-role=toggle][data-monster-state=small]{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707'/%3E%3C/svg%3E\")}[data-monster-role=container]{align-items:center;box-sizing:border-box;display:flex;justify-content:center;position:relative}[data-monster-role=container] [data-monster-role=inside]{align-items:center;display:flex;justify-content:center;transition:width .5s ease-in-out} 
 }`, 0);
 } catch (e) {
   addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
diff --git a/source/components/layout/width-toggle.mjs b/source/components/layout/width-toggle.mjs
index 29471c026..46cba9639 100644
--- a/source/components/layout/width-toggle.mjs
+++ b/source/components/layout/width-toggle.mjs
@@ -3,19 +3,20 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
+import {addAttributeToken} from "../../dom/attributes.mjs";
+import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
 import {
     assembleMethodSymbol,
     CustomElement,
     registerCustomElement,
 } from "../../dom/customelement.mjs";
-import "../notify/notify.mjs";
 import {fireCustomEvent} from "../../dom/events.mjs";
 import {Observer} from "../../types/observer.mjs";
 import {WidthToggleStyleSheet} from "./stylesheet/width-toggle.mjs";
 import {instanceSymbol} from "../../constants.mjs";
 import {internalSymbol} from "../../constants.mjs";
 
-export {WidthToggle, TYPE_VERTICAL, TYPE_HORIZONTAL};
+export {WidthToggle, MODE_SMALL, MODE_WIDE};
 
 /**
  * @private
@@ -28,6 +29,22 @@ const widthToggleElementSymbol = Symbol("WidthToggleElement");
  * @type {symbol}
  */
 const toggleElementSymbol = Symbol("toggleElement");
+/**
+ * @private
+ * @type {symbol}
+ */
+const insideElementSymbol = Symbol("insideElement");
+
+/**
+ *
+ * @type {string}
+ */
+const MODE_SMALL = "small";
+/**
+ *
+ * @type {string}
+ */
+const MODE_WIDE = "wide";
 
 /**
  * The WidthToggle component is used to change the width of a panel.
@@ -38,14 +55,14 @@ const toggleElementSymbol = Symbol("toggleElement");
  * Javascript via the `document.createElement('monster-split-screen');` method.
  *
  * ```html
- * <monster-split-screen></monster-split-screen>
+ * <monster-width-toggle></monster-width-toggle>
  * ```
  *
  * Or you can create this CustomControl directly in Javascript:
  *
  * ```js
- * import '@schukai/monster/components/layout/split-screen.mjs';
- * document.createElement('monster-split-screen');
+ * import '@schukai/monster/components/layout/width-toggle.mjs';
+ * document.createElement('monster-width-toggle');
  * ```
  *
  * @startuml widthToggle.png
@@ -76,7 +93,7 @@ class WidthToggle extends CustomElement {
      * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
      *
      * The individual configuration values can be found in the table.
-     *
+     * 
      * @property {Object} templates Template definitions
      * @property {string} templates.main Main template
      * @property {string} splitType Split type (vertical or horizontal)
@@ -90,36 +107,14 @@ class WidthToggle extends CustomElement {
             templates: {
                 main: getTemplate(),
             },
-            splitType: TYPE_VERTICAL,
-            dimension: {
-                initial: "60%",
-                max: "80%",
-                min: "20%",
+            width: {
+                small: "40%",
+                wide: "95%",
             },
+            default: MODE_SMALL,
         });
     }
 
-    fullStartScreen() {
-        this.setDimension("100%");
-        return this;
-    }
-
-    fullEndScreen() {
-        this.setDimension("0%");
-        return this;
-    }
-
-    resetScreen() {
-        this.setDimension(this.getOption("dimension").initial);
-        return this;
-    }
-
-
-    setContent(html) {
-        this.setOption("content", html);
-        return this;
-    }
-
     /**
      *
      * @returns {Monster.Components.Host.Viewer}
@@ -129,27 +124,19 @@ class WidthToggle extends CustomElement {
 
         initControlReferences.call(this);
         initEventHandler.call(this);
-        //applyContainerWidth.call(this);
-        this.setDimension(this.getOption("dimension").initial);
+        applyContainerWidth.call(this, this.getOption("default"));
+
     }
 
     /**
      * Check if the dimension is a percentage and within a valid range, then set the dimension option.
      *
-     * @param {string} width - The dimension to be set, can be in percentage or absolute value.
+     * @param {string} mode - The mode of the panel. Possible values are "wide" or "small".
      * @return {Object} - Returns the current object instance for chaining.
+     * @throws {Error} - If the mode is not supported.
      */
-    setWidth(width) {
-        // check if percent and greater than100
-        if (width.includes("%")) {
-            if (parseInt(width) > 100) {
-                throw new Error("width must be less than 100%");
-            } else if (parseInt(width) < 0) {
-                throw new Error("width must be greater than 0%");
-            }
-        }
-
-        this.setOption("width", width);
+    setWidth(mode) {
+        applyContainerWidth.call(this, mode);
         return this;
     }
 
@@ -173,21 +160,36 @@ class WidthToggle extends CustomElement {
 
 /**
  * Set the dimensions of the panel based on the split type.
+ * @param {string} mode - The mode of the panel. Possible values are "wide" or "small".
  * @fires Monster.Components.Layout.event:monster-dimension-changed
  */
-function applyContainerWidth() {
+function applyContainerWidth(mode) {
 
-    let width = this.getOption("width");
+    const width = this.getOption("width." + mode)
     if (!width) {
-        width = "100%";
+        addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+        throw new Error("unsupported mode");
     }
 
-    this[widthToggleElementSymbol].style.width = width;
+    switch (mode) {
+        case MODE_SMALL:
+        case MODE_WIDE:
 
-    fireCustomEvent(this, "monster-dimension-changed", {
-        controller: this,
-        dimension: width
-    });
+            this[toggleElementSymbol].style.right = "calc( 50% - (" + width + " / 2) + 1rem)"
+            this[toggleElementSymbol].setAttribute("data-monster-state", mode);
+            this[insideElementSymbol].style.width = width;
+
+            fireCustomEvent(this, "monster-dimension-changed", {
+                controller: this,
+                dimension: width
+            });
+            break;
+
+        default:
+            const error = new Error("unsupported mode")
+            addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.message);
+            throw error;
+    }
 
 }
 
@@ -202,8 +204,9 @@ function initControlReferences() {
         throw new Error("no shadow-root is defined");
     }
 
-    this[widthToggleElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=width-toggle]");
+    this[widthToggleElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=control]");
     this[toggleElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=toggle]");
+    this[insideElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=inside]");
 
 
 }
@@ -214,10 +217,10 @@ function initControlReferences() {
 function initEventHandler() {
     const self = this;
 
-    this[internalSymbol].attachObserver(
-        new Observer(() => {
-            applyContainerWidth.call(self);
-        }));
+    this[toggleElementSymbol].addEventListener("click", function () {
+        const mode = self[toggleElementSymbol].getAttribute("data-monster-state") === MODE_SMALL ? MODE_WIDE : MODE_SMALL;
+        applyContainerWidth.call(self, mode);
+    });
 
 
     return this;
@@ -231,10 +234,12 @@ function initEventHandler() {
 function getTemplate() {
     // language=HTML
     return `
-        <div data-monster-role="width-toggle" part="control">
+        <div data-monster-role="control" part="control">
             <div part="container" data-monster-role="container">
-                <div data-monster-role="toggle">ICON</div>
-                <slot></slot>
+                <div part="toggle" data-monster-role="toggle" data-monster-state="wide"></div>
+                <div part="inside" data-monster-role="inside">
+                    <slot></slot>
+                </div>
             </div>
         </div>`;
 }
-- 
GitLab