NEWS: Welcome to my new homepage! <3

Added css function - figure - Unnamed repository; edit this file 'description' to name the repository.

figure

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 2744b6551226a461212ab6e0a6b5b670be08d3f2
parent b6a9da2f1ee9cef6a445274aee8c27220628b6b5
Author: typable <contact@typable.dev>
Date:   Thu, 15 Sep 2022 18:44:56 +0200

Added css function

Diffstat:
Mexample.html | 73+++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mlib.js | 70+++++++++++++++++++++++++++++++++++++++++++++-------------------------
2 files changed, 92 insertions(+), 51 deletions(-)

diff --git a/example.html b/example.html @@ -1,28 +1,49 @@ +<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&family=Noto+Sans"> + <div id="app"></div> +<style> + + * { + font-family: 'Noto Sans', sans-serif; + } + + body { + margin: 0; + } + +</style> + <script type="module"> import {useState, createElement} from 'https://cdn.skypack.dev/react'; import {render} from 'https://cdn.skypack.dev/react-dom'; - import {createTlx} from './lib.js'; + import {createTlx, css} from './lib.js'; const tlx = createTlx(createElement); const Button = (props, $slot) => { const styles = { - minWidth: '40px', - height: '40px', - border: 'none', - outline: 'none', - border: '1px solid #a3a3a3', - backgroundColor: props.disabled ? '#f5f5f5' : '#e5e5e5', - cursor: props.disabled ? 'default' : 'pointer', - fontSize: '1rem', - fontFamily: 'Inter', + ...css` + min-width: 40px; + height: 40px; + border: none; + outline: none; + border: 1px solid #a3a3a3; + background-color: ${props.disabled ? '#f5f5f5' : '#e5e5e5'}; + cursor: ${props.disabled ? 'default' : 'pointer'}; + font-size: 1rem; + `, ...props.styles }; return tlx` - <button disabled="${props.disabled}" style="${styles}" @click="${() => props.onClick()}">${$slot}</button> + <button + disabled="${props.disabled}" + style="${styles}" + @click="${() => props.onClick()}" + > + ${$slot} + </button> `; } @@ -38,19 +59,19 @@ <div style="display: inline-flex; width: 100%; border: 1px solid #a3a3a3; border-radius: 4px; overflow: hidden; height: 40px; box-sizing: border-box;"> ${Button({ onClick: () => setValue(value - 1), - styles: { - fontSize: '1.2rem', - borderWidth: '0px 1px 0px 0px' - }, + styles: css` + font-size: 1.2rem; + border-width: 0px 1px 0px 0px; + `, disabled: value <= min }, '-')} <input type="text" @input="${(event) => validate(event.target.value)}" value="${value}" style="font-size: 1rem; text-align: center; border: none; flex: 1; min-width: 0; height: 40px; outline: none;"> ${Button({ onClick: () => setValue(value + 1), - styles: { - fontSize: '1.2rem', - borderWidth: '0px 0px 0px 1px' - }, + styles: css` + font-size: 1.2rem; + border-width: 0px 0px 0px 1px; + `, disabled: value >= max }, '+')} </div> @@ -64,13 +85,13 @@ <div style="margin: 100px; display: flex; width: 150px; flex-direction: column; gap: 15px; align-items: flex-start;"> ${Counter({ value: quantity, setValue: setQuantity })} ${Button({ - styles: { - backgroundColor: isDisabled ? '#f5f5f5' : '#f97316', - borderColor: isDisabled ? '#d4d4d4' : '#c2410c', - color: isDisabled ? '#a3a3a3' : 'white', - borderRadius: '4px', - width: '100%' - }, + styles: css` + background-color: ${isDisabled ? '#f5f5f5' : '#f97316'}; + border-color: ${isDisabled ? '#d4d4d4' : '#c2410c'}; + color: ${isDisabled ? '#a3a3a3' : '#ffffff'}; + border-radius: 4px; + width: 100%; + `, onClick: () => alert(`Added ${quantity} ${quantity > 1 ? 'items' : 'item'} to the cart`), disabled: isDisabled }, 'Add to cart')} diff --git a/lib.js b/lib.js @@ -68,36 +68,56 @@ export const createTlx = (createElement) => { (node.childNodes ?? []).forEach((child) => children.push(...render(child, refs))); return [createElement(tag, attributes, ...children)]; } + + return tlx; +} - function apply(value, refs) { - let values = []; - const expr = /\$tlx-\d+/g; +export const css = (parts, ...props) => { + const [css, refs] = ltr(parts, props); + const styles = {}; + for(const item of css.split(';')) { + if(item.trim().length === 0) { + break; + } + let [key, value] = item.split(':'); + key = key.trim(); let match = null; - let last = 0; - while((match = expr.exec(value)) !== null) { - const index = match.index; - values.push(value.substring(last, index)); - values.push(refs[match[0]]); - last = index + match[0].length; + if((match = /-(\w)/.exec(key)) !== null) { + const char = match[1]; + key = key.replace(`-${char}`, char.toUpperCase()); } - values.push(value.substring(last)); - return values; + value = value.trim(); + styles[key] = apply(value, refs).join(''); } + return styles; +} - function ltr(parts, props) { - let string = ''; - const refs = {}; - for(let i = 0; i < parts.length; i++) { - string += parts[i]; - if(props[i] !== undefined) { - const id = `$tlx-${counter}`; - refs[id] = props[i]; - string += id ?? ''; - counter++; - } +function apply(value, refs) { + let values = []; + const expr = /\$tlx-\d+/g; + let match = null; + let last = 0; + while((match = expr.exec(value)) !== null) { + const index = match.index; + values.push(value.substring(last, index)); + values.push(refs[match[0]]); + last = index + match[0].length; + } + values.push(value.substring(last)); + return values; +} + +function ltr(parts, props) { + let string = ''; + const refs = {}; + for(let i = 0; i < parts.length; i++) { + string += parts[i]; + if(props[i] !== undefined) { + const id = `$tlx-${counter}`; + refs[id] = props[i]; + string += id ?? ''; + counter++; } - return [string.trim(), refs]; } - - return tlx; + return [string.trim(), refs]; }