Familiar to write
A .stsx file is React-like JSX with scoped CSS built in: one <style> at the end of the file serves every component in it, typed by stock TypeScript. Edit the sample: it compiles in your browser.
import { signal } from "lumiose";
const gap = 8;
const radius = { pill: "999px" };
export default function Counter() {
const count = signal(0);
return (
<div class="counter">
<button class={{ pill: true, hot: count() > 9 }} onClick={() => count.update((n) => n + 1)}>
Clicked {count()} times
</button>
<Reset onReset={() => count.set(0)} />
</div>
);
}
function Reset(props: { onReset(): void }) {
return (
<button class="pill ghost" onClick={props.onReset}>
Reset
</button>
);
}
// One block at the end of the file styles both components.
<style>
.counter {
display: flex;
gap: calc($gap * 1px);
}
.pill {
padding: calc($gap * 1px) calc($gap * 2px);
border: 2px solid #5546ff;
border-radius: $radius.pill;
background: #5546ff;
color: white;
font: inherit;
}
.ghost {
background: transparent;
color: inherit;
}
.hot {
outline: 2px solid tomato;
}
</style>import { signal } from "lumiose";
import { template, bind, toggleClass, insert, createComponent, delegateEvents } from "lumiose/dom";
import "/src/App.stsx?lumiose&type=style&lang.css";
const _t0 = /* @__PURE__ */ template(`<div class=counter data-l-rdjmzp3m><button class=pill data-l-rdjmzp3m>Clicked <!> times`);
const _t1 = /* @__PURE__ */ template(`<button class="pill ghost" data-l-rdjmzp3m>Reset`);
const _a0 = (el, v) => toggleClass(el, "hot", v);
const gap = 8;
const radius = { pill: "999px" };
export default function Counter() {
const count = signal(0);
const _el = _t0(), _button = _el.firstChild, _marker = _button.firstChild.nextSibling;
bind(_button, () => count() > 9, _a0);
_button.$$click = () => count.update((n) => n + 1);
insert(_button, count, _marker);
insert(_el, createComponent(Reset, { onReset: () => count.set(0) }));
return _el;
}
function Reset(props) {
const _el2 = _t1();
_el2.$$click = props.onReset;
return _el2;
}
delegateEvents(["click"]);.counter[data-l-rdjmzp3m] {
gap: 8px;
display: flex;
}
.pill[data-l-rdjmzp3m] {
color: #fff;
font: inherit;
background: #5546ff;
border: 2px solid #5546ff;
border-radius: 999px;
padding: 8px 16px;
}
.ghost[data-l-rdjmzp3m] {
color: inherit;
background: none;
}
.hot[data-l-rdjmzp3m] {
outline: 2px solid tomato;
}App.stsxEsc, then Tab, leaves the editor
No diagnostics.