Skip to content

Your first interface ​

Install it into your app:

bash
npm install sayshape

A SayShape interface needs three things: a <canvas>, the components the instance understands, and a spec.

html
<div style="max-width: 480px">
  <canvas id="ui"></canvas>
</div>
ts
import { SayShape, coreComponents } from "sayshape";

const canvas = document.querySelector<HTMLCanvasElement>("#ui")!;
const ui = new SayShape(canvas, { components: coreComponents });

ui.setSpec(`state count=0
card
  text "Clicked {count} times"
  button "Click me" on=inc:count`);

The canvas fills its parent's width and grows to fit its content, so size the parent rather than the canvas. That spec renders as:

sayshape
state count=0
card
  text "Clicked {count} times"
  button "Click me" on=inc:count
Rendered by the SayShape engineOpen in playground

This is the same code a clean Vite app runs against the published package in the release checks (npm run verify:pack).

Listen to it ​

Everything the interface does is visible to your page through events:

ts
// Any state change: a click, a keystroke, a value the spec declares.
ui.on("change", ({ key, value }) => console.log(key, value));

// Actions the spec hands to your app with emit:
ui.on("action", ({ name, value }) => {
  if (name === "order") submitOrder(value);
});

on() returns a function that unsubscribes. Call ui.destroy() when you remove the canvas from the page: it removes the instance's listeners and stops rendering.

Change it ​

  • ui.setSpec(text) replaces the spec. Values the person already changed are kept when the new spec declares them the same way; pass { resetState: true } to start over.
  • ui.state.set("count", 10) changes state from your app.
  • ui.setTheme(theme) switches themes (Themes).

The full list of options, methods and events is in Embedding SayShape.

Add the map ​

The world map ships separately because its country outlines are large:

ts
import { SayShape, coreComponents } from "sayshape";
import { mapComponents } from "sayshape/map";

const ui = new SayShape(canvas, { components: [...coreComponents, ...mapComponents] });

Next: what happens between the spec and the pixels.

SayShape v0.1 is an early prototype under the MIT License. Status · GitHub