upp-panel
A structured panel component that organizes content into three distinct regions: header, content, and footer. The panel supports configurable sizing and optional border lines, making it suitable for dashboards, forms, and card-style layouts.
When to Use
Use upp-panel whenever you need a bordered container with a fixed header, scrollable content area, and an optional footer. Typical use cases include dashboard cards, detail views, and form containers. Panels can be placed side by side and independently sized.
Demo
Source Code
- HTML
- TypeScript
- SCSS
<h2>upp-panel — Dashboard Cards</h2>
<p class="demo-description">Three <code>upp-panel</code> cards forming a mini dashboard. Each has a header, metric content, and footer with actions.</p>
<div class="demo-controls">
<ion-button size="small" (click)="toggleLines()">Lines: {{ panelLines }}</ion-button>
<ion-button size="small" (click)="cycleSize(0)">Sales: {{ panelSizes[0] }}</ion-button>
<ion-button size="small" (click)="cycleSize(1)">Orders: {{ panelSizes[1] }}</ion-button>
<ion-button size="small" (click)="cycleSize(2)">Alerts: {{ panelSizes[2] }}</ion-button>
</div>
<div class="panel-row">
<div class="panel-col" *ngFor="let card of cards; let i = index">
<div class="panel-wrapper">
<upp-panel [size]="panelSizes[i]" [lines]="panelLines">
<upp-panel-header>
<upp-header [color]="card.color" menu="hide" height="40px">
<upp-header-title>{{ card.title }}</upp-header-title>
<upp-header-button>
<ion-icon [name]="card.icon"></ion-icon>
</upp-header-button>
</upp-header>
</upp-panel-header>
<upp-panel-content>
<div class="metric">
<span class="metric-value">{{ card.value }}</span>
<span class="metric-label">{{ card.label }}</span>
</div>
</upp-panel-content>
<upp-panel-footer>
<ion-item lines="none" button detail>
<ion-icon name="arrow-forward-outline" slot="start" color="medium"></ion-icon>
<ion-label color="medium">View details</ion-label>
</ion-item>
</upp-panel-footer>
</upp-panel>
</div>
</div>
</div>
import { Component } from '@angular/core';
import { ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'demo-upp-panel',
templateUrl: './demo-upp-panel.html',
styleUrls: ['../demo-common.scss', './demo-upp-panel.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DemoUppPanelComponent {
panelLines: 'show' | 'hide' = 'hide';
panelSizes: Array<'small' | 'auto' | 'large'> = ['small', 'auto', 'large'];
cards = [
{ title: "Today's Sales", value: '€1,245', label: 'Revenue today', color: 'success', icon: 'cash-outline' },
{ title: 'Active Orders', value: '38', label: 'Orders in progress', color: 'primary', icon: 'receipt-outline' },
{ title: 'Low Stock Alerts', value: '7', label: 'Items below threshold', color: 'warning', icon: 'alert-circle-outline' }
];
toggleLines() {
this.panelLines = this.panelLines === 'show' ? 'hide' : 'show';
}
cycleSize(index: number) {
const sizes: Array<'small' | 'auto' | 'large'> = ['small', 'auto', 'large'];
const current = sizes.indexOf(this.panelSizes[index]);
this.panelSizes[index] = sizes[(current + 1) % sizes.length];
}
}
:host {
display: block;
padding: 16px;
}
.panel-row {
display: flex;
gap: 12px;
}
.panel-col {
flex: 1;
min-width: 0;
}
.panel-wrapper {
height: 260px;
}
.metric {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 24px 16px;
text-align: center;
}
.metric-value {
font-size: 36px;
font-weight: 700;
line-height: 1.1;
color: var(--ion-color-dark, #222);
}
.metric-label {
margin-top: 8px;
font-size: 13px;
color: var(--ion-color-medium, #888);
}
API Reference
upp-panel
The main panel container. Use the sub-components to define header, content, and footer regions.
| Property | Type | Default | Description |
|---|---|---|---|
size | 'small' | 'auto' | 'large' | 'auto' | Controls the panel size. 'small' renders a compact layout, 'large' a wider one, and 'auto' adapts to the available space. |
lines | 'show' | 'hide' | 'hide' | Controls whether a visible border is drawn around the panel. |
The component applies CSS classes dynamically based on these inputs (--small, --auto, --large, --border-show, --border-hide).
upp-panel-header
Content-projection wrapper for the panel header. Typically contains a upp-header or a title element. Rendered at the top of the panel with a fixed height.
No inputs or outputs.
upp-panel-content
Content-projection wrapper for the main body of the panel. This region fills the available vertical space between the header and footer and can scroll if the content overflows.
No inputs or outputs.
upp-panel-footer
Content-projection wrapper for the panel footer. Rendered at the bottom of the panel with a fixed height. Useful for action buttons, status indicators, or summary information.
No inputs or outputs.