This repository has been archived on 2026-05-05. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Will Anderson 143137e2b4 add ssr-counter example demonstrating SSR + hydration end-to-end
Counter.el defines Counter, CounterPair, and App components with {#if}
conditionals, event handlers, and child component composition.

render.js (generated by elc-ui --target=server) is the Node.js render
script the server calls. app.js (generated by elc-ui --target=web) is the
compiled browser module. hydrate.js attaches the runtime to the
server-rendered DOM without replacing it.

index.html shows the integration point with instructions for injecting
server output and the two CLI commands needed to regenerate both targets.
2026-05-04 12:49:19 -05:00

89 lines
2.4 KiB
EmacsLisp

// ssr-counter/Counter.el
//
// A counter component that demonstrates:
// - State with initial value
// - {#if} conditional rendering
// - {#each} list rendering
// - Interpolation
// - Event binding
// - SSR + client hydration
//
// Run `node render.js Counter` to see the server-rendered HTML.
// Open index.html in a browser to see the full SSR + hydration lifecycle.
component Counter {
props {
initialValue: Int = 0
label: String = "Counter"
}
state {
count: Int = 0
history: String = ""
}
fn increment() -> Void {
count = count + 1
history = history + "+" + count + " "
}
fn decrement() -> Void {
count = count - 1
history = history + "-" + count + " "
}
fn reset() -> Void {
count = 0
history = ""
}
template {
<div class="counter">
<h2 class="counter-label">{label}</h2>
<div class="count-display">
<span class={count > 0 ? "count positive" : count < 0 ? "count negative" : "count zero"}>
{count}
</span>
</div>
<div class="buttons">
<button class="btn btn-decrement" on:click={() => decrement()}>-</button>
<button class="btn btn-reset" on:click={() => reset()}>reset</button>
<button class="btn btn-increment" on:click={() => increment()}>+</button>
</div>
{#if history != ""}
<div class="history">
<span class="history-label">history:</span>
<code>{history}</code>
</div>
{/if}
{#if count == 0}
<p class="hint">Press + or - to begin.</p>
{/if}
</div>
}
}
component CounterPair {
template {
<div class="counter-pair">
<Counter label="Left" />
<Counter label="Right" />
</div>
}
}
component App {
template {
<div class="app">
<header class="app-header">
<h1>el-ui SSR + Hydration</h1>
<p class="subtitle">Server-rendered, client-hydrated with spreading activation</p>
</header>
<main class="app-main">
<Counter label="Main Counter" />
<CounterPair />
</main>
</div>
}
}