Skip to content
Snippets Groups Projects
Verified Commit 7aa2e062 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: integrate components, test, example and code #127

parent d24fe162
Branches
Tags
No related merge requests found
Showing
with 486 additions and 262 deletions
......@@ -76,7 +76,7 @@ We do try to work around some browser bugs, but on the whole we don't use polyfi
However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased.
```html
<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,console,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,MutationObserver,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.every,Array.prototype.fill,Array.prototype.filter,Array.prototype.find,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.some,Array.prototype.sort,Array.prototype.values,ArrayBuffer,atob,Blob,console,CustomEvent,DataView,Date.prototype.toISOString,document,Document,DocumentFragment,Element,Event,fetch,Function.prototype.bind,getComputedStyle,globalThis,HTMLDocument,HTMLTemplateElement,IntersectionObserver,Intl,JSON,Map,Math.log2,MutationObserver,Number.isFinite,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,requestAnimationFrame,ResizeObserver,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
```
......
......@@ -64,3 +64,11 @@ tasks:
- bp
cmds:
- build-and-publish
build-stylesheets:
silent: true
desc: Build the stylesheets javascript files
aliases:
- bs
cmds:
- build-stylesheets
\ No newline at end of file
......@@ -220,9 +220,22 @@ fi
'';
scripts.build-stylesheets.exec = ''
components=$(${pkgs.coreutils}/bin/ls -d ${config.devenv.root}/source/components/*/ | \
${pkgs.gnused}/bin/sed -E "s|${config.devenv.root}/source/||g" | \
${pkgs.gnused}/bin/sed -E "s|/$||g" | ${pkgs.gnugrep}/bin/grep -v style )
for component in $components; do
${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path $component
done
${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path "components/"
'';
scripts.run-tests.exec = ''
update-versions
${pkgs.nodePackages.pnpm}/bin/pnpm mocha --recursive test/cases/
${pkgs.nodePackages.pnpm}/bin/pnpm mocha --colors --jobs 10 --bail --recursive test/cases/
'';
scripts.build-monster-mjs.exec = ''
......@@ -246,10 +259,16 @@ find ''${TEST_CASES_PATH} -type f | sed "s|^$TEST_CASES_PATH||" > ''${TEST_PATH}
sed -i 's|^|import "../cases/|' ''${TEST_PATH}web/import.js
sed -i 's|$|";|' ''${TEST_PATH}web/import.js
sed -i "1 i import \"./prepare.js\";" ''${TEST_PATH}web/import.js
sed -i "1 i /** this file was created automatically by the make target test-browser-monster */" ''${TEST_PATH}web/import.js
sed -i "1 i /** this file was created automatically by the run-web-tests script */" ''${TEST_PATH}web/import.js
npx esbuild --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle ''${TEST_PATH}web/import.js --outfile=''${TEST_PATH}web/tests.js
sed -i '1s/^/try {\n/' ''${TEST_PATH}web/tests.js
echo "} catch (e) {" >> ''${TEST_PATH}web/tests.js
echo "document.getElementById('mocha-errors').insertAdjacentHTML('afterbegin', e );" >> ''${TEST_PATH}web/tests.js
echo "document.getElementById('mocha-stats').style.backgroundColor = 'red';" >> ''${TEST_PATH}web/tests.js
echo "}" >> ''${TEST_PATH}web/tests.js
sed -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster ''${VERSION}</h1>_" ''${TEST_PATH}web/test.html
sed -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(date)</div>_" ''${TEST_PATH}web/test.html
sed -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(date +"%T")\"_" ''${TEST_PATH}web/test.html
......
import {Button} from '@schukai/component-form/source/button.js';
const button = document.createElement('monster-button');
// set label
button.setOption('labels.button', 'Click')
// add action for click
button.setOption('actions.click', function (e) {
console.log(e);
})
document.body.appendChild(button)
import {Select} from '@schukai/component-form/source/select.js';
const select = document.createElement('monster-select');
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
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",
}
]);
document.body.appendChild(select);
\ No newline at end of file
import {TreeSelect} from '@schukai/component-form/source/tree-select.mjs';
const treeSelect = document.createElement('monster-tree-select');
treeSelect.setOption('mapping.valueTemplate', '${name} (${alpha-2})')
treeSelect.setOption('mapping.labelTemplate', '${country-code}')
treeSelect.importOptions([
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
"parent": undefined
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
"parent": undefined
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
"parent": undefined
}
]);
document.body.appendChild(treeSelect);
import {Notify} from '@schukai/component-notify/source/message.js';
const notify = document.createElement('monster-notify');
document.body.appendChild(notify);
import {Notify} from '@schukai/component-notify/source/notify.mjs';
const notify = document.createElement('monster-notify');
document.body.appendChild(notify);
\ No newline at end of file
#!/usr/bin/env node
const regex = /^\s*(?<exp>(export\s+{[^}]+)})/gm;
const fs = require('fs');
const path = require('path')
const os = require('os');
const path = require('path');
const postcss = require('postcss');
const cssnano = require('cssnano');
const normalizeCss = require('postcss-normalize');
const postcssFluid = require('postcss-fluid');
const importCss = require('postcss-import');
const postcssNested = require('postcss-nested');
const postcssNesting = require('postcss-nesting');
const postcssFor = require('postcss-for');
//const postcssRtlcss = require('postcss-rtlcss');
const autoprefixer = require('autoprefixer');
const styleSourceRoot = __dirname + '/../../application/source/style/'
const styleSheetRoot = __dirname + '/../../application/source/stylesheet/'
const postcssMixins = require('postcss-mixins');
const postcssStripUnits = require('postcss-strip-units');
const args = process.argv.slice(2);
if (args.length < 1) {
console.log("Usage: node build-stylesheets.js <project-root>");
process.exit(1);
}
const projectRoot = args[0];
if (!fs.existsSync(projectRoot)) {
console.log("Project root " + projectRoot + " does not exist");
process.exit(1);
}
let relPath = null;
for (let i = 0; i < args.length; i++) {
if (args[i] === '--rel-path') {
relPath = args[i + 1];
}
}
if (relPath === null || relPath === undefined || relPath === "") {
console.error("Relativ path must be set");
console.log("Usage: node build-stylesheets.js --relPath <relativ-path>");
process.exit(1);
}
if (relPath.substr(-1) !== '/') {
relPath += '/';
}
if (relPath.substr(0, 1) === '/') {
console.error("Relativ path must not start with /");
console.log("Usage: node build-stylesheets.js --relPath <relativ-path>");
process.exit(1);
}
// build rel, return path ../ to root
let backToRootPath = "";
const parts = relPath.split("/");
for (let i = 0; i < parts.length; i++) {
backToRootPath += "../";
}
const absoluteProjectRoot = path.resolve(projectRoot) + "/";
const absoluteSourcePath = absoluteProjectRoot + 'source/';
const styleSourceRoot = absoluteSourcePath + relPath + 'style/'
const styleSheetRoot = absoluteSourcePath + relPath + 'stylesheet/'
const nodeModuleStyleSourceRoot = absoluteProjectRoot + 'node_modules/'
if (!fs.existsSync(styleSourceRoot)) {
console.log("Style source root " + styleSourceRoot + " does not exist");
process.exit(1);
}
if (!fs.existsSync(nodeModuleStyleSourceRoot)) {
console.log("Node module style source root " + nodeModuleStyleSourceRoot + " does not exist");
process.exit(1);
}
if (!fs.existsSync(styleSheetRoot)) {
fs.mkdirSync(styleSheetRoot);
}
let promises = [];
let styles = new Map();
const packageJsonPath = absoluteProjectRoot + 'package.json';
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const copyRightYear = new Date().getFullYear();
const codeTemplate = `
/**
* Copyright schukai GmbH and contributors 2022. All Rights Reserved.
* Node module: @schukai/component-empty-state
* Copyright schukai GmbH and contributors ${copyRightYear}. All Rights Reserved.
* Node module: ${packageJson.name}
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import {addAttributeToken} from "@schukai/monster/source/dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "@schukai/monster/source/dom/constants.mjs";
import {addAttributeToken} from "` + backToRootPath + `dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "` + backToRootPath + `dom/constants.mjs";
export {{{ClassName}}StyleSheet}
/**
* @private
* @type {CSSStyleSheet}
*/
export const {{ClassName}}Stylesheet = new CSSStyleSheet();
const {{ClassName}}StyleSheet = new CSSStyleSheet();
try {
{{ClassName}}Stylesheet.insertRule(\`
@layer component {
{{ClassName}}StyleSheet.insertRule(\`
@layer {{LayerName}} {
{{css}}
}\`, 0);
} catch (e) {
......@@ -62,9 +133,13 @@ function scanFiles(root, keyPath) {
const currentPath = [...keyPath]
currentPath.push(key);
if (f.isDirectory()) {
localPromises.push(scanFiles(fn), currentPath);
if (["node_modules", "mixin"].includes(f.name)) {
continue;
}
localPromises.push(scanFiles(fn, currentPath));
continue;
} else if (!f.isFile()) {
continue;
......@@ -74,10 +149,13 @@ function scanFiles(root, keyPath) {
continue;
}
//console.log("Found file: " + fn);
let content = fs.readFileSync(fn, 'utf8');
localPromises.push(rewriteCSS(content, fn, currentPath));
}
dir.closeSync();
Promise.all(localPromises).then(resolve).catch(reject);
})
......@@ -90,40 +168,77 @@ function rewriteCSS(content, sourceFile, keyPath) {
return new Promise((resolve, reject) => {
return postcss([
importCss({
path: [styleSourceRoot],
path: [absoluteSourcePath, nodeModuleStyleSourceRoot, styleSourceRoot],
root: absoluteProjectRoot,
resolve: (id, basedir, importOptions, astNode) => {
firstTry = path.join(basedir, id);
if (fs.existsSync(firstTry)) {
return firstTry;
}
const dir = path.dirname(sourceFile);
const fn = path.join(dir, id);
return fs.realpathSync(fn);
}
}),
normalizeCss,
postcssNested(),
postcssMixins,
postcssNesting(),
postcssFor(),
postcssStripUnits({
functionName: 'strip-units',
}),
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,
//postcssRtlcss,
cssnano
]).process(content, {
from: undefined,
}).catch(reject).then(result => {
}).catch((e) => {
reject(e + " in file " + sourceFile);
}).then(result => {
if (result === undefined || result.css === undefined) {
reject("Error processing file " + sourceFile);
return;
}
styles.set(newPath, result.css);
resolve();
}).catch((e) => {
console.error(e);
});
})
}
scanFiles(path.normalize(styleSourceRoot)).then(() => {
styles.forEach((css, fn) => {
let className = path.parse(fn).name;
className = className.charAt(0).toUpperCase() + className.slice(1);
className = className.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
className = className.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
});
let layerName = className.toLowerCase();
css = css.replace(/"/g, '\\"');
const code = codeTemplate.replaceAll("{{ClassName}}", className).replaceAll("{{css}}", css);
const code = codeTemplate
.replaceAll("{{ClassName}}", className)
.replaceAll("{{LayerName}}", layerName)
.replaceAll("{{css}}", css);
const targetFile = path.normalize(path.join(styleSheetRoot, fn));
fs.mkdirSync(path.dirname(targetFile), {recursive: true});
......@@ -131,7 +246,6 @@ scanFiles(path.normalize(styleSourceRoot)).then(() => {
})
}).catch(e => {
console.log("Error styles.css");
console.log("Error creating stylesheets");
console.error(e);
})
console.log("Done");
const fs = require('fs');
const os = require('os');
const path = require('path');
const postcss = require('postcss');
const cssnano = require('cssnano');
const normalizeCss = require('postcss-normalize');
const postcssFluid = require('postcss-fluid');
const importCss = require('postcss-import');
const postcssNesting = require('postcss-nesting');
const postcssFor = require('postcss-for');
const postcssRtlcss = require('postcss-rtlcss');
const autoprefixer = require('autoprefixer');
const postcssMixins = require('postcss-mixins');
const postcssStripUnits = require('postcss-strip-units');
const args = process.argv.slice(2);
if (args.length < 1) {
console.log("Usage: node build-stylesheets.js <project-root>");
process.exit(1);
}
const projectRoot = args[0];
if (!fs.existsSync(projectRoot)) {
console.log("Project root " + projectRoot + " does not exist");
process.exit(1);
}
const absoluteProjectRoot = path.resolve(projectRoot) + "/";
const styleSourceRoot = absoluteProjectRoot + 'application/source/style/'
const nodeModuleStyleSourceRoot = absoluteProjectRoot + 'development/node_modules/'
const styleSheetRoot = absoluteProjectRoot + 'application/source/stylesheet/'
if (!fs.existsSync(styleSourceRoot)) {
console.log("Style source root " + styleSourceRoot + " does not exist");
process.exit(1);
}
if (!fs.existsSync(nodeModuleStyleSourceRoot)) {
console.log("Node module style source root " + nodeModuleStyleSourceRoot + " does not exist");
process.exit(1);
}
if (!fs.existsSync(styleSheetRoot)) {
fs.mkdirSync(styleSheetRoot);
}
let promises = [];
let styles = new Map();
const packageJsonPath = absoluteProjectRoot + 'development/package.json';
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const copyRightYear = new Date().getFullYear();
const codeTemplate = `
/**
* Copyright schukai GmbH and contributors ${copyRightYear}. All Rights Reserved.
* Node module: ${packageJson.name}
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import {addAttributeToken} from "@schukai/monster/source/dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "@schukai/monster/source/dom/constants.mjs";
export {{{ClassName}}StyleSheet}
/**
* @private
* @type {CSSStyleSheet}
*/
const {{ClassName}}StyleSheet = new CSSStyleSheet();
try {
{{ClassName}}StyleSheet.insertRule(\`
@layer {{LayerName}} {
{{css}}
}\`, 0);
} catch (e) {
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
}
`;
function scanFiles(root, keyPath) {
if (keyPath === undefined) {
keyPath = [];
}
return new Promise((resolve, reject) => {
let localPromises = [];
let f;
const dir = fs.opendirSync(root);
while ((f = dir.readSync()) !== null) {
const key = f.name;
const fn = path.join(root, f.name);
const currentPath = [...keyPath]
currentPath.push(key);
if (f.isDirectory()) {
if (["node_modules","mixin"].includes(f.name)) {
continue;
}
localPromises.push(scanFiles(fn, currentPath));
continue;
} else if (!f.isFile()) {
continue;
}
if ((path.extname(f.name) !== ".css" && path.extname(f.name) !== ".pcss")) {
continue;
}
console.log("Found file: " + fn);
let content = fs.readFileSync(fn, 'utf8');
localPromises.push(rewriteCSS(content, fn, currentPath));
}
dir.closeSync();
Promise.all(localPromises).then(resolve).catch(reject);
})
}
function rewriteCSS(content, sourceFile, keyPath) {
const newPath = path.format({...path.parse(keyPath.join("/")), base: '', ext: '.mjs'})
return new Promise((resolve, reject) => {
return postcss([
importCss({
path: [styleSourceRoot, nodeModuleStyleSourceRoot],
}),
normalizeCss,
postcssMixins,
postcssNesting(),
postcssFor(),
postcssStripUnits({
functionName: 'strip-units',
}),
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,
//postcssRtlcss,
cssnano
]).process(content, {
from: undefined,
}).catch((e) => {
reject(e + " in file " + sourceFile);
}).then(result => {
styles.set(newPath, result.css);
resolve();
});
})
}
scanFiles(path.normalize(styleSourceRoot)).then(() => {
styles.forEach((css, fn) => {
let className = path.parse(fn).name;
className = className.charAt(0).toUpperCase() + className.slice(1);
className = className.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
});
let layerName = className.toLowerCase();
css = css.replace(/"/g, '\\"');
const code = codeTemplate
.replaceAll("{{ClassName}}", className)
.replaceAll("{{LayerName}}", layerName)
.replaceAll("{{css}}", css);
const targetFile = path.normalize(path.join(styleSheetRoot, fn));
fs.mkdirSync(path.dirname(targetFile), {recursive: true});
fs.writeFileSync(targetFile, code);
})
}).catch(e => {
console.log("Error styles.css");
console.error(e);
})
console.log("Done");
{
"name": "@schukai/monster",
"version": "3.51.5",
"version": "4.0.0",
"description": "Monster is a simple library for creating fast, robust and lightweight websites.",
"keywords": [
"framework",
......@@ -39,26 +39,31 @@
},
"author": "schukai GmbH",
"license": "AGPL 3.0",
"dependencies": {
"@floating-ui/dom": "^1.5.3",
"@popperjs/core": "^2.11.8"
},
"devDependencies": {
"@biomejs/biome": "1.3.3",
"@peculiar/webcrypto": "^1.4.3",
"autoprefixer": "^10.4.14",
"browserslist": "^4.21.9",
"autoprefixer": "^10.4.16",
"browserslist": "^4.22.1",
"btoa": "^1.2.1",
"c8": "^8.0.0",
"chai": "^4.3.7",
"c8": "^8.0.1",
"chai": "^4.3.10",
"chai-dom": "^1.11.0",
"clean-jsdoc-theme": "^4.2.9",
"clean-jsdoc-theme": "^4.2.14",
"create-polyfill-service-url": "^2.2.6",
"crypt": "^0.0.2",
"cssnano": "^6.0.1",
"element-internals-polyfill": "^1.3.5",
"esbuild": "^0.18.4",
"dom-storage": "^2.1.0",
"element-internals-polyfill": "^1.3.9",
"esbuild": "^0.19.5",
"esdoc": "^1.1.0",
"esdoc-standard-plugin": "^1.0.0",
"flow-bin": "^0.209.0",
"flow-bin": "^0.220.0",
"fs": "0.0.1-security",
"glob": "^10.2.7",
"glob": "^10.3.10",
"graphviz": "^0.0.9",
"jsdoc": "^4.0.2",
"jsdoc-external-example": "github:volker-schukai/jsdoc-external-example",
......@@ -68,27 +73,27 @@
"jsdom-global": "^3.0.2",
"mocha": "^10.2.0",
"node-plantuml": "^0.9.0",
"postcss": "^8.4.24",
"postcss": "^8.4.31",
"postcss-fluid": "^1.4.2",
"postcss-for": "^2.1.1",
"postcss-import": "^15.1.0",
"postcss-load-config": "^4.0.1",
"postcss-mixins": "^9.0.4",
"postcss-nested": "^6.0.1",
"postcss-nesting": "^11.3.0",
"postcss-nesting": "^12.0.1",
"postcss-normalize": "^10.0.1",
"postcss-responsive-type": "^1.0.0",
"postcss-rtlcss": "^4.0.6",
"postcss-rtlcss": "^4.0.8",
"postcss-strip-units": "^2.0.1",
"puppeteer": "^21.4.1",
"sinon": "^15.1.2",
"url": "^0.11.1",
"puppeteer": "^21.5.0",
"sinon": "^17.0.1",
"url": "^0.11.3",
"url-exist": "3.0.1",
"util": "^0.12.5",
"vite": "^4.3.9",
"vite-plugin-banner": "^0.7.0",
"vite": "^4.5.0",
"vite-plugin-banner": "^0.7.1",
"vite-plugin-list-directory-contents": "^1.4.5",
"vite-plugin-minify": "^1.5.2",
"ws": "^8.13.0"
"ws": "^8.14.2"
}
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Typography</title>
<script src="./main.js" type="module"></script>
</head>
<body style="display:flex;justify-content: center">
<main style="width: 600px">
<h1>Badge</h1>
<div class="container">
<div>
<div class="monster-badge-primary">monster-badge-primary</div>
<div class="monster-badge-primary-pill">monster-badge-primary-pill</div>
</div>
<div>
<div class="monster-badge-secondary">monster-badge-secondary</div>
<div class="monster-badge-secondary-pill">monster-badge-secondary-pill</div>
</div>
<div>
<div class="monster-badge-tertiary">monster-badge-tertiary</div>
<div class="monster-badge-tertiary-pill">monster-badge-tertiary-pill</div>
</div>
<div>
<div class="monster-badge-destructive">monster-badge-destructive</div>
<div class="monster-badge-destructive-pill">monster-badge-destructive-pill</div>
</div>
<div>
<div class="monster-badge-success">monster-badge-success</div>
<div class="monster-badge-success-pill">monster-badge-success-pill</div>
</div>
<div>
<div class="monster-badge-warning">monster-badge-warning</div>
<div class="monster-badge-warning-pill">monster-badge-warning-pill</div>
</div>
<div>
<div class="monster-badge-error">monster-badge-error</div>
<div class="monster-badge-error-pill">monster-badge-error-pill</div>
</div>
</div>
</main>
</body>
</html>
\ No newline at end of file
import "@schukai/component-style/source/style/property.pcss";
import "@schukai/component-style/source/style/normalize.pcss";
import "@schukai/component-style/source/style/color.pcss";
import "@schukai/component-style/source/style/typography.pcss";
import "@schukai/component-style/source/style/theme.pcss";
import "@schukai/component-style/source/style/badge.pcss";
import "./main.pcss";
@import "@schukai/component-style/source/style/mixin/property.pcss";
.container {
font-size: 17px;
display: flex;
flex-direction: column;
}
.container > div {
padding: 10px;
}
@media (prefers-color-scheme: dark) {
html {
background-color: #000;
}
h1 {
color: #fff;
}
}
\ No newline at end of file
<!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>Typography</title>
<script src="./main.js" type="module"></script>
</head>
<body style="display:flex;justify-content: center">
<main style="width: 600px">
<h1 class="deco">Button</h1>
<p class="deco">Buttons are used to trigger actions. They are used in forms, dialogs, and more. They can be used as
links or as a button.</p>
<div class="container">
<div>
<button>button</button>
<button class="monster-button-primary">monster-button-primary</button>
<button class="monster-button-secondary">monster-button-secondary</button>
<button class="monster-button-tertiary">monster-button-tertiary</button>
<button class="monster-button-outline-primary">monster-button-outline-primary</button>
<button class="monster-button-outline-secondary">monster-button-outline-secondary</button>
<button class="monster-button-outline-tertiary">monster-button-outline-tertiary</button>
</div>
<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>
<div class="monster-button-bar">
<div class="monster-button-group">
<button class="monster-button-primary">monster-button-primary</button>
<button class="monster-button-secondary">monster-button-secondary</button>
<button class="monster-button-tertiary">monster-button-tertiary</button>
</div>
</div>
<div>
<button>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-archive" viewBox="0 0 16 16">
<path d="M0 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1v7.5a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 1 12.5V5a1 1 0 0 1-1-1V2zm2 3v7.5A1.5 1.5 0 0 0 3.5 14h9a1.5 1.5 0 0 0 1.5-1.5V5H2zm13-3H1v2h14V2zM5 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5z"/>
</svg>
This is a button with an icon
</button>
</div>
</div>
</main>
</body>
</html>
\ No newline at end of file
import "@schukai/component-style/source/style/property.pcss";
import "@schukai/component-style/source/style/normalize.pcss";
import "@schukai/component-style/source/style/color.pcss";
import "@schukai/component-style/source/style/typography.pcss";
import "@schukai/component-style/source/style/theme.pcss";
import "@schukai/component-style/source/style/button.pcss";
import "@schukai/component-style/source/style/ripple.pcss";
import "./main.pcss";
import "@schukai/component-style/source/style/space.pcss";
function createRipple(event) {
const button = event.currentTarget;
const circle = document.createElement("span");
const diameter = Math.max(button.clientWidth, button.clientHeight);
const radius = diameter / 2;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - button.offsetLeft - radius}px`;
circle.style.top = `${event.clientY - button.offsetTop - radius}px`;
circle.classList.add("monster-fx-ripple");
const ripples = button.getElementsByClassName("monster-fx-ripple");
for (const ripple of ripples) {
ripple.remove();
}
button.appendChild(circle);
}
const buttons = document.getElementsByTagName("button");
for (const button of buttons) {
button.addEventListener("click", createRipple);
}
@import "@schukai/component-style/source/style/mixin/property.pcss";
.container{
font-size: 12px;
display: flex;
flex-direction: column;
}
button {
margin: 20px 0 0 0;
}
@media (prefers-color-scheme: dark) {
html {
background-color: #000;
}
h1 {
color: #fff;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment