Skip to content
Ooidget

Docs

Your first component

This walk-through builds a toggle button: a rounded rectangle that lights up when clicked, with a hover look and a label. Each step adds one idea of the format.

1. The size and a face

Every widget has a design size. Its layers are drawn in order, back to front:

toggle.json
{
  "spec": "0.1",
  "about": "A toggle button.",
  "widget": {
    "size": [96, 32],
    "layers": [
      { "shape": "rect", "radius": 6, "effects": [{ "type": "fill", "color": "#2a2b31" }] }
    ]
  }
}

A layer without a frame covers the whole widget. effects paint the shape, as CSS backgrounds and borders do.

2. State, and a layer that depends on it

Add an initial state and a second layer drawn only while the toggle is on:

"state": { "on": false, "label": "Loop" },
"layers": [
  { "shape": "rect", "radius": 6, "effects": [{ "type": "fill", "color": "#2a2b31" }] },
  { "shape": "rect", "radius": 6, "effects": [{ "type": "fill", "color": "#4a78c0" }], "when": "s.on" }
]

when is an ECMAScript expression. s is the state as this widget sees it.

3. Hover and press

ui describes the pointer. Add a light veil while hovered and a dark one while pressed:

{ "shape": "rect", "radius": 6, "effects": [{ "type": "fill", "color": "#ffffff" }], "opacity": 0.08, "when": "ui.hover && !ui.down" },
{ "shape": "rect", "radius": 6, "effects": [{ "type": "fill", "color": "#000000" }], "opacity": 0.18, "when": "ui.down" }

4. A label

A text layer’s text is an expression too, here reading the state:

{ "text": "s.label", "frame": { "l": 8, "t": 0, "r": 8, "b": 0 }, "size": 13, "color": "#ececec", "align": "center" }

The frame insets the text 8 units from the left and right edges, as CSS left and right would.

5. Behaviour

Finally, a behaviour maps a click to a new state. It is a JavaScript object of handlers, each returning the state to change:

"behaviour": "({ click(s) { return { on: !s.on } } })"

That is the whole component. The same file runs in every Ooidget runtime; with an accessible role it is also a proper toggle to screen readers:

"role": "switch", "label": "s.label"