A frontend-only interactive dashboard built with React and Vite to explore GridStack (v12.4.x). You can add sections and widgets, configure grid options, and observe behavior in real time without a backend.
- React 19 + Vite 8
- GridStack 12.4.x — one
GridStackinstance per column (see architecture below)
npm install
npm run devOpen the URL shown in the terminal (typically http://localhost:5173).
npm run build # production build
npm run preview # serve the built app locally- The dashboard is a vertical stack of sections.
- Each section has one or more columns (flex row). Column widths come from templates (e.g. 50/50, 66/33, three equal columns).
- Each column hosts its own independent
GridStackinstance. Widgets do not move between columns or between sections automatically; sections act as hard boundaries.
- Widgets are full width of their column (
w: 12,x: 0for user-added and library-dragged items). Horizontal resize is disabled; only vertical resize is enabled (resizablehandles:s).
- Default options (sidebar): global defaults for new behavior and for merging.
- Per-section overrides (gear icon on a section header in Builder): each section can override many of the same options. Overrides merge with defaults;
undefinedmeans inherit. - Global-only options (not overridable per section):
column,rtl,animate,alwaysShowResizeHandle— always taken from the default options.
- Builder: editing controls, sidebar, event log, widget drag-in from the library, section gear, collapse empty is not applied visually (you can still configure it for preview).
- Preview: read-only style view; collapse empty and other preview-only behaviors apply; sidebar and most editing UI are hidden.
- Builder / Preview mode toggle.
| Area | Purpose |
|---|---|
| Section templates | Add a new section from presets (1 column, 2 columns, 3 columns, various splits, nested-style previews). |
| Widget library | Drag predefined templates into a column grid. |
| Default options | Global GridStack defaults: columns, cell height, margin, float, min/max row, static grid, drag/resize toggles, removable, RTL, size-to-content, resize-handle behavior, collapse empty, etc. Helper text (?) on controls. |
| Add widget | Programmatically add a widget to the active column (click a column first to set target; otherwise the first section’s first column). |
| Selected widget | When a widget is selected, edit its properties (row, height, min/max height, locked, no move, no resize) and delete it. |
| Actions | Save / load layout (JSON), compact, remove all, enable/disable grid, etc. |
- Sections: each has a header (label, description), gear (section options), reorder, remove.
- Columns: click a column to activate it for “Add widget”; active column is highlighted.
- Event log (Builder): GridStack events (added, removed, change, drag, resize, etc.).
- Collapse empty (Preview): collapses columns with no widgets and can hide fully empty sections. It does not remove the vertical gap when one column is shorter than another in the same row (that comes from flex column stretching and grid row height).
- Margin (GridStack): spacing between widgets inside a column; exposed as default + section overrides. The app applies CSS variables (
--gs-item-margin-*) so margins stay consistent with GridStack. - Section row: flex layout with gap and padding between columns for clearer separation than a single-pixel divider.
- Save exports a nested structure: sections with columns and widget layouts (per grid).
- Load replaces sections with new IDs to avoid collisions.
| Path | Role |
|---|---|
main.jsx |
React root (no StrictMode — avoids double-mount issues with GridStack in dev). |
App.jsx |
Global state: sections, default options, section overrides, mode, selection, active column, events. |
App.css |
App layout, panels, sections, GridStack overrides, widget chrome. |
components/GridDashboard.jsx |
Renders sections; merges defaults + overrides; forwardRef API. |
components/DashboardSection.jsx |
One section: multiple grids, events, collapse-empty, preview rules. |
components/GridOptionsPanel.jsx |
Default options + exported GridOptionControls for section gear. |
components/SectionTemplates.jsx |
Template definitions and preview thumbnails. |
components/WidgetLibrary.jsx |
Draggable template tiles. |
components/AddWidgetPanel.jsx |
Add widget form (full-width widgets). |
components/SelectedWidgetPanel.jsx |
Selected widget inspector + delete. |
components/ActionsPanel.jsx |
Save/load/compact/utility actions. |
components/EventLog.jsx |
Event stream. |
components/HelpTip.jsx |
Viewport-aware tooltips for sidebar help. |
App holds a ref to GridDashboard. Useful methods include:
addWidget(opts)— add to active column, or first section / first column if none active.removeWidget(id),updateWidget(id, opts)save(),load(data)compact(layout),removeAll()enableGrid()/disableGrid()getWidgetNodes()
- Section boundaries — widgets stay within their section/column grids; no cross-section auto-fill.
- Full column width — widgets span the column; no horizontal resize in the UI.
- Preview vs Builder — collapse-empty and similar are configured in Builder but applied in Preview where relevant.
This is a playground for learning GridStack behavior. GridStack is licensed under its own terms; see the GridStack repository.