Page layouts

PageLayoutControl · SplitterControl · DashboardLayoutControl

An application shell with collapsible side panels and a splitter, and a dashboard grid.

Overview

Three ways to divide a page. PageLayoutControl is a flex row of LeftPanelControl, CenterPanelControl and RightPanelControl; the side panels collapse to a 20px tab. SplitterControl puts a draggable bar between two panes, in pixels or as a share of the container, with keyboard resizing. DashboardLayoutControl is a CSS grid of panels placed by row, column and span; change those values and the grid re-flows.

Examples

#Application shell: panels and a splitter

PageLayoutControl rows up a navigation panel, the centre and a properties panel; each side panel collapses from its own tab or from the icon buttons in the centre, because Collapsed binds two ways. The centre holds a SplitterControl: drag the bar, or Tab to it and use the arrow keys, Home and End; double-click restores the first size. Bind PrimarySize two ways and persist from OnResizeCommitted, which fires once per gesture. The navigation, list and properties are wired together, so click around.

Example
Razor
C#

Navigation

Estimates

EST-2042 Contoso

14 lines · Draft · $18,240 · last saved today 09:12

Properties

Customer
Contoso
Status
Draft
Lines
14
Total
$18,240
List pane 200 px, 0 commits · navigation shown, properties shown

#Dashboard grid

Columns sets the grid; each panel takes Row, Column, SizeX and SizeY, here from page state. Click a KPI card to expand it across the row and back; hover one for its comparison. A panel is exactly its grid box, so spans are chosen to fit the cards. No script.

Example
Razor
C#
1,234
Orders
↑ +5.2%
$89K
Revenue
↑ +12%
98.5%
Uptime
↑ +0.1%
Traffic
069138206275 120.0180.0210.0190.0250.0140.0100.0MonTueWedThuFriSatSun
Sources
Organic: 55.0 (55.0%)Paid: 25.0 (25.0%)Referral: 15.0 (15.0%)Direct: 5.0 (5.0%)
Organic
Paid
Referral
Direct
Three KPI cards on row 0, charts on rows 2–4.

Documentation

PageLayoutControl and panels

ParameterTypeDefaultDescription
PageLayoutControl.Heightstring?"100%"Height of the flex row; panels fill it.
PageLayoutControl.CssClassstring?nullExtra classes on the row.
Left/RightPanelControl.Widthstring?"250px"Panel width when open.
Left/RightPanelControl.CollapsibleboolfalseShows the 20px tab that collapses the panel.
Left/RightPanelControl.CollapsedboolfalseCollapsed state. Two-way with @bind-Collapsed.
CenterPanelControl—Takes the remaining width. Only CssClass and content.

SplitterControl

ParameterTypeDefaultDescription
PrimaryContent / SecondaryContentRenderFragment?—The two panes. Primary is left or top.
Verticalbooltruetrue: vertical bar, panes side by side. false: horizontal bar, panes stacked.
PrimarySizedouble240Primary pane size in px, or percent in Proportional mode. Bind it two ways: a parent re-render otherwise resets the pane to the parameter value.
SizeModeSplitterSizeModePixelPixel keeps the size through container resizes; Proportional keeps the ratio, pure CSS.
OnResizeCommittedEventCallback<double>—Fires once when a drag or key press finishes. Persist from here.
ResizeOnReleasebooltrueGuide while dragging, panes resize on release. false resizes live through the server.
MinPrimarySize / MaxPrimarySizedouble80 / 1200Pixel limits.
MinPrimary / MaxPrimary / MinSecondarystring?nullLimits that also take a percentage; they win over the pixel ones.
ShrinkPrimaryToContentboolfalseCaps the primary pane at its content size.
DefaultPrimarySize / ResetOnDoubleClickdouble? / boolnull / trueSize restored by a double-click; defaults to the first size seen.
KeyboardStepdouble16Arrow-key step in px, or percentage points in Proportional mode.
SplitterSizedouble6Bar thickness in px.
DisabledboolfalseBar cannot be dragged or focused.
Height / Widthstring?nullContainer size.
Titlestring"Resize"Bar tooltip and accessible name.
CssClass / Stylestring?nullOn the container.

DashboardLayoutControl and DashboardLayoutPanel

ParameterTypeDefaultDescription
Columnsint1Grid columns, equal width.
CellSpacingdouble[]?null (0, 0)Column and row gap in px, as a two-element array.
CellAspectRatiodouble1Height of one cell relative to its width; 1 is square. A panel is exactly its grid box and does not grow for tall content.
CssClassstring?nullExtra classes on the grid.
Panel.Row / Panel.Columnint0Zero-based placement.
Panel.SizeX / Panel.SizeYint1Column and row span.
Panel.ContentTemplate / ChildContentRenderFragment?—Panel content; the template wins when both are set.

CSS classes

ClassEffect
fx-page-layout · fx-left-panel · fx-center-panel · fx-right-panelFlex row and its panels. Side panels: grey, bordered, scroll their own content; .fx-panel-collapsed at zero width.
fx-panel-toggle · -left · -rightThe 20×40px collapse tab, hung outside the panel edge.
fx-splitter · -vertical · -horizontal · -disabledContainer and orientation.
fx-splitter-pane · -primary · -secondary · fx-splitter-bar · fx-splitter-gripPanes, the bar and its grip.
fx-splitter-overlay · fx-splitter-guide · fx-splitter-server-guideDrag-time overlay and the guide line.
fx-dashboard-layout · fx-dashboard-panels · fx-dashboard-panelThe grid, a display: contents wrapper, and each item with its grid placement and aspect ratio inline.

CSS variables

VariableFallbackPurpose
--fx-splitter-size6pxBar thickness; set by SplitterSize.
--fx-zoom1Scales the collapse-tab glyph.

Keyboard and accessibility

  • Panel collapse tabs are native buttons titled "Collapse panel" / "Expand panel"; their only text is an arrow glyph.
  • The splitter bar is a native button with role="separator", aria-orientation and the Title as its name. Arrow keys move it by KeyboardStep, Home and End go to the limits, double-click resets.
  • The splitter imports the library's own splitter-control.js for the drag guide and measuring. No third-party script. Page layout and dashboard are CSS only.
  • Dashboard panels are plain grid items with no landmarks or headings of their own; give each panel's content a heading.
An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.