# Dashboards docs

> Build responsive dashboard grids with @texuli/data. The grid, FilterBar and MetricCard are in 0.18.0, in development.

Language: en
Canonical: https://texuli.com/guides/solutions/dashboards/
Markdown: https://texuli.com/guides/solutions/dashboards.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

---

Guides

Build responsive dashboard grids with @texuli/data. The grid, FilterBar and MetricCard are in 0.18.0, in development.

[Back to overview](https://texuli.com/solutions/dashboards/)

## What Dashboards is

`@texuli/data/dashboard` provides a responsive widget grid. People can arrange widgets with pointer or keyboard controls. The framework-free layout engine is also available from `@texuli/data/dashboard/engine`. The dashboard and engine APIs are published in `@texuli/data@0.17.4`, which remains in development before 1.0.

The interactive page demo uses fictional data in the browser. It does not contact a service or save filters and layouts.

## Components and release status

`Dashboard` and `DashboardWidget` are in the published dashboard subpath. The `FilterBar` and `MetricCard` additions described here were released in `0.18.0` and are in development; they need `@texuli/data@0.18.0` or later.

## What you get

- A grid expressed in row and column units, with responsive breakpoints and reading-order rendering.
- Pointer and keyboard move and resize controls, including announced steps and a no-drag arrange toolbar.
- Pure layout operations and bounded parsing for persisted layout data.
- Host-owned rendering and persistence: Texuli does not fetch metric data or save a dashboard for you.

## Install

Install `@texuli/data@0.18.0` for the published dashboard grid. Svelte 5 is a peer dependency. Import `@texuli/tokens/base.css` once, then import the dashboard subpath where the view is used.

```
npm install @texuli/data@0.18.0
```

## Render a board

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

<Dashboard label="Operations" editable>
  <DashboardWidget id="signups" title="Signups" x={0} y={0} w={4} h={2}>
    <p>1,284 this week</p>
  </DashboardWidget>
  <DashboardWidget id="revenue" title="Revenue" x={4} y={0} w={8} h={2}>
    <p>$48,200 this week</p>
  </DashboardWidget>
</Dashboard>
```

Positions and sizes are grid units, not pixels. A widget without `x` and `y` takes the first free slot. The sample values above are illustrative; connect the board to data owned by your application.

## Add metric and filter controls

`MetricCard` and `FilterBar` were released in `0.18.0` and are in development. Their API examples are in the integration section.

## Grid model

Each widget has a stable id and a position and size in grid units: `x`, `y`, `w`, and `h`. Optional `minW`, `minH`, `maxW`, `maxH`, and `locked` values constrain layout changes. The view renders widgets in row-then-column reading order.

## Layout engine

`@texuli/data/dashboard/engine` contains framework-free pure operations. `normalizeLayout` reads untrusted layouts, clamps values, resolves overlap deterministically, and returns issues. `moveItem`, `resizeItem`, `nudgeItem`, `compactLayout`, and `reflowLayout` return a new layout or a refusal; they do not mutate the input.

Breakpoints describe the available column count. `dashboardBreakpoints(12)` provides a twelve-column wide grid, up to six columns at medium widths, and one column on narrow containers. A missing breakpoint layout is reflowed from the nearest available layout.

## Persistence shape

`serializeDashboard` produces canonical JSON. Treat stored or shared data as untrusted and pass it to `parseDashboard` before restoring it. Parsing normalizes the layout and reports refused, dropped, or clamped entries instead of throwing.

The engine caps the input at 200 widgets, 24 columns, 8 breakpoints and 512 KiB of serialized state. See `packages/data/docs/data-dashboard-engine.md` for the complete types and limits.

## Keep data in the host

The dashboard renders widget content supplied by the host. Fetch and transform metrics in your application, then pass formatted values and text labels into components. Texuli does not accept a data URL, run queries, or persist dashboards for you.

## Persist layouts

Bind `layouts` and serialize updates in the host. On restore, parse the stored value as untrusted input before binding it back to the view.

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

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

  onMount(() => {
    layouts = { ...parseDashboard(localStorage.getItem('ops-dashboard') ?? '').state?.layouts };
  });
</script>

<Dashboard
  label="Operations"
  editable
  bind:layouts
  onLayoutChange={() => localStorage.setItem('ops-dashboard', serializeDashboard(layouts))}
>
  <DashboardWidget id="signups" title="Signups" w={4} h={2}>1,284</DashboardWidget>
</Dashboard>
```

## Filter and date controls

The published `@texuli/data/filter-builder` exposes the filter model and `applyFilter` for host-owned filtering. `FilterBar` from `@texuli/data/filter-bar` was released in `0.18.0` and is in development. It edits the same `FilterGroup` model used by the filter builder and data grid.

Use `DateRangePicker` from `texuli/date` to collect a date range. The host applies that range to its own sample or live data. Pass `today` when a deterministic preset origin is needed, such as for an SSR example or a test.

## Metric cards

`MetricCard` was released in `0.18.0` and is in development. Its API accepts a formatted value, comparison and trend label, optional loading or empty state, and an optional sparkline snippet. The sparkline needs its own text alternative.

## Keyboard and pointer

Dashboard move and resize handles are buttons. Space or Enter picks up a widget; arrow keys move or resize it by a grid step; Space or Enter drops it; Escape cancels and restores its prior layout. Tab cancels and moves focus onward. Left and right account for right-to-left direction.

The arrange toolbar also offers buttons for moving or sizing a selected widget, so a drag gesture is not required. Each step, refusal, drop, and cancellation is announced in a polite live region.

## Reading order and focus

Widgets render in grid reading order and their titles are headings. When widget content overflows and scrolls, its region becomes keyboard focusable and is named by the widget heading. Content that fits does not add a tab stop.

Use a meaningful label for the dashboard region. Give each chart or sparkline a text alternative, and make each metric value and comparison understandable without color or an arrow alone.

## Layout and motion

The component uses logical layout properties and keeps handles and focus visible in forced colors. Layout motion respects reduced-motion preferences; it does not animate on mount or hydration.

## Status and release

The dashboard grid and engine are available in `@texuli/data@0.18.0`, a pre-1.0 release that is still in development; `FilterBar` and `MetricCard` were added in `0.18.0`. A new minor release under 0.x may introduce breaking changes.

## Host responsibilities

- The host fetches, validates, formats and refreshes data.
- The host chooses where layouts and filters are stored and who can access them.
- Texuli does not provide a hosted dashboard service, collaboration, or automatic persistence.
- Adding and removing widgets from an existing board is a host action.
- Sync integration with `@texuli/document/sync` is planned, not implemented.

The Solutions demo uses fictional, local sample data only. It is not a production analytics connection.

## Agent-authored dashboards

The catalog describes dashboards with `data-dashboard` and `data-dashboard-widget` nodes. Widget bodies are ordinary catalog components. Metric data comes from a source registered by the host; the blueprint does not supply executable code or an arbitrary fetch URL.

`@texuli/catalog` checks that widgets are direct children of a dashboard, widget ids are unique, and the dashboard has at most 200 widgets. The host validates the draft and decides whether it is suitable to render.

## Keep agent data untrusted

Parse stored layouts with `parseDashboard` and use the catalog validation path for blueprint content. Treat text, metric values, saved filters, and layout JSON as data. Do not turn them into HTML or construct a network request from an agent-provided string.

## Skill

The Texuli skill's dashboard recipe covers the dashboard grid, widget composition, filters, metrics and visual validation. Use only the APIs available in the installed package version; `FilterBar` and `MetricCard` need `@texuli/data@0.18.0` or later.
