Dashboard Layout and Components#
Superset's dashboard edit mode is built on a React-based grid system using react-dnd for drag-and-drop and re-resizable for resizing. All layout state lives in Redux and is serialized as a flat map of component nodes (the "layout tree").
Grid Constants#
All sizing is derived from two base values defined in constants.ts:
| Constant | Value | Purpose |
|---|---|---|
GRID_BASE_UNIT | 8 px | Minimum snap unit for height |
GRID_GUTTER_SIZE | 16 px (2 × GRID_BASE_UNIT) | Horizontal spacing between columns |
GRID_COLUMN_COUNT | 12 | Total columns in the grid |
GRID_MIN_ROW_UNITS | 5 | Minimum height of a chart (in base units) |
GRID_MAX_ROW_UNITS | 100 | Maximum height of a chart (in base units) |
GRID_DEFAULT_CHART_WIDTH | 4 | Default chart width in columns |
Pixel width of a resizable item is computed as (widthStep + gutterWidth) × widthMultiple − gutterWidth, where widthStep = columnWidth and gutterWidth = GRID_GUTTER_SIZE . Height is heightStep × heightMultiple where heightStep = GRID_BASE_UNIT .
Component Type Registry#
Every layout node has a type string drawn from componentTypes.ts:
- Containers:
GRID,ROOT,ROW,COLUMN,TABS,TAB - Content:
CHART,MARKDOWN,HEADER,DIVIDER - Special:
NEW_COMPONENT_SOURCE(palette drag source),DYNAMIC(lazy-loaded custom components)
The runtime component lookup (gridComponents/index.js) maps each type constant to its React component for dynamic rendering.
Component Nesting Rules#
isValidChild.ts enforces the nesting hierarchy using a parentMaxDepthLookup table. Key rules:
GRIDaccepts:CHART,ROW,COLUMN,TABS,MARKDOWN,HEADER,DIVIDER,DYNAMICROWaccepts:CHART,COLUMN,MARKDOWN,DYNAMIC— notDIVIDERorHEADERCOLUMNaccepts:CHART,HEADER,MARKDOWN,ROW,DIVIDER,TABSCHART,DIVIDER,HEADER,MARKDOWNhave no valid childrenTABS/TABdo not increment nesting depth, allowing valid paths likeROOT > GRID > TABS > TAB > ROW > COLUMN > CHART
Builder Component Pane (Layout Palette)#
BuilderComponentPane/index.tsx renders a 374 px sticky side panel with two tabs:
- Charts — a
SliceAddersearch list of saved charts - Layout elements — draggable palette items:
NewTabs,NewRow,NewColumn,NewHeader,NewMarkdown,NewDivider, plus any registered dynamic components
Each New* item wraps DraggableNewComponent — a thin layer that configures DragDroppable with the component's type, a NEW_*_ID constant for its source identity, and an Ant Design icon + label for the palette UI. The parent is set to NEW_COMPONENTS_SOURCE_ID so drop handlers can distinguish palette drops from existing-component moves.
ResizableContainer#
ResizableContainer.tsx wraps re-resizable and provides the snap-to-grid behavior. Resize handles appear on hover (right, bottom, bottom-right) and are only enabled in editMode . On onResizeStop, the delta is converted back to grid multiples: nextWidthMultiple = widthMultiple + round(delta.width / (widthStep + gutterWidth)) .
ChartHolder#
ChartHolder.tsx is the layout wrapper for every chart on the canvas. It:
- Resolves
widthMultiplefrom the component'smeta.width, clamping it to the parent column's width if nested inside aCOLUMN - Computes
chartWidth = widthMultiple × columnWidth + (widthMultiple − 1) × GRID_GUTTER_SIZE − CHART_MARGINandchartHeight = meta.height × GRID_BASE_UNIT − CHART_MARGIN, whereCHART_MARGIN = 32px - Width is only adjustable when the parent is
ROW_TYPE; height is always adjustable - Wraps the chart in a
Draggable(drag source only) with orientation based on parent type
Divider Component#
The DIVIDER is a non-container leaf component used as a visual separator. It consists of two files:
NewDivider.jsx— the palette entry; usesNEW_DIVIDER_IDandDIVIDER_TYPE, renders withIcons.LineOutlinedDivider.jsx— the canvas component; renders aDividerLinestyled div: 1 pxgrayscale.light2::afterpseudo-element withsizeUnit × 2vertical padding for a larger mouse target . In edit mode shows aHoverMenuwith a delete button . Orientation is always"row"since it can be placed insideGRIDorCOLUMNbut notROW.
Key Source Locations#
| Path | Purpose |
|---|---|
src/dashboard/util/constants.ts | Grid numeric constants |
src/dashboard/util/componentTypes.ts | Component type string constants |
src/dashboard/util/isValidChild.ts | Parent–child nesting rules |
src/dashboard/components/BuilderComponentPane/ | Side-panel palette |
src/dashboard/components/gridComponents/index.js | All canvas components + componentLookup |
src/dashboard/components/resizable/ResizableContainer.tsx | Grid-snapping resize wrapper |
src/dashboard/components/gridComponents/ChartHolder.tsx | Chart layout + resize integration |
src/dashboard/components/dnd/DragDroppable.jsx | Core DnD HOC (Draggable / Droppable) |
src/dashboard/actions/dashboardLayout.js | Redux drop handler and layout mutations |