Panel System
The Panel system provides a fluent API for creating flex-based layouts. It eliminates the need to manually combine CSS classes and makes layout intent clear in code.
Quick Start
// Create a two-column layout var main = content.Add(Panel.Row().Grow()); var left = main.Add(Panel.Col().Percent(60)); var right = main.Add(Panel.Col().Percent(40));
Creating Panels
Panels are created using static factory methods:
Panel.Row() // Horizontal: children flow left → right Panel.Col() // Vertical: children flow top → bottom
Rule: Always start with Row() or Col() - these set the flex direction.
Sizing
How much space does this panel take?
| Method | Behavior | Use When |
|---|---|---|
| .Grow() | Fills available space | Charts, main content areas |
| .Fixed() | Sizes to content | Filter bars, tables, headers |
| .Percent(n) | Proportional width | Side-by-side columns |
// Fixed-size header, growing content var header = container.Add(Panel.Row().Fixed()); var content = container.Add(Panel.Col().Grow()); // 60/40 split var left = main.Add(Panel.Col().Percent(60)); var right = main.Add(Panel.Col().Percent(40));
Supported percentages: 25, 33, 40, 50, 60
Content Behavior
How do children behave inside this panel?
| Method | Behavior | Use When |
|---|---|---|
| .Fill() | Children can grow to fill | Parent of charts with .WithFill() |
| .Scroll() | Scrollbars when overflow | Tables that might be wide/tall |
// Chart needs Fill() in its parent chain var chartPanel = container.Add(Panel.Col().Grow().Fill()); // Table that might overflow var tablePanel = container.Add(Panel.Col().Fixed().Scroll());
Visual Styling
| Method | Behavior |
|---|---|
| .Card() | White background, border, rounded corners, padding |
var card = container.Add(Panel.Col().Grow().Fill().Card());
The Golden Rule: Flex Chain
For a chart with .WithFill() to grow properly, every ancestor must be a flex container.
❌ BROKEN - Div breaks the chain
Panel.Col().Grow()
└── new Div() ← Not a flex container!
└── chart.WithFill() ← Can't grow
✅ WORKING - Unbroken chain
Panel.Col().Grow()
└── Panel.Col().Grow().Fill()
└── chart.WithFill() ← Works!
Rule: If you need a wrapper, use Panel not Div.
Common Patterns
Full-Page Layout
// Make content fill viewport
content.CssClass = CoreCss.PanelCol;
content.Style.Flex("1");
// Fixed header, growing body
var header = content.Add(Panel.Row().Fixed());
var body = content.Add(Panel.Row().Grow());
Two-Column Dashboard
var main = content.Add(Panel.Row().Grow()); // Left: 60% width, vertical stack var left = main.Add(Panel.Col().Percent(60)); var leftTop = left.Add(Panel.Row().Fixed()); // KPIs var leftMiddle = left.Add(Panel.Col().Grow().Fill()); // Chart var leftBottom = left.Add(Panel.Col().Fixed()); // Table // Right: 40% width var right = main.Add(Panel.Col().Percent(40));
2x2 Grid
var container = parent.Add(Panel.Col().Grow()); var topRow = container.Add(Panel.Row().Grow()); var topLeft = topRow.Add(Panel.Col().Grow().Fill().Card()); var topRight = topRow.Add(Panel.Col().Grow().Fill().Card()); var bottomRow = container.Add(Panel.Row().Grow()); var bottomLeft = bottomRow.Add(Panel.Col().Grow().Fill().Card()); var bottomRight = bottomRow.Add(Panel.Col().Grow().Fill().Card());
Card with Chart
var chartCard = parent.Add(Panel.Col().Grow().Fill().Card());
chartCard.Add(new Div(CoreCss.ChartTitle).WithText("My Chart"));
chartCard.Add(new ChartElement(
new BarChart()
.FromData(data, "category", "value")
.WithFill()));
Card with Scrollable Table
var tableCard = parent.Add(Panel.Col().Card().Scroll()); tableCard.Add(new SimpleTable(data, CoreCss.BorderTable));
Method Chaining Order
While order doesn't matter technically, this order reads naturally:
Panel.Col() // 1. Direction
.Percent(60) // 2. Size (or .Grow() or .Fixed())
.Fill() // 3. Content behavior
.Card() // 4. Visual styling
Debugging Layout Issues
Chart not growing?
- Does the chart have .WithFill()?
- Does every parent panel have .Fill() where needed?
- Are you using Panel instead of Div for wrappers?
Content overflowing?
Add .Scroll() to the panel that should scroll.
Columns not sizing correctly?
Make sure parent is Panel.Row() - percentage widths only work in row containers.
CSS Classes Reference
The Panel methods map to these CSS classes:
| Method | CSS Class |
|---|---|
| Panel.Row() | panel-row |
| Panel.Col() | panel-col |
| .Grow() | panel-grow |
| .Fixed() | panel-fixed |
| .Percent(20) | panel-20 |
| .Percent(25) | panel-25 |
| .Percent(33) | panel-33 |
| .Percent(40) | panel-40 |
| .Percent(50) | panel-50 |
| .Percent(60) | panel-60 |
| .Fill() | panel-fill |
| .Scroll() | panel-scroll |
| .Card() | panel-card |