Dashboard
Grid of resizable panes, dragged by the edges they share.
c2-dashboard
Grid of resizable panes. The children are c2-dash-card elements, placed by their col/row attributes; each
one draws drag handles on the edges it shares with a neighbour, and dragging one resizes the whole track, so the
cards on either side stay aligned. columns and rows take a track count (columns="3" is three equal columns)
or an explicit track list (columns="320px 1fr"); a track is switched to pixels the first time it is dragged, and
the fr tracks around it give up the space in proportion to their weight, down to the minimums. With a
storage-key the sizes survive a reload.
layouts makes the grid responsive without a remount: each entry names a media query and the tracks and card
placements to use while it matches, the first match wins, and every entry keeps its own stored sizes under
<storage-key>@<media>. Stored payloads are versioned and include stable card order; serializeLayout and
deserializeLayout can preserve application metadata such as named sizes without coupling it to the component.
Placement is the application's: the grid never re-places cards on its own. A pane removed or hidden at runtime
leaves its cells empty and its neighbours where they were, and a pane added at runtime lands exactly where its
col/row say, on top of whatever is already there if that cell is taken. To close a gap, or to make room, set
the cards' col/row/col-span/row-span or hand the grid a layout record — both are applied in place.
The grid is the sizing authority: a card never sets its own width. Give the element a height (or place it in a
flex/grid parent that does) whenever the rows use fr, since the row tracks divide the host's height.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
columns | number | string | string[] | 2 | Column count (3) or an explicit track list ('320px 1fr'). Each entry must be one simple size. |
rows | number | string | string[] | 1 | Row count (2) or an explicit track list ('auto 1fr'). |
min-column-width | number | 50 | Floor for every column, in pixels. A card's own min-width raises it for the tracks that card covers. |
min-row-height | number | 50 | Floor for every row, in pixels. A card's own min-height raises it for the tracks that card covers. |
storage-key | string | undefined | undefined | localStorage key the track sizes and stable card order are stored under. Without it the grid starts from the authored layout. |
Slots
| Name | Description |
|---|---|
(default) | The c2-dash-card panes. Anything else becomes an ordinary grid item, placed by your own CSS. |
Events
| Name | Type | Description |
|---|---|---|
layout-change | CustomEvent<DashboardLayoutChangeDetail> | The tracks or stable card order changed: a gesture ended, setPanelOrder()/reset() was called, or another entry of layouts took over. Includes the active breakpoint. Does not bubble: listen on the element. |
CSS custom properties
Grouped by semantic target and state from --c2-component__target__state--property. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-dashboard--gap | pixel | 8px | Gutter between the cards. The whole gutter drags: each card's handle is centred on its edge and as thick as the gap (never under --c2-dash-card__handle--size). |
--c2-dashboard--padding | padding | 0px | Inset around the tracks. With a background it is what turns the gutters into a visible frame between the panes. |
--c2-dashboard--background | background | transparent | |
--c2-dashboard--border | border | none | |
--c2-dashboard--border-radius | border-radius | 0px | |
c2-dash-card
One pane of a c2-dashboard. It owns its place in the grid (col, row, col-span, row-span), the drag
handles on the edges it shares with a neighbour, and the optional expand controls; it draws no surface of its
own, so put a c2-card — or any markup — in the default slot.
A handle resizes the whole grid track, never just this card, and it only appears where there is a neighbour to take the space from: the right edge has one when another column follows, the left edge when one precedes. Drag it, or focus it and use the arrow keys (10px a step, 1px with Shift).
Filling the header, actions or footer slot turns on that row; with the header and actions both empty the
expand controls float over the top-right corner of the pane instead. An expanded card covers its neighbours on
an opaque --c2-dash-card__expanded--background (the theme's surface colour), while the card itself stays
transparent at rest.
A card that arrives while the grid is already on screen fades and scales in; one that leaves — through the
grid's layout record (visible: false) or through dismiss(), which removes the element once the animation
has played — fades out the same way. Cards present at load do not animate, and prefers-reduced-motion turns
both off.
Every built-in icon is a slot whose fallback is the default drawing, so a pane can use the host application's own icon set without giving up the behaviour.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
card-id | string | undefined | undefined | Identifier the grid's layout record is keyed by. |
col | number | 1 | 1-based column the card starts in. |
row | number | 1 | 1-based row the card starts in. |
col-span | number | 1 | Number of columns the card occupies. |
row-span | number | 1 | Number of rows the card occupies. |
min-width | number | 0 | Smallest width in pixels the card accepts; it raises the minimum of every column it covers. |
min-height | number | 0 | Smallest height in pixels the card accepts; it raises the minimum of every row it covers. |
resize | DashCardResize | both | Which edges carry a drag handle. |
expand-width | boolean | false | Offers a control that expands the card across every column. |
expand-height | boolean | false | Offers a control that expands the card across every row. |
expand-full | boolean | false | Offers a control that expands the card over the whole grid. |
expanded | DashCardExpanded | none | How far the card is currently expanded. Settable, so an app can expand a card from its own control. |
Slots
| Name | Description |
|---|---|
(default) | Pane content. It fills the pane: the body is a column flex box and every slotted child is a flex: 1 item with min-height: 0, so a chart or an editor follows the row track without a height: 100% chain. |
header | Title area of the header row; filling it turns the row on. |
actions | Your own controls at the end of the header row, before the built-in expand buttons and separated from them by --c2-dash-card__actions--gap. |
controls | Your own controls inside the built-in group, immediately before the expand buttons — for a button that belongs with them, such as a refresh or a close. |
footer | Status bar under the pane content; filling it turns the row on. |
expand-width-icon | Icon of the full-width control while the card is not expanded that way. |
collapse-width-icon | Icon of the full-width control while it is. |
expand-height-icon | Icon of the full-height control while the card is not expanded that way. |
collapse-height-icon | Icon of the full-height control while it is. |
expand-full-icon | Icon of the fullscreen control while the card is not expanded. |
collapse-full-icon | Icon of the fullscreen control while it is. |
Events
| Name | Type | Description |
|---|---|---|
expand-change | CustomEvent<DashCardExpandChangeDetail> | The card was expanded or collapsed through one of its own controls. Does not bubble: listen on the element. |
CSS parts
Shadow DOM styling hooks used with ::part(name). Prefer CSS custom properties when they cover the change.
| Name | Description |
|---|---|
header | Conditional row containing the header and actions slots, or the floating controls when both are empty. |
body | The wrapper around the default slot. |
footer | Conditional row wrapping the assigned footer slot. |
controls | Component-owned group containing the controls slot and built-in expand-button fallbacks. |
control | One built-in expand button. |
handle | Every drag handle. Each also carries the part of its edge. |
handle-left | The handle on the left edge. |
handle-right | The handle on the right edge. |
handle-top | The handle on the top edge. |
handle-bottom | The handle on the bottom edge. |
CSS custom properties
Grouped by semantic target and state from --c2-component__target__state--property. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-dash-card--background | background | transparent | |
--c2-dash-card--border | border | none | |
--c2-dash-card--border-radius | border-radius | 0px | |
--c2-dash-card--box-shadow | box-shadow | none | |
--c2-dash-card--padding | padding | 0px | |
--c2-dash-card--overflow | overflow | hidden | hidden keeps the content inside the track; switch it to visible for a pane that has to overflow, such as one holding a menu. |
--c2-dash-card__expanded--background | background | #ffffff | Fill while the card is expanded over its neighbours, so they do not show through; the card's own background stays transparent. |
--c2-dash-card__expanded--z-index | number | 20 | |
--c2-dash-card__expanded--animation-duration | duration | 200ms | Length of the scale-in the card plays when it expands or collapses. Ignored under prefers-reduced-motion. |
--c2-dash-card__enter--animation-duration | duration | 200ms | Fade and scale-in of a card added to a grid that is already on screen, or shown again through the layout record. 0ms disables it. |
--c2-dash-card__leave--animation-duration | duration | 160ms | Fade-out before a card is hidden by the layout record or removed by dismiss(). 0ms disables it. |
--c2-dash-card__header--min-height | pixel | 44px | |
--c2-dash-card__header--padding-block | padding | 8px | |
--c2-dash-card__header--padding-inline | padding | 12px | |
--c2-dash-card__header--gap | pixel | 12px | |
--c2-dash-card__header--background | background | transparent | |
--c2-dash-card__header--border-bottom | border | none | |
--c2-dash-card__header--color | color | #18181b | |
--c2-dash-card__header--font-size | pixel | 14px | |
--c2-dash-card__header--font-weight | font-weight | 600 | |
--c2-dash-card__footer--min-height | pixel | 36px | |
--c2-dash-card__footer--padding-block | padding | 6px | |
--c2-dash-card__footer--padding-inline | padding | 12px | |
--c2-dash-card__footer--gap | pixel | 8px | |
--c2-dash-card__footer--background | background | transparent | |
--c2-dash-card__footer--border-top | border | none | |
--c2-dash-card__footer--color | color | #71717a | |
--c2-dash-card__footer--font-size | pixel | 12px | |
--c2-dash-card__actions--gap | pixel | 8px | |
--c2-dash-card__controls--gap | pixel | 2px | |
--c2-dash-card__controls--offset | pixel | 4px | Inset of the floating control group from the top-right corner, used only while the header row is off. |
--c2-dash-card__control--size | pixel | 24px | |
--c2-dash-card__control--icon-size | pixel | 16px | |
--c2-dash-card__control--border-radius | border-radius | 6px | |
--c2-dash-card__control--color | color | #71717a | |
--c2-dash-card__control--background | background | transparent | |
--c2-dash-card__control__hover--background | background | #f4f4f5 | |
--c2-dash-card__control__hover--color | color | #18181b | |
--c2-dash-card__control__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | |
--c2-dash-card__control__focus--outline-offset | pixel | 2px | |
--c2-dash-card__handle--size | pixel | 6px | Smallest thickness of the grab area on an edge. Inside a grid the handle is as thick as the gutter when that is wider, centred on the edge, so the whole gutter drags. |
--c2-dash-card__handle--inset | pixel | 2px | Gap between the handle's visible bar and the ends of the edge. |
--c2-dash-card__handle--background | background | transparent | |
--c2-dash-card__handle--border-radius | border-radius | 999px | |
--c2-dash-card__handle--transition-duration | duration | 150ms | |
--c2-dash-card__handle__hover--background | background | rgba(2, 101, 220, 0.2) | |
--c2-dash-card__handle__active--background | background | rgb(2, 101, 220) | |
--c2-dash-card__handle__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | |