Published
Edited
May 14, 2021
6 stars
Insert cell
Insert cell
Preact = import(
"https://cdn.skypack.dev/pin/preact@v10.5.13-D6jTjNdYfFTh4ByqJuPH/mode=imports/optimized/preact.js"
)
Insert cell
hooks = import(
"https://cdn.skypack.dev/pin/preact@v10.5.13-D6jTjNdYfFTh4ByqJuPH/mode=imports/optimized/preact/hooks.js"
)
Insert cell
htm = (
await import(
"https://cdn.skypack.dev/pin/htm@v3.0.4-cmMJ6o0JPpTvFvXS4BFU/mode=imports/optimized/htm.js"
)
).default.bind(Preact.h)
Insert cell
tex = ({
block: (...params) => {
const container = html`<div>`;
Preact.render(htm(...params), container);
return container;
}
})
Insert cell
function HelloWorld() {
return htm`<div>
Hello, world!
</div>`;
}
Insert cell
${/* everything in this "TeX" code cell gets rendered as pure CSS!*/ null}

<${HelloWorld}/>
Insert cell
function Counter() {
const [value, setValue] = hooks.useState(0);

return htm`<div>
<div>Counter: ${value}</div>
<button onClick=${() => setValue(value + 1)}>Increment</button>
<button onClick=${() => setValue(value - 1)}>Decrement</button>
</div>`;
}
Insert cell
class TodoList extends Preact.Component {
constructor(props) {
super(props);
this.state = { todos: [], text: "" };
this.setText = this.setText.bind(this);
this.addTodo = this.addTodo.bind(this);
}
setText(e) {
this.setState({ text: e.target.value });
}

addTodo(e) {
e.preventDefault();
let { todos, text } = this.state;
todos = todos.concat({ text });
this.setState({ todos, text: "" });
}

render() {
const { todos, text } = this.state;
return htm`<form onSubmit=${this.addTodo}>
<label>
<span>Add Todo</span>
<input value=${text} onInput=${this.setText} />
</label>
<button type="submit">Add</button>
<ul>
${todos.map((todo) => htm`<li>${todo.text}</li>`)}
</ul>
</form>`;
}
}
Insert cell
function DogPic() {
const [pic, setPic] = hooks.useState(null);
const [refresh, setRefresh] = hooks.useState(null);

hooks.useEffect(() => {
fetch("https://dog.ceo/api/breeds/image/random")
.then((r) => r.json())
.then((data) => setPic(data.message));
}, [refresh]);

if (!pic) return htm`<div>Loading...</div>`;
return htm`<div>
<h2>Doggo</h2>
<div>
<img width=400 src=${pic}/>
</div>
<button onClick=${() => setRefresh(Date.now())}>Refresh</button>
</div>`;
}
Insert cell
<${Counter}/>

<br/>
<${TodoList}/>

<${DogPic}/>

Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more