Badge
Notification bell with count badge, pulse animation, and custom SVG icon support. 9 properties (8 input + 1 event), 6 controls. Timer-driven pulse when count is zero.
Import via Components → New component → Import from code → paste YAML
Preview
Installation
This component requires Modern controls to be enabled. Settings → Updates → Preview → Modern controls and themes
# In Power Apps Studio:
1. Components tab → New component → Import from code
2. Paste the full YAML definition
3. Add the component to any screen
4. Wire OnSelect to navigate or open a panelUsage
Basic notification badge
// Named formula for unread count
UnreadCount = CountRows(Filter(Notifications, Read = false))
// Component properties
Badge.BadgeCount = UnreadCount
Badge.HasNotifications = UnreadCount > 0
Badge.OnSelect = Navigate(NotificationsScreen)Custom icon and badge color
// Email icon with blue stroke, orange badge
Badge.IconSvg = "<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'><rect x='2' y='4' width='20' height='16' rx='2'/><path d='m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7'/></svg>"
Badge.IconColor = "#2563EB"
Badge.BadgeColor = RGBA(234, 88, 12, 1)
Badge.BadgeCount = CountRows(Filter(Emails, Unread))Pulse-only (no count)
// Activity indicator without a number
Badge.BadgeCount = 0
Badge.HasNotifications = !IsEmpty(
Filter(ActivityLog, Timestamp > User().LastCheckTime)
)
Badge.OnSelect = UpdateContext({locShowActivity: true})Properties
Input
| Property | Type | Default |
|---|---|---|
BadgeColorBackground color of the count badge and pulse dot. | Color | RGBA(220,38,38,1) |
BadgeCountNumber to display. Caps at 99+. Set to 0 for pulse-only mode. | Number | 5 |
HasNotificationsControls badge/pulse visibility. When true with BadgeCount = 0, shows pulse animation. | Boolean | true |
HoverTextTooltip and accessible label for the icon. | Text | "" |
IconColorHex color override for the SVG icon stroke (e.g. "#2563EB"). | Text | "" |
IconSvgRaw SVG markup. Falls back to a bell icon if blank. | Text | "" |
SizeComponent width and height in pixels. | Number | 45 |
Theme"Light" or "Dark". Controls icon stroke color and container border. | Text | "Light" |
Event
| Property | Type | Description |
|---|---|---|
OnSelect | Event | Formula executed when the bell is tapped. Fires via a transparent Classic/Button overlay. |
8 input properties + 1 event. No output properties.
Implementation Details
Auto-sizing badge
Badge width scales with the count: single digits (1–9) render as a circle matching the badge height, two digits (10–99) expand to 20px, and anything over 99 shows “99+” at 24px wide. Height is capped at 45% of the parent container viaMin(20, Parent.Height * 0.45).
Pulse animation
A Timer@2.1.0 runs at 1000ms intervals. The pulse container's size and opacity are computed fromtmrPulse.Value / tmrPulse.Durationusing Power(p, 0.6) for an ease-out curve. The pulse uses a hardcoded red with animated alpha since Power Fx doesn't support extracting RGB channels from a Color value. The count badge uses BadgeColor directly.
SVG icon rendering
The bell icon is rendered in an Image control via a data:image/svg+xml URI. Pass any Lucide or custom SVG to IconSvg to replace the default bell. IconColor overrides the stroke color on the default bell; for custom SVGs, use stroke='currentColor' in your markup and set IconColor to control it.
Tap handling
A transparent Classic/Button overlays the entire component to capture taps and route them to the OnSelect event property. The button shows a subtle hover fill based on the Theme property.
Self-contained
No external dependencies. All colors derive from the Theme and BadgeColor properties. The container border, icon stroke, and hover fill all adapt automatically.
Examples
Email notification (custom icon)
Badge.IconSvg = "<svg ...email icon.../>"
Badge.IconColor = "#2563EB"
Badge.BadgeCount = CountRows(
Filter(Emails, Unread)
)
Badge.OnSelect = Navigate(EmailScreen)Shopping cart (dark, orange badge)
Badge.Theme = "Dark"
Badge.BadgeColor = RGBA(234, 88, 12, 1)
Badge.IconSvg = "<svg ...cart icon.../>"
Badge.BadgeCount = CountRows(ShoppingCart)
Badge.OnSelect = Navigate(CartScreen)Activity pulse (no count)
Badge.BadgeCount = 0
Badge.HasNotifications = !IsEmpty(
Filter(ActivityLog,
Timestamp > User().LastCheckTime)
)
Badge.OnSelect =
UpdateContext({locShowActivity: true})Architecture
6 controls — GroupContainer (manual) + Image + GroupContainer (pulse) + Timer + GroupContainer (badge) + Text + Classic/Button overlay.
9 properties — 8 input + 1 event. No output properties.
Default size — 45 × 45px (controlled by Size property).
Badge (Size × Size, Fill: transparent)
└── cntBellContainer (GroupContainer, ManualLayout)
├── Fill: theme-aware subtle background
├── BorderColor: theme-aware border
├── imgBell (Image)
│ └── data:image/svg+xml (IconSvg or default bell)
├── cntPulseAnimation (GroupContainer)
│ ├── Fill: red with animated opacity (alpha fade-out)
│ ├── Size: animated via Power(p, 0.6)
│ ├── Visible: HasNotifications && BadgeCount = 0
│ └── tmrPulse (Timer, 1000ms, Repeat, hidden)
├── cntNotificationBadge (GroupContainer)
│ ├── Fill: BadgeColor
│ ├── Width: auto-sized (circle → 20px → 24px)
│ ├── Visible: HasNotifications || BadgeCount > 0
│ └── lblNotificationCount (Text@0.0.51)
│ └── "99+" cap, bold, white, centered
└── btnBell (Classic/Button, transparent overlay)
└── OnSelect: Badge.OnSelect()Want to customize this component?
Use the visual builder to configure colors, icons, and behavior without writing code.
Open Builder