The vanilla alternative for writing JSX-based React applications
git clone git://soophie.de/figure
9
const tlx = createTlx(createElement);11
const Button = (props, $slot) => {12
const styles = {13
minWidth: '40px',14
height: '40px',15
border: 'none',16
outline: 'none',17
border: '1px solid #a3a3a3',18
backgroundColor: props.disabled ? '#f5f5f5' : '#e5e5e5',19
cursor: props.disabled ? 'default' : 'pointer',20
fontSize: '1rem',21
fontFamily: 'Inter',22
...props.styles23
};24
return tlx`25
<button disabled="${props.disabled}" style="${styles}" @click="${() => props.onClick()}">${$slot}</button>26
`;27
}29
const Counter = (props) => {30
const [defaultValue, setDefaultValue] = useState(0);31
const { min = 0, max = 999, value = defaultValue, setValue = setDefaultValue } = props ?? {};
37
return tlx`38
<div style="display: inline-flex; width: 100%; border: 1px solid #a3a3a3; border-radius: 4px; overflow: hidden; height: 40px; box-sizing: border-box;">39
${Button({22
text: '-',40
onClick: () => setValue(value - 1),41
styles: {42
fontSize: '1.2rem',43
borderWidth: '0px 1px 0px 0px'44
},45
disabled: value <= min29
})}46
}, '-')}47
<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;">48
${Button({32
text: '+',49
onClick: () => setValue(value + 1),50
styles: {51
fontSize: '1.2rem',52
borderWidth: '0px 0px 0px 1px'53
},54
disabled: value >= max39
})}55
}, '+')}56
</div>57
`;58
}44
const Button = (props) => {45
const styles = {46
minWidth: '40px',47
height: '40px',48
border: 'none',49
outline: 'none',50
border: '1px solid #a3a3a3',51
backgroundColor: props.disabled ? '#f5f5f5' : '#e5e5e5',52
cursor: props.disabled ? 'default' : 'pointer',53
fontSize: '1rem',54
fontFamily: 'Inter',55
...props.styles56
};57
return tlx`58
<button disabled="${props.disabled}" style="${styles}" @click="${() => props.onClick()}">${props.text}</button>59
`;60
}60
const App = () => {61
const [quantity, setQuantity] = useState(1);62
const isDisabled = quantity <= 0;
64
<div style="margin: 100px; display: flex; width: 150px; flex-direction: column; gap: 15px; align-items: flex-start;">65
${Counter({ value: quantity, setValue: setQuantity })}66
${Button({69
text: 'Add to cart',67
styles: {68
backgroundColor: isDisabled ? '#f5f5f5' : '#f97316',69
borderColor: isDisabled ? '#d4d4d4' : '#c2410c',
73
},74
onClick: () => alert(`Added ${quantity} ${quantity > 1 ? 'items' : 'item'} to the cart`),75
disabled: isDisabled79
})}76
}, 'Add to cart')}77
</div>78
`;79
}