# Dashboard

> A widget grid people rearrange: move and resize handles for pointer drags, the arrow keys with announced positions and a click-to-arrange toolbar, breakpoints…

Language: en
Canonical: https://texuli.com/examples/data-dashboard/
Markdown: https://texuli.com/examples/data-dashboard.md (this page). Every texuli.com page has a Markdown twin at its URL plus `.md` (the home page is https://texuli.com/index.md), and any page URL answers `Accept: text/markdown` with its twin instead of HTML.
Last Updated: 2026-11-13

---

[All examples](https://texuli.com/examples/)

A widget grid people rearrange: move and resize handles for pointer drags, the arrow keys with announced positions and a click-to-arrange toolbar, breakpoints that reflow to one column, and a layout saved as JSON.

[Dashboard](https://texuli.com/examples/data-dashboard/)

`data-dashboard` · `data/dashboard`

 data dashboard

 Props
- `columns`
- `editable`
- `label`
- `layout`
- `layouts`
- `onLayoutChange`

Live example loads in an isolated same-origin preview frame.

Source (data-dashboard/DataDashboardDemo.svelte)

```
<script lang="ts">
import {
  Dashboard,
  type DashboardLayout,
  DashboardWidget,
  serializeDashboard,
} from '@texuli/data/dashboard';

/** An operations overview: four widgets, editable, with the saved layout shown as JSON. */
const metrics = [
  {
    id: 'signups',
    title: 'Signups',
    value: '1,284',
    note: 'This week, up 12%',
    x: 0,
    y: 0,
    w: 4,
    h: 2,
  },
  {
    id: 'revenue',
    title: 'Revenue',
    value: '$48,200',
    note: 'Month to date',
    x: 4,
    y: 0,
    w: 4,
    h: 2,
  },
  { id: 'uptime', title: 'Uptime', value: '99.98%', note: 'Last 30 days', x: 8, y: 0, w: 4, h: 2 },
] as const;

let layouts = $state<Record<string, DashboardLayout>>({});
let saved = $state('');
</script>

<div data-example="data-dashboard" class="demo">
  <Dashboard
    label="Operations overview"
    editable
    rowHeight={64}
    bind:layouts
    onLayoutChange={() => {
      saved = serializeDashboard(layouts);
    }}
  >
    {#each metrics as metric (metric.id)}
      <DashboardWidget id={metric.id} title={metric.title} x={metric.x} y={metric.y} w={metric.w} h={metric.h}>
        <p class="value">{metric.value}</p>
        <p class="note">{metric.note}</p>
      </DashboardWidget>
    {/each}
    <DashboardWidget id="incidents" title="Open incidents" x={0} y={2} w={12} h={3} minH={2}>
      <ul class="list">
        <li>Checkout latency on eu.example.com, investigating</li>
        <li>Webhook retries for partner.example, monitoring</li>
      </ul>
    </DashboardWidget>
  </Dashboard>
  <p class="saved" aria-live="off">{saved ? `Saved layout: ${saved.length} bytes of JSON` : 'Layout not changed yet'}</p>
</div>

<style>
  .demo {
    display: grid;
    gap: 0.75rem;
  }

  .value {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 600;
  }

  .note,
  .saved {
    margin: 0;
    color: var(--tx-muted-foreground, CanvasText);
    font-size: 0.875rem;
  }

  .list {
    margin: 0;
    padding-inline-start: 1.25rem;
  }
</style>
```

## For agents

A worked example rendered live in the browser; the isolated preview frame (`/examples/preview/<id>/`) shows the same example without the site shell, and the example page next to it carries its code. The live parts run in the browser and are not in this Markdown; the operations below do the same work through the read-only MCP server at https://texuli.com/mcp (no sign-in; see https://texuli.com/auth.md).

MCP operations ([reference](https://github.com/DailybotHQ/texuli/blob/main/packages/tools/docs/ops.md#operations)):

- `example.search`: Find component examples.
- `component.get`: Read a component manifest.

Docs:

- [Component docs for agents (llms.txt)](https://texuli.com/llms/llms.txt)
- [Catalog manifest snapshot (JSON)](https://texuli.com/catalog/catalog.json)
- [@texuli/examples README](https://github.com/DailybotHQ/texuli/blob/main/packages/examples/README.md)
- [texuli README](https://github.com/DailybotHQ/texuli/blob/main/packages/texuli/README.md)
