commit 2744b6551226a461212ab6e0a6b5b670be08d3f2
parent b6a9da2f1ee9cef6a445274aee8c27220628b6b5
Author: typable <contact@typable.dev>
Date: Thu, 15 Sep 2022 18:44:56 +0200
Added css function
Diffstat:
M | example.html | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
M | lib.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];
}