Examples

Composition

About

Composition: building a page out of views and components.

quillo run compose.qwe --watch then open http://localhost:8080

Run it

$ quillo run compose.qwe --watch

Source

compose.qwe
view Card(title: str, children) =    <section.card>        <h2>{title}</h2>        {children}    </section>component Counter(label: str, start: int = 0, step: int = 1, on_change = null) {    state n = start    <div.counter>        <span.label>{label}</span>        <button @click={() => { n -= step; on_change && on_change(label, n) }}>−</button>        <span.n>{n}</span>        <button @click={() => { n += step; on_change && on_change(label, n) }}>+</button>    </div>}component Panel(header, open: bool = true, children) {    state shown = open    <div.panel>        <button.header @click={() => { shown = !shown }}>            {shown ? "▾" : "▸"} {header}        </button>        {shown && <div.body>{children}</div>}    </div>}component Dashboard() {    state totals = { Apples: 0, Pears: 3, Plums: 0 }    state log = []    let fruit = values(totals) | sum    // Called by the Counters when their count changes.    let note = (label, n) => { log = take([`${label} → ${n}`] + log, 5) }    let changed = (label, n) => {        totals = set(totals, label, n)        note(label, n)    }    <main>        <Card title="Fruit">            {for [label, start] in totals =>                <Counter key={label} label={label} start={start} on_change={changed}/>}            <p.sum>Total: <b>{fruit}</b></p>        </Card>        <Card title="Bulk">            <Counter label="Crates" step={10} on_change={note}/>        </Card>        <Panel header={<span>Recent changes <small>({len(log)})</small></span>}>            {len(log) == 0                ? <p.muted>Nothing yet: press + or −.</p>                : <ul>{for entry in log => <li>{entry}</li>}</ul>}        </Panel>    </main>}let style = css`body { font: 15px/1.5 system-ui, sans-serif; max-width: 34rem; margin: 2rem auto; padding: 0 1rem; color: #222; }.card { border: 1px solid #e3e3e3; border-radius: 10px; padding: .25rem 1rem 1rem; margin-bottom: 1rem; }.card h2 { font-size: 1rem; color: #666; font-weight: 600; }.counter { display: flex; align-items: center; gap: .6rem; padding: .25rem 0; }.counter .label { flex: 1; }.counter .n { min-width: 2.5rem; text-align: center; font-variant-numeric: tabular-nums; }.counter button { width: 2rem; height: 2rem; border: 1px solid #ccc; border-radius: 6px; background: white; font: inherit; cursor: pointer; }.sum { margin: .75rem 0 0; color: #555; }.panel .header { border: none; background: none; font: inherit; font-weight: 600; cursor: pointer; padding: 0; }.panel small, .muted { color: #888; }@media (prefers-color-scheme: dark) {  body { background: #161616; color: #ddd; }  .card { border-color: #333; }  .counter button { background: #222; color: #ddd; border-color: #444; }  .panel .header { color: #ddd; }}`route GET / =    <html>        <head>            <meta charset="utf-8"/>            <meta name="viewport" content="width=device-width, initial-scale=1"/>            <title>Composition</title>            <style>{style}</style>        </head>        <body>            <h1>Composition</h1>            <Dashboard/>        </body>    </html>

See compose.qwe on GitHub

Thread
14Useful? Like it, or add to its thread below.

Thread 0 posts

On Composition: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.