mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-12-16 02:45:48 -07:00
9.6 KiB
9.6 KiB
Codex Guide: Shared UI (MagicUI + AG Grid)
Applies to all Borealis frontends. Use Data/Engine/web-interface/src/Admin/Page_Template.jsx as the canonical visual reference (no API/business logic). Keep this doc as the single source of truth for styling rules and AG Grid behavior.
- Toast notifications: see
Docs/Codex/TOAST_NOTIFICATIONS.mdfor endpoint, payload, severity variants, and quick test commands.
Page Template Reference
- Purpose: visual-only baseline for new pages; copy structure but wire your data in real pages.
- Header: small Material icon left of the title, subtitle beneath, utility buttons on the top-right.
- Shell: avoid gutters on the Paper.
- Selection column (for bulk actions): pinned left, square checkboxes, header checkbox enabled, ~52px fixed width, no menu/sort/resize; rely on AG Grid built-ins.
- Typography/buttons: IBM Plex Sans, gradient primary buttons, rounded corners (~8px), themed Quartz grid wrapper.
MagicUI Styling Language (Visual System)
- Full-bleed canvas: hero shells run edge-to-edge; inset padding lives inside cards so gradients feel immersive.
- Glass panels: glassmorphic layers (
rgba(15,23,42,0.7)), rounded 16–24px corners, blurred backdrops, micro borders, optional radial flares for motion. - Hero storytelling: start views with stat-forward heroes—gradient StatTiles (min 160px) and uppercase pills (HERO_BADGE_SX) summarizing live signals/filters.
- Summary data grids: use AG Grid inside a glass wrapper (two columns Field/Value), matte navy background, no row striping.
- Tile palettes: online cyan→green; stale orange→red; “needs update” violet→cyan; secondary metrics fade from cyan into desaturated steel for consistent hue families.
- Hardware islands: storage/memory/network blocks reuse Quartz theme in rounded glass shells with flat fills; present numeric columns (Capacity/Used/Free/%) to match Device Inventory.
- Action surfaces: control bars live in translucent glass bands; filled dark inputs with cyan hover borders; primary actions are pill-shaped gradients; secondary controls are soft-outline icon buttons.
- Anchored controls: align selectors/utility buttons with grid edges in a single row; reserve glass backdrops for hero sections so content stays flush.
- Buttons & chips: gradient pills for primary CTAs (
linear-gradient(135deg,#34d399,#22d3ee)success;#7dd3fc→#c084fccreation); neutral actions use rounded outlines withrgba(148,163,184,0.4)borders and uppercase microcopy. - Rainbow accents: for creation CTAs, use dark-fill pills with rainbow border gradients + teal halo (shared with Quick Job).
- AG Grid treatment: Quartz theme with matte navy headers, subtle alternating row opacity, cyan/magenta interaction glows, rounded wrappers, soft borders, inset selection glows.
- Default grid cell padding: keep roughly 18px on the left edge and 12px on the right for standard cells (12px/9px for
auto-col-tight) so text never hugs a column edge. Target the center + pinned containers so both regions stay aligned. - Overlays/menus:
rgba(8,12,24,0.96)canvas, blurred backdrops, thin steel borders; bright typography; deep blue glass inputs; cyan confirm, mauve destructive accents.
Aurora Tabs (MagicUI Tabbed Interfaces)
- Placement: sit directly below the hero title/subtitle band (8–16px gap). Tabs span the full width of the content column.
- Typography: IBM Plex Sans,
fontSize: 15, mixed case labels (textTransform: "none"). UsefontWeight: 600for emphasis, but avoid uppercase that crowds the aurora glow. - Indicator: 3px tall bar with rounded corners that uses the cyan→violet aurora gradient
linear-gradient(90deg,#7dd3fc,#c084fc). Keep it flush with the bottom border so it looks like a light strip under the active tab. - Hover/active treatment: tabs float on a translucent aurora panel
linear-gradient(120deg, rgba(125,211,252,0.18), rgba(192,132,252,0.22))with a 1px inset steel outline. This gradient applies on hover for both selected and non-selected tabs to keep parity. - Colors: base text
MAGIC_UI.textMuted(#94a3b8). Hovering switches toMAGIC_UI.textBright(#e2e8f0). Always forceopacity: 1to avoid MUI’s default faded text on unfocused tabs. - Shape/spacing: tabs are pill-like with
borderRadius: 4(MUI unit1). MaintainminHeight: 44pxso targets are touchable. ProvideborderBottom: 1px solid MAGIC_UI.panelBorderto anchor the rail. - CSS/SX snippet to copy into new tab stacks:
const TAB_HOVER_GRADIENT = "linear-gradient(120deg, rgba(125,211,252,0.18), rgba(192,132,252,0.22))"; <Tabs value={tab} onChange={(_, v) => setTab(v)} variant="scrollable" scrollButtons="auto" TabIndicatorProps={{ style: { height: 3, borderRadius: 3, background: "linear-gradient(90deg,#7dd3fc,#c084fc)", }, }} sx={{ borderBottom: `1px solid ${MAGIC_UI.panelBorder}`, "& .MuiTab-root": { color: MAGIC_UI.textMuted, fontFamily: "\"IBM Plex Sans\", \"Helvetica Neue\", Arial, sans-serif", fontSize: 15, textTransform: "none", fontWeight: 600, minHeight: 44, opacity: 1, borderRadius: 1, transition: "background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease", "&:hover": { color: MAGIC_UI.textBright, backgroundImage: TAB_HOVER_GRADIENT, boxShadow: "0 0 0 1px rgba(148,163,184,0.25) inset", }, }, "& .Mui-selected": { color: MAGIC_UI.textBright, "&:hover": { backgroundImage: TAB_HOVER_GRADIENT, }, }, }} > {TABS.map((t) => ( <Tab key={t} label={t} /> ))} </Tabs> - Interaction rules: tabs should never scroll vertically; rely on horizontal scroll for overflow. Always align the tab rail with the first section header on the page so the aurora indicator lines up with hero metrics.
- Accessibility: keep
aria-label/aria-controlspairs when the panes hold complex content, and ensure the gradient backgrounds preserve 4.5:1 contrast for the text (the current cyan on dark meets this).
Page-Level Action Buttons
- Place page-level actions/buttons/hero-badges in a fixed overlay at the top-right, just below the global menu bar. Match the Filter Editor's placement if an example is needed
Data\Engine\web-interface\src\Devices\Filters\Filter_Editor.jsx: wrapperposition: "fixed",top: { xs: 72, md: 88 },right: { xs: 12, md: 20 },zIndex: 1400, withpointerEvents: "none"on the wrapper andpointerEvents: "auto"on the innerStackso underlying content remains clickable. - Use gradient primary pills and outlined secondary pills (rounded 999 radius, MagicUI colors). Keep horizontal spacing via a
Stack(e.g.,spacing={1.25}); do not nest these buttons inside the title grid or tab rail. - Tabs stay in normal document flow beneath the title/subtitle; the floating action bar should not shift layout. When operators request moving page actions (or when building new pages), apply this fixed overlay pattern instead of absolute positioning tied to tab rails.
- Keep the responsive offsets (xs/md) unless a specific page has a different header height/padding; only adjust the numeric values when explicitly needed to align with a nonstandard shell.
AG Grid Column Behavior (All Tables)
- Auto-size value columns and let the last column absorb remaining width so views span available space.
- Declare
AUTO_SIZE_COLUMNSnear the grid component (exclude the fill column). - Helper: store the grid API in a ref and call
api.autoSizeColumns(AUTO_SIZE_COLUMNS, true)insiderequestAnimationFrame(orsetTimeout(...,0)fallback); swallow errors because it can run before rows render. - Hook the helper into both
onGridReadyand auseEffectwatching the dataset (e.g.,[filteredRows, loading]); skip whileloadingor when there are zero rows. - Column defs: apply shared
cellClass: "auto-col-tight"(or equivalent) to every auto-sized column for consistent padding. Last column keeps the class for styling consistency. - CSS override: ensure the wrapper targets both center and pinned containers so every cell shares the same flex alignment. Then apply the tighter inset to
auto-col-tight:"& .ag-center-cols-container .ag-cell, & .ag-pinned-left-cols-container .ag-cell, & .ag-pinned-right-cols-container .ag-cell": { display: "flex", alignItems: "center", justifyContent: "flex-start", textAlign: "left", padding: "8px 12px 8px 18px", }, "& .ag-center-cols-container .ag-cell .ag-cell-wrapper, & .ag-pinned-left-cols-container .ag-cell .ag-cell-wrapper, & .ag-pinned-right-cols-container .ag-cell .ag-cell-wrapper": { width: "100%", display: "flex", alignItems: "center", justifyContent: "flex-start", padding: 0, }, "& .ag-center-cols-container .ag-cell.auto-col-tight, & .ag-pinned-left-cols-container .ag-cell.auto-col-tight, & .ag-pinned-right-cols-container .ag-cell.auto-col-tight": { paddingLeft: "12px", paddingRight: "9px", }, - Style helper: reuse a
GRID_STYLE_BASE(or similar) to set fonts/icons and--ag-cell-horizontal-padding: "18px"on every grid, then merge it with per-grid dimensions. - Fill column: last column
{ flex: 1, minWidth: X }(no width/maxWidth) to stretch when horizontal space remains. - Pagination baseline: every Quartz grid ships with
pagination,paginationPageSize={20}, andpaginationPageSizeSelector={[20, 50, 100]}. This matches Device List behavior and prevents infinitely tall tables (Targets, assembly pickers, job histories, etc.). - Example: follow the scaffolding in
Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsxand the structure inData/Engine/web-interface/src/Admin/Page_Template.jsx.