# DashboardOptions

Import it from `@grafloria/element`.

```ts
interface DashboardOptions
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `columns?` | `number` |  | Column count for every view (default 12). |
| `gap?` | `number` |  | Gap between widgets AND the board padding, px (default 8). |
| `sizing?` | `'fit' \| 'grow'` |  | Sizing mode. 'grow': rows keep `rowHeight` and the board extends downward — the default on a FLUID board, and what every grid library does: dragging one tile never resizes another. 'fit': the board keeps its height and rows squeeze so everything stays on one screen (bounded, see `overflow`) — the default on a FIXED board, and the choice for a designer who wants the whole dashboard visible at once. |
| `layout?` | `'grid' \| 'split'` |  | HOW THE BOARD IS LAID OUT (the DevExpress question, decided 6 Sep 2026). 'grid' (the default): the cell grid — columns, spans, push, gravity, the gridstack model. |
| `rowHeight?` | `number` |  | Row height in 'grow' mode, px (default 130). |
| `width?` | `number` |  | Board size, px (default 1180 × 660). |
| `height?` | `number` |  |  |
| `float?` | `boolean` |  | Engine float mode (default false → gravity packs upward). |
| `mode?` | `'fluid' \| 'fixed'` |  | DIAGRAM OR LAYOUT — the one switch (decision of 2026-09-06). |
| `overflow?` | `'bounded' \| 'scroll'` |  | FIT MEANS BOUNDED. In 'fit' the board never changes size; widgets do. Past the row floor the design height is a CAPACITY: a drop, resize or `addWidget()` that would need one row too many is refused (the placeholder stays put, the palette chip dims, `addWidget` returns undefined) — at design time, instead of tiles painted past the frame. |
| `static?` | `boolean` |  | STATIC board (gridstack's `staticGrid`): no drag, no resize, no handles — the viewer's mode. The API (moveTo, resize, addWidget, undo) still works, so a designer/viewer pair is one flag apart. Live: `handle.setStatic()`. |
| `nesting?` | `number` |  | The deepest board a drop may enter (a view is 0; unbounded by default). See the grid binder's `nesting`. |
| `dragHandle?` | `DragHandleOption` |  | DRAG HANDLE — DevExpress drags an item by its caption. `true`: the caption strip is the only handle (the header shows grip dots); a selector string: your own element inside the card; `{ grip: true, position, placement }`: a painted grip, left / center / right along the top edge, `inside` the header band or `outside` as a tab above the card; off (default): the whole card. |
| `squeeze?` | `boolean` |  | FIT AND THE ROW FLOOR. `true` (default): a bounded fit board squeezes its rows toward `minRowHeight` before refusing growth. `false`: rows freeze at the height they have now — a gesture that needs a row the frame does not hold is refused outright and no other tile shrinks. See the grid binder's `squeeze` for the exact rule. |
| `rtl?` | `boolean` |  | RIGHT-TO-LEFT boards: column x=0 renders at the RIGHT edge and columns run leftwards. Cells are untouched — the same `widgets` array describes the same layout in both directions, and a layout saved in one renders mirrored in the other with identical cells. |
| `responsive?` | `DashboardResponsiveOptions` |  | RESPONSIVE COLUMN COUNT: derive the live count from each board's width. `{ columnWidth: 100 }` gives one column per ~100px (capped by `columns`); `{ breakpoints: [{ w: 480, c: 1 }, { w: 900, c: 6 }] }` names the steps. |
| `views?` | `DashboardViewSpec[]` |  | One view, or many (the tab pattern). Mutually exclusive with `widgets`. |
| `widgets?` | `DashboardWidgetSpec[]` |  | Shorthand for a single unnamed view. |
| `renderWidget?` | `(widget: DashboardWidgetSpec, host: HTMLElement) => void` |  | Paint a widget into its host element. Called once per widget when it mounts (the host is reused across re-renders, so this is not a per-frame hook). Omit for a titled placeholder frame. |
| `onSelect?` | `(id: string \| undefined, viewId: string) => void` |  | The selection changed on a board: the selected id — a widget or a SECTION (container) — or undefined when cleared, and the view it belongs to. A press on a section's empty band selects the section. |
| `renderCaption?` | `(widget: DashboardWidgetSpec, host: HTMLElement) => void` |  | Paint a section's caption band yourself (the escape hatch `renderWidget` is for cards): the band arrives empty, sized and themed, and keeps its press rules — a press on it selects the section, a pass-through element (a button, an input, `[data-axdb-pass]`) reaches your content. |
| `onCaptionAction?` | `(sectionId: string, actionId: string, viewId: string) => void` |  | A press on a caption action (`caption.actions`): the section, the action id, the view. |
| `onTabChange?` | `(containerId: string, pageId: string, viewId: string) => void` |  | A tab container switched pages: the container, the page now showing, the view. |
| `onLayoutChange?` | `(viewId: string, widgets: DashboardWidgetSpec[]) => void` |  | Fires after any committed gesture, with the view whose layout changed. |
| `binder?` | `Partial<DashboardGridOptions>` |  | Extra binder options, merged last (escape hatch to the layer below). |
