Archived
143137e2b4
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.
119 lines
5.0 KiB
JavaScript
119 lines
5.0 KiB
JavaScript
import { Component, Graph, Renderer, Router, mount } from '../../dist/el-ui.js';
|
|
|
|
class Counter extends Component {
|
|
constructor(props = {}) {
|
|
super();
|
|
this.props = props;
|
|
this._graph = new Graph();
|
|
this._stateNodes = {};
|
|
this._state = {};
|
|
this._stateNodes['count'] = this._graph.seed({ type: 'state', name: 'count', content: 0 });
|
|
this._state['count'] = 0;
|
|
this._stateNodes['history'] = this._graph.seed({ type: 'state', name: 'history', content: "" });
|
|
this._state['history'] = "";
|
|
for (const [key, nodeId] of Object.entries(this._stateNodes)) {
|
|
this._graph.subscribe(nodeId, (node) => {
|
|
this._state[key] = node.content;
|
|
if (this._renderer) this._renderer.patch();
|
|
});
|
|
}
|
|
}
|
|
|
|
setState(name, value) {
|
|
if (this._stateNodes[name] !== undefined) {
|
|
this._graph.update(this._stateNodes[name], value);
|
|
}
|
|
}
|
|
|
|
increment() {
|
|
const __self = this;
|
|
const count = this._state['count'];
|
|
const history = this._state['history'];
|
|
const initialValue = this.props['initialValue'] !== undefined ? this.props['initialValue'] : 0;
|
|
const label = this.props['label'] !== undefined ? this.props['label'] : "Counter";
|
|
|
|
__self.setState('count', count + 1)
|
|
__self.setState('history', history + "+" + count + " ")
|
|
|
|
}
|
|
|
|
decrement() {
|
|
const __self = this;
|
|
const count = this._state['count'];
|
|
const history = this._state['history'];
|
|
const initialValue = this.props['initialValue'] !== undefined ? this.props['initialValue'] : 0;
|
|
const label = this.props['label'] !== undefined ? this.props['label'] : "Counter";
|
|
|
|
__self.setState('count', count - 1)
|
|
__self.setState('history', history + "-" + count + " ")
|
|
|
|
}
|
|
|
|
reset() {
|
|
const __self = this;
|
|
const count = this._state['count'];
|
|
const history = this._state['history'];
|
|
const initialValue = this.props['initialValue'] !== undefined ? this.props['initialValue'] : 0;
|
|
const label = this.props['label'] !== undefined ? this.props['label'] : "Counter";
|
|
|
|
__self.setState('count', 0)
|
|
__self.setState('history', "")
|
|
|
|
}
|
|
|
|
render() {
|
|
const __self = this;
|
|
const count = this._state['count'];
|
|
const history = this._state['history'];
|
|
const initialValue = this.props['initialValue'] !== undefined ? this.props['initialValue'] : 0;
|
|
const label = this.props['label'] !== undefined ? this.props['label'] : "Counter";
|
|
return `<div class="counter" data-el-tag="div"><h2 class="counter-label" data-el-tag="h2">${label }</h2><div class="count-display" data-el-tag="div"><span class="${count > 0 ? "count positive" : count < 0 ? "count negative" : "count zero"}" data-el-tag="span">${count }</span></div><div class="buttons" data-el-tag="div"><button class="btn btn-decrement" data-el-click="() => decrement()" data-el-tag="button">-</button><button class="btn btn-reset" data-el-click="() => reset()" data-el-tag="button">reset</button><button class="btn btn-increment" data-el-click="() => increment()" data-el-tag="button">+</button></div>${(history != "") ? `<div class="history" data-el-tag="div"><span class="history-label" data-el-tag="span">history:</span><code data-el-tag="code">${history }</code></div>` : ``}${(count == 0) ? `<p class="hint" data-el-tag="p">Press + or - to begin.</p>` : ``}</div>`;
|
|
}
|
|
|
|
}
|
|
|
|
class CounterPair extends Component {
|
|
constructor(props = {}) {
|
|
super();
|
|
this.props = props;
|
|
this._graph = new Graph();
|
|
this._stateNodes = {};
|
|
this._state = {};
|
|
}
|
|
|
|
setState(name, value) {
|
|
if (this._stateNodes[name] !== undefined) {
|
|
this._graph.update(this._stateNodes[name], value);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const __self = this;
|
|
return `<div class="counter-pair" data-el-tag="div">${__self._child(Counter, { label: "Left" })}${__self._child(Counter, { label: "Right" })}</div>`;
|
|
}
|
|
|
|
}
|
|
|
|
class App extends Component {
|
|
constructor(props = {}) {
|
|
super();
|
|
this.props = props;
|
|
this._graph = new Graph();
|
|
this._stateNodes = {};
|
|
this._state = {};
|
|
}
|
|
|
|
setState(name, value) {
|
|
if (this._stateNodes[name] !== undefined) {
|
|
this._graph.update(this._stateNodes[name], value);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const __self = this;
|
|
return `<div class="app" data-el-tag="div"><header class="app-header" data-el-tag="header"><h1 data-el-tag="h1">el-ui SSR + Hydration</h1><p class="subtitle" data-el-tag="p">Server-rendered, client-hydrated with spreading activation</p></header><main class="app-main" data-el-tag="main">${__self._child(Counter, { label: "Main Counter" })}${__self._child(CounterPair, { })}</main></div>`;
|
|
}
|
|
|
|
}
|
|
|
|
export { Counter, CounterPair, App }; |