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