These pages document @evanion/react-widget 0.3.3, the version on npm.
Playground
The @evanion/react-widget playground allows you to experiment with component maps and item arrays in real-time. You can see exactly how the Widgets component transforms your data into a rendered UI without needing to set up a full project.
Interactive Region: Baize’s Staff Page
The demo below renders a single react-widget region representing a staff dashboard. It uses a combination of layout and data widgets:
- Columns: A layout widget that positions its children side-by-side.
- Metrics: Single-figure displays with labels and change indicators.
- Boards: Titled panels containing data tables.
export const counterItems = defineItems([
{
id: 'week',
type: 'columns',
props: {},
children: [
{
id: 'intake',
type: 'metric',
props: { figure: '38', label: 'Games in', delta: '+6' },
},
{
id: 'sold',
type: 'metric',
props: { figure: '31', label: 'Sold', delta: '+2' },
},
{
id: 'turnaround',
type: 'metric',
props: { figure: '2.4 d', label: 'Turnaround', delta: '−0.3' },
},
],
},
{
id: 'counter',
type: 'columns',
props: {},
children: [
{
id: 'tables',
type: 'tables',
props: { title: 'Tonight at the tables' },
meta: { span: 2 },
},
{
id: 'reprints',
type: 'reprints',
props: { title: 'Reprints on order' },
},
],
},
]);Tonight at the tables
| Table | Game | Party | State |
|---|---|---|---|
| One | Brass: Birmingham | Hanna Lind, +3 | Playing |
| Two | Spirit Island | Otto Ruane, +2 | Playing |
| Three | Root | Sigrid Vall, +3 | Teaching |
| Four | Crokinole | Emil Norrby, +1 | Booked, 20:00 |
Reprints on order
| Title | Due |
|---|---|
| Wingspan, Oceania | Tuesday |
| Hive Pocket | Thursday |
| Azul, Summer Pavilion | Next week |
itemsMove one and the page is composed again
[ { "id": "week", "type": "columns", "props": {}, "children": [ { "id": "intake", "type": "metric", "props": { "figure": "38", "label": "Games in", "delta": "+6" } }, { "id": "sold", "type": "metric", "props": { "figure": "31", "label": "Sold", "delta": "+2" } }, { "id": "turnaround", "type": "metric", "props": { "figure": "2.4 d", "label": "Turnaround", "delta": "−0.3" } } ] }, { "id": "counter", "type": "columns", "props": {}, "children": [ { "id": "tables", "type": "tables", "props": { "title": "Tonight at the tables" }, "meta": { "span": 2 } }, { "id": "reprints", "type": "reprints", "props": { "title": "Reprints on order" } } ] }]You can interactively rearrange the region using the controls beside each item.
- Swap Rows: Move the
counterrow above theweekrow to see the entire section move. - Reorder Widgets: Move the
tablesboard past thereprintsboard. Becausemeta.spanis tied to the item, the two-column layout follows the widget as it moves.
Live Code Editor
The playground includes a live editor where you can write snippets using the actual @evanion/react-widget build. Every snippet follows a simple pattern:
- Build a component map with
createWidgets. - Define an item array.
- Call
render(<Widgets items={items} />)to display the result.
Try these examples
Editor Scope
The snippets run in a restricted environment. The following are available in scope:
createWidgets: The package’s primary export.Reactand standard hooks (useState,useEffect, etc.) for adding client-side state to your widgets.render: The function that hands the resulting element to the preview pane.
Note: DefaultWrapper and DefaultItem are not in scope, so you should define your chrome using plain JSX elements.
Limitations of the Playground
Since the playground runs entirely in the browser, it cannot demonstrate certain server-side behaviors:
- Server Components: You cannot use
asynccomponents or Server Component-specific features. - Streaming: The streaming behavior of
chrome.suspense(where the shell is sent first) cannot be shown. - Type Checking: The snippets are strings. They are not type-checked, so unknown
types or mistyped props will not be flagged by the compiler. - Production Silence: This site is a production build, so
Widgetswill not print warnings to the console for unknown types.
Experiments to Try
To understand how the renderer works, try making these changes in a snippet:
- Break a Type: Change a
typeto something not in your component map. The item will simply disappear from the page. - Mistype a Prop: Change a prop key (e.g.,
titleheadline). The widget will receiveundefinedfor that prop, demonstrating why compile-time validation is so important. - Change the Shell: Modify the
chrome.wrapper. You’ll see the container for the entire region change while the widgets inside remain unchanged. - Reorder the List: Swap the position of two items in the array to see the render order change instantly.
API Reference
For a full list of exports, signatures, and types, visit the API reference.