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.
- 1. Go to the Components tab (right side panel, next to Screens)
- 2. Click New component — this creates a blank component
- 3. Click outside the new component to deselect it
- 4. Paste the YAML with Ctrl+V / ⌘V
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 BuilderGet new components and templates when they drop
One email when something new ships. Unsubscribe anytime.
Community
Use the toolbar to format · or type markdown directly