NewPower Apps · canvas componentData display✓ Tested in StudioMIT License
KPI card
One number with its label as a count, money, a percentage or 12.4K; the change against a previous value, coloured by whether up is good; progress toward a target with a status that follows it; and OnSelect to open the list behind it.
- Name in Studio
- lcsKpiCard
- Version
- 0.1.0
- Properties
- 15 inputs · 6 outputs · 1 event
Variations
As it is when you paste it, with every input at its default.
Trend: Up · Status: Good · ValueText: 128
Formulas on this screen
Set the same ones in Studio to try it the same way; there, each Notify shows its event in a banner, which this preview leaves out so nothing covers the component. The instance names are the ones Studio gives the first copy on a screen.
Text1.Text = "Trend: " & lcsKpiCard_1.Trend & " · Status: " & lcsKpiCard_1.StatusShown & " · ValueText: " & lcsKpiCard_1.ValueText
lcsKpiCard_1.OnSelect = Notify("Selected: " & lcsKpiCard_1.Label)
A web replica that behaves as the component does in Power Apps. In Studio it uses Microsoft's controls, which can look slightly different.
Add it in five steps
- In Power Apps Studio, open Settings > Updates and check that Modern controls and themes and Enhanced component properties are on.
- Open the Components tab in the tree view and select New component.
- Select an empty part of Studio, so the new component isn't selected.
- Copy the YAML on this page and press Ctrl+V.
lcsKpiCardappears with all its properties. - On a screen, insert it from Insert > Custom >
lcsKpiCard.
What it needs
- No premium licence: standard controls, no connectors
- Modern controls and themes: on
- Enhanced component properties: on
- Tested in Power Apps Studio 3.26094.9 on October 13, 2026
- Version 0.1.0
Properties (22)
Read from the component's own YAML, so they always match what you paste.
| Property | Kind | Type | Default |
|---|---|---|---|
LabelWhat the number is, such as Open orders. | Input | Text | "Open orders" |
ValueThe number to show, such as CountIf(Orders, Status = "Open"). | Input | Number | 128 |
FormatHow to show Value: Number, Currency, Percent (0.42 shows as 42%), or Compact (12,400 shows as 12.4K). | Input | Text | "Number" |
CurrencySymbolThe symbol before a Currency value, such as $ or €. | Input | Text | "$" |
DecimalsHow many decimal places to show for Number and Currency. | Input | Number | 0 |
PreviousThe value to compare with, such as last week's. Leave it blank to show no change. | Input | Number | 112 |
ChangeLabelWhat the change is against, shown after it, such as vs last week. | Input | Text | "vs last week" |
GoodWhenUp when a rise is good (sales), Down when a fall is good (open tickets), None to colour the change neutrally. | Input | Text | "Up" |
TargetA goal to show progress toward as a bar. Leave it blank for no bar. | Input | Number | 120 |
StatusThe status that tints the icon's circle and the target bar: Auto (good at or above the target, warning from 70%, bad below), Good, Warning, Bad or Neutral. | Input | Text | "Auto" |
IconA modern icon's name shown in a circle tinted by the status, such as Cart, People or Money. Empty for none. | Input | Text | "Cart" |
CaptionA small line under the number when there's no change to show, such as Updated 5 min ago. | Input | Text | "" |
AccentColorYour brand colour, for the icon, the target bar and the focus ring. | Input | Color | RGBA(15, 108, 189, 1) |
ThemeLight, or Dark for a dark screen. | Input | Text | "Light" |
MotionThe target bar fills and the change arrow pops in when the card loads or its values change. None plays for people who've asked their device for reduced motion. | Input | Boolean | true |
| Property | Kind | Type | Default |
|---|---|---|---|
ChangeValue minus Previous; 0 when there's no Previous. | Output | Number | — |
ChangePercentThe change as a fraction of Previous, such as 0.125 for 12.5%; 0 when there's no Previous or it's 0. | Output | Number | — |
TrendUp, Down or Flat. | Output | Text | — |
TargetPercentValue as a fraction of Target, capped at 1; 0 when there's no Target. | Output | Number | — |
StatusShownThe status in effect: Good, Warning, Bad or Neutral, after Auto is worked out. | Output | Text | — |
ValueTextThe number as the card shows it, such as $12.4K, for a tooltip or a summary. | Output | Text | — |
| Property | Kind | Type | Default |
|---|---|---|---|
OnSelect()Runs in your app when the card is selected, such as Navigate to the list behind the number. | Event | — | false |
Guide
Use lcsKpiCard for the row of numbers at the top of a dashboard or a home screen: open orders, revenue this month, on-time delivery, tickets over SLA. Makers rebuild this card for every app, and the hard parts are always the same: formatting the number, working out the change and colouring it the right way round (a fall in open tickets is good), and keeping a target bar honest. This component has them:
- Formats: Number, Currency (with your symbol), Percent (0.42 shows as 42%) and Compact (12,400 shows as 12.4K), with
Decimals; - Change against
Previous, as a percentage with an arrow, coloured byGoodWhen(Up, Down or None); - Target progress as a bar, and a status that follows it (good at or above the target, warning from 70%, bad below) or one you set;
- Outputs your screen can use:
Change,ChangePercent,Trend,TargetPercent,StatusShown,ValueText; OnSelect, so the card opens the detail behind it, and a Caption for cards with no comparison ("Updated 5 min ago").
The examples call it kpiOpen, on a dashboard over a Dataverse table Orders.
The number, and last week's for the change:
// kpiOpen.Label
"Open orders"
// kpiOpen.Value
CountIf(Orders, Status = 'Status (Orders)'.Open)
// kpiOpen.Previous
varOpenLastWeek // set in Screen.OnVisible from your own query or a saved snapshot
// kpiOpen.GoodWhen
"Down" // fewer open orders is good
Money, with a target:
// kpiRevenue.Value
Sum(Filter(Invoices, 'Invoice Date' >= DateAdd(Today(), -30)), Total)
// kpiRevenue.Format and kpiRevenue.CurrencySymbol
"Currency"; "$"
// kpiRevenue.Target
250000
A percentage that must not fall:
// kpiOnTime.Value
CountIf(Deliveries, 'On Time' = true) / Max(1, CountIf(Deliveries, true))
// kpiOnTime.Format
"Percent"
// kpiOnTime.Target
0.95
Open the list behind the number:
// kpiOpen.OnSelect
Navigate(scrOrders, ScreenTransition.None, {filter: "Open"})
A row of cards that fit the screen:
// kpiOpen.Width (and the others)
(Parent.Width - 3 * 16) / 4
- Counts.
CountRows(Orders)on a whole table returns a number Dataverse caches, which can be stale;CountIf(Orders, condition)is exact up to 50,000 rows and delegates. Over 50,000, count in a flow or a view. - Sums and averages.
Sum,Average,MinandMaxdelegate to Dataverse for up to 50,000 rows, with aFilterinside to stay under; they don't delegate to SharePoint. - Previous values. Dataverse has no "last week" built in: query it the same way with the earlier date range, or save a daily snapshot row and read it; set it once in
OnVisibleso the card doesn't recount on every redraw. - Choice columns. Compare the choice value (
Status = 'Status (Orders)'.Open) rather than its text, so the formula delegates.
- The whole card is one button whose name reads the card out: "Open orders: 128, down 12.5% vs last week". Enter and Space run
OnSelect. - The change is never colour alone: the arrow's direction and the text carry it, and
GoodWhenonly changes the colour. - The icon's tinted circle shows the status as colour; the status word is in
StatusShownfor your own labels, the change chip carries its arrow and sign, and the bar's length carries the progress. - With
Motionon, the arrow pops in and the target bar fills when the card loads or its values change, in under a second. None plays for people who've asked their device for reduced motion, andMotionoff draws it at once.
- Percent expects a fraction (0.42), as
CountIfdivisions give; a value already in percent shows as 4,200%: divide by 100. - The change is a percentage of
Previous; whenPreviousis 0 it shows the absolute change instead. - Compact rounds to one decimal: 1,250 shows as 1.3K.
- Width below 200 cramps the value; at 28 points a number longer than about nine characters needs a wider card or Compact.
- 0.1.0: first version: label, value in four formats, change against a previous value with
GoodWhen, target bar and Auto status, icon and caption, the six outputs,OnSelect, light and dark, motion.
Did it work for you?
No ratings yet.Nobody has said it worked in their app yet.
Sign in to rate it or to say it worked in your app.
Comments
No comments yet. Share how you used it, or ask something.
Sign in to comment or reply. Comments show under a display name you choose, never your email.