KPI Cards
Responsive KPI cards with icons, values, and percentage changes. Auto-adjusts from 1 to 4 columns based on screen size. Three style variants (Standard, Compact, Filled), theme-aware styling. 12 controls, 6 properties.
Import via Components → New component → Import from code → paste YAML
Preview
All Assets
118
In Use
6
Available
111
Expiring Soon
1
Installation
This component requires Modern controls to be enabled. Settings → Updates → Preview → Modern controls and themes
Copy the YAML component definition and import into Power Apps Studio.
# In Power Apps Studio:
1. Components → New component → Import from code
2. Paste YAML definition
3. Component appears in library
4. Add to screens for KPI displayProperties
Input
| Property | Type | Default |
|---|---|---|
DataTable of KPI items. Each row needs Icon, Value, Label, PercentChange, PercentLabel, IconBg, IconColor. Optional: isHidden, ID. | Table | 4 sample cards |
Style"Standard" (icon top-right, footer), "Compact" (icon left, inline percent), or "Filled" (colored background from IconBg, no icon). | Text | "Compact" |
StyleConfigRecord with colors, space, radius, type, and heights tokens. Type tokens: value (size/sizeCompact/weight), label (size/weight), body (size/weight). | Record | Light theme tokens |
IconsTable of {Name, SVG} rows. SVG strings use "COLOR" placeholder replaced at runtime by IconColor. | Table | 6 built-in icons |
ColumnsLayoutRecord with Mobile, Tablet, Desktop column counts and breakpoint widths. | Record | {Mobile:1, Tablet:2, Desktop:4} |
AnimationEffect"Pop" (scale in), "Push" (slide), or "None" (instant). | Text | "Pop" |
Events
| Event | Description |
|---|---|
OnCardClick | Fires when any card is tapped. Receives the full KPI record as ClickedItem (ID, Icon, Value, Label, PercentChange, PercentLabel, IconBg, IconColor). |
Implementation Details
Responsive grid system
The component renders a vertical Gallery with WrapCount driven by responsive breakpoints. At runtime, App.Width is compared against ColumnsLayout.MobileBreakpoint (640) and TabletBreakpoint (1024) to select 1, 2, or 4 columns. Gallery template contains a ManualLayout GroupContainer (conKPICard) that holds all card internals.
Icon library
Icons are rendered as inline SVG via an Image control. The Icons table contains raw SVG strings with a “COLOR” placeholder that gets replaced by ThisItem.IconColor at runtime using Substitute(). The encoded SVG is passed as a data URI to the Image property. Custom icons can be added to the Icons table.
Three style variants
Icon top-right in a 48 px circle. 190 px tall card with value center-left and a footer row showing percent + label.
Best for: Full dashboards, detail views
Icon left-aligned, value and percent inline on one row. 88 px tall — roughly half the height of Standard.
Best for: Above tables, tight layouts, mobile
Card background becomes IconBg, all text becomes IconColor, icon circle is hidden, border drops to 0. Same data columns — no extra fields needed.
Best for: Hero rows, landing pages, exec summaries
Dynamic height
Component height is calculated from the visible card count, breakpoint column count, and card height (88px Compact vs 190px Standard/Filled), plus appropriate padding. This prevents clipping when cards wrap to multiple rows on narrower screens.
Examples
Responsive layout — mobile, tablet, desktop
All Assets
118
In Use
6
Available
111
Expiring Soon
1
All Assets
118
↑ +14%In Use
6
↓ -8%Available
111
↑ +12%Expiring Soon
1
All Assets
118
↑ +14%In Use
6
↓ -8%Available
111
↑ +12%Expiring Soon
1
ColumnsLayout: {Mobile: 1, MobileBreakpoint: 640, Tablet: 2, TabletBreakpoint: 1024, Desktop: 4}
Basic static data
All Assets
118
In Use
6
Available
111
Expiring Soon
1
// Simple static data
cmpKPIDashboard.Data: Table(
{
Icon: "Box",
Value: 118,
Label: "All Assets",
PercentChange: 14,
PercentLabel: "vs last month",
IconBg: "#EBF5FF",
IconColor: "#2196F3"
},
{
Icon: "TrendLines",
Value: 6,
Label: "In Use",
PercentChange: -8,
PercentLabel: "vs last month",
IconBg: "#FFF3E0",
IconColor: "#FF9800"
}
)Compact — above a data table
All Assets
In Use
Available
Expiring Soon
cmpKPI.Style = "Compact"
// Compact cards are 88px tall — perfect
// for placing above a gallery or table.
// Inline percent sits next to the value.
cmpKPI.OnCardClick =
Set(varSelectedStatus, ClickedItem.Label);
UpdateContext({locFilter: ClickedItem.Label})Filled — executive summary
All Assets
118
In Use
6
Available
111
Expiring Soon
1
cmpKPI.Style = "Filled"
// Card Fill = ColorValue(ThisItem.IconBg)
// All text = ColorValue(ThisItem.IconColor)
// Icon circle is hidden — the card IS the color
// No new data columns needed
// Dark mode: swap IconBg/IconColor for
// darker values or override StyleConfigLive data — SharePoint connection
Total Value
$45.2K
Open Orders
234
// Named formula — declarative, auto-refreshing
KPIData =
ForAll(
GroupBy(Assets, "Status", "Group"),
{
ID: CountRows(Group),
Icon: Switch(Status,
"Available", "Package",
"In Use", "TrendLines",
"Box"
),
Value: CountRows(Group),
Label: Status,
PercentChange: Round(
(CountRows(Group) - varPrev)
/ varPrev * 100, 0
),
PercentLabel: "vs last month",
IconBg: Switch(Status,
"Available", "#E8F5E9",
"#EBF5FF"
),
IconColor: Switch(Status,
"Available", "#4CAF50",
"#2196F3"
)
}
)
cmpKPI.Data = KPIDataClick interactions — navigate with context
All Assets
In Use
// Handle card clicks
cmpKPIDashboard.OnCardClick:
Navigate(
DetailsScreen,
ScreenTransition.Push,
{
SelectedKPI: ThisItem.Label,
KPIValue: ThisItem.Value
}
)
// Or update a variable
cmpKPIDashboard.OnCardClick:
Set(varSelectedKPI, ThisItem);
Set(varShowDetails, true);Data Schema
Data record
| Field | Type | Notes |
|---|---|---|
| ID | Number | Optional. Unique identifier for each card. |
| Icon | Text | Name matching an Icons table entry (e.g. "Box", "TrendLines", "Warning"). |
| Value | Number | Main KPI value displayed as large text. |
| Label | Text | Card title shown above the value. |
| PercentChange | Number | Trend percentage. Positive = green ↑, negative = red ↓. Blank to hide. |
| PercentLabel | Text | Footer text next to percent (e.g. "vs last month"). Blank to hide. |
| IconBg | Text | Hex background for icon circle. In Filled style, becomes the entire card background. |
| IconColor | Text | Hex color for icon SVG stroke. In Filled style, becomes all text color. |
| isHidden | Boolean | Optional. Set true to hide a card without removing it from the data source. |
Architecture
12 controls — 5 Text@0.0.51, 2 Classic/Button, 1 Image, 4 GroupContainer.
6 input properties — Data, Style, StyleConfig, Icons, ColumnsLayout, AnimationEffect.
1 event — OnCardClick.
Default size — Parent.Width × dynamic height. Card height: 88px (Compact) or 190px (Standard/Filled).
cmpKPI (Parent.Width × dynamic height)
└── cntStatsRow (GroupContainer — AutoLayout, horizontal wrap)
└── galKPIs (Gallery — vertical, WrapCount by breakpoint)
└── conKPICard (GroupContainer — ManualLayout)
├── txtLabel (Text@0.0.51 — card title, 13px semibold)
├── cntValueRow (GroupContainer — AutoLayout horizontal)
│ ├── txtValue (Text@0.0.51 — main number, FillPortions=1)
│ └── txtPercentInline (Text@0.0.51 — Compact only, W=70)
├── cntKPIFooter (GroupContainer — AutoLayout, Standard+Filled)
│ ├── txtFooterPercent (Text@0.0.51 — ↑/↓ percent, 14px)
│ └── txtFooterSub (Text@0.0.51 — "vs last month", 12px)
├── btnIconBg (Classic/Button — icon circle, hidden in Filled)
├── imgIconKPI (Image — inline SVG, hidden in Filled)
└── btnCardOverlay (Classic/Button — OnSelect → OnCardClick)
Style switching:
Filled → card Fill=IconBg, text=IconColor, icon hidden, border=0
Compact → 88px height, icon left, inline percent, no footer
Standard → 190px height, icon top-right, footer with percent+label