Notification Badge Builder

Customize your notification badge and generate PowerFx YAML code

🎨 Visual Component Builder - Configure your badge visually and get a complete, ready-to-import YAML component with your custom defaults. No base component needed!

Configuration

Will display as 5

45px

Live Preview

5

This is how your badge will appear in Power Apps. The count can be overridden dynamically using props.

Complete Component YAML

Full badge component with your customized defaults

# ============================================
# CUSTOMIZED BADGE COMPONENT
# Generated by PowerApps UI Builder
# ============================================
# 
# Configuration:
# - Icon: Bell
# - Count: 5
# - Theme: light
# - Size: 45px
#
# This is a complete, ready-to-use component with your
# custom defaults. Simply copy and import into Power Apps.
#
# ============================================

ComponentDefinitions:
    Badge:
      DefinitionType: CanvasComponent
      AccessAppScope: true
      CustomProperties:
        BadgeCount:
          PropertyKind: Input
          DisplayName: BadgeCount
          Description: Number of notifications (shows count if > 0)
          DataType: Number
          Default: =5
        HasNotifications:
          PropertyKind: Input
          DisplayName: HasNotifications
          Description: Shows red notification dot when true
          DataType: Boolean
          Default: =true
        HoverText:
          PropertyKind: Input
          DisplayName: HoverText
          Description: A custom property for hover label text
          DataType: Text
          Default: ="Notifications"
        IconColor:
          PropertyKind: Input
          DisplayName: IconColor
          Description: Optional hex color (e.g., '#111827') to override the SVG stroke/fill in the default icon.
          DataType: Text
          Default: =""
        IconSvg:
          PropertyKind: Input
          DisplayName: IconSvg
          Description: Raw SVG markup to render (full <svg>...</svg>). Falls back to default bell if blank.
          DataType: Text
          Default: ="<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'><path d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/><path d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/></svg>"
        OnSelect:
          PropertyKind: Event
          DisplayName: OnSelect
          Description: Action to perform when bell is clicked
          ReturnType: None
          Default: =false
        Size:
          PropertyKind: Input
          DisplayName: Size
          Description: Size of the notification bell (width and height in pixels)
          DataType: Number
          Default: =45
        Theme:
          PropertyKind: Input
          DisplayName: Theme
          Description: Light or Dark theme for visual appearance
          DataType: Text
          Default: ="Light"
      Properties:
        Fill: |-
          =// Transparent background for root container
          Color.Transparent
        Height: |-
          =// Component height is controlled by Size property
          Badge.Size
        Width: |-
          =// Component width is controlled by Size property
          Badge.Size
      Children:
        - cntBellContainer:
            Control: GroupContainer@1.3.0
            Variant: ManualLayout
            Properties:
              BorderColor: |-
                =If(
                  Badge.Theme = "Dark",
                  RGBA(55, 65, 81, 1),
                  RGBA(229, 231, 235, 1)
                )
              DropShadow: |-
                =// No shadow effect
                DropShadow.None
              Height: |-
                =// Fill parent height
                Parent.Height
              RadiusBottomLeft: |-
                =// Rounded corners for modern appearance
                6
              RadiusBottomRight: =6
              RadiusTopLeft: =6
              RadiusTopRight: =6
              Width: |-
                =// Fill parent width
                Parent.Width
            Children:
              - imgBell:
                  Control: Image@2.2.3
                  Properties:
                    AccessibleLabel: |
                      =Badge.HoverText
                    BorderColor: |-
                      =// Dark blue border
                      RGBA(0, 18, 107, 1)
                    Height: |-
                      =// Fill container height
                      Parent.Height
                    Image: |-
                      =With(
                        {
                          // Choose between host-provided SVG and our themed fallback
                          _svg:
                            If(
                              !IsBlank(Badge.IconSvg),
                              // Custom SVG: replace 'currentColor' with IconColor if provided
                              If(
                                !IsBlank(Badge.IconColor),
                                Substitute(Badge.IconSvg, "currentColor", Badge.IconColor),
                                Badge.IconSvg
                              ),
                              // Fallback bell SVG (theme-aware)
                              "<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 24 24' fill='none' stroke='" &
                              // If IconColor provided, use it; else theme-based default
                              If(
                                !IsBlank(Badge.IconColor),
                                Badge.IconColor,
                                If(Badge.Theme = "" || Badge.Theme = "Light", "#000000", "#ffffff")
                              ) &
                              "' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'>" &
                              "<path d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/>" &
                              "<path d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/>" &
                              "</svg>"
                            )
                        },
                        Concatenate("data:image/svg+xml;utf8,", EncodeUrl(_svg))
                      )
                    PaddingBottom: |-
                      =// Padding around the bell icon (15% of container size)
                      Parent.Height * 0.15
                    PaddingLeft: =Parent.Width * 0.15
                    PaddingRight: =Parent.Width * 0.15
                    PaddingTop: =Parent.Height * 0.15
                    Width: |-
                      =// Fill container width
                      Parent.Width
              - cntPulseAnimation:
                  Control: GroupContainer@1.3.0
                  Variant: ManualLayout
                  Properties:
                    DropShadow: =DropShadow.None
                    Fill: |-
                      =// Animated fill with opacity that fades based on timer progress
                      If(
                          Badge.Theme = "Dark",
                          // Red color with animated opacity for dark theme
                          RGBA(
                              239,
                              68,
                              68,
                              Max(
                                  0,
                                  0.3 * (1 - tmrPulse.Value / tmrPulse.Duration)
                              )
                          ),
                          // Slightly different red for light theme
                          RGBA(
                              220,
                              38,
                              38,
                              Max(
                                  0,
                                  0.3 * (1 - tmrPulse.Value / tmrPulse.Duration)
                              )
                          )
                      )
                    Height: |-
                      =// Animated height that grows with timer progress
                      16 + 12 * With({p: tmrPulse.Value / tmrPulse.Duration}, Power(p, 0.6))
                    RadiusBottomLeft: |-
                      =// Circular shape with radius = half of height
                      Self.Height / 2
                    RadiusBottomRight: =Self.Height / 2
                    RadiusTopLeft: =Self.Height / 2
                    RadiusTopRight: =Self.Height / 2
                    Visible: |-
                      =// Only visible when there are notifications but no specific count
                      Badge.HasNotifications && Badge.BadgeCount = 0
                    Width: |-
                      =// Animated width that grows with timer progress
                      16 + 12 * With({p: tmrPulse.Value / tmrPulse.Duration}, Power(p, 0.6))
                    X: |-
                      =// Position in top-right corner
                      Parent.Width - Self.Width
                  Children:
                    - tmrPulse:
                        Control: Timer@2.1.0
                        Properties:
                          AutoPause: |-
                            =// Don't pause automatically
                            false
                          AutoStart: |-
                            =// Start automatically when conditions met
                            true
                          BorderColor: =ColorFade(Self.Fill, -15%)
                          Color: =RGBA(255, 255, 255, 1)
                          DisabledBorderColor: =ColorFade(Self.BorderColor, 70%)
                          DisabledColor: =ColorFade(Self.Fill, 90%)
                          DisabledFill: =ColorFade(Self.Fill, 70%)
                          Duration: |-
                            =// 1 second pulse cycle
                            1000
                          Fill: =RGBA(56, 96, 178, 1)
                          Font: =Font.'Open Sans'
                          Height: |-
                            =// Fixed timer size
                            16
                          HoverBorderColor: =ColorFade(Self.BorderColor, 20%)
                          HoverColor: =RGBA(255, 255, 255, 1)
                          HoverFill: =ColorFade(RGBA(56, 96, 178, 1), -20%)
                          PressedBorderColor: =Self.Fill
                          PressedColor: =Self.Fill
                          PressedFill: =Self.Color
                          Repeat: |-
                            =// Repeat the pulse animation
                            true
                          Start: |-
                            =// Start timer only when notifications exist but no count is shown
                            Badge.HasNotifications && Badge.BadgeCount = 0
                          Visible: |-
                            =// Timer is hidden, only animation effect is visible
                            false
                          Width: |-
                            =// Fixed timer size
                            16
              - cntNotificationBadge:
                  Control: GroupContainer@1.3.0
                  Variant: ManualLayout
                  Properties:
                    DropShadow: =DropShadow.None
                    Fill: |-
                      =// Red background for notification badge
                      RGBA(220, 38, 38, 1)
                    Height: |-
                      =// Dynamic height: larger if showing count, smaller for simple dot
                      If(Badge.BadgeCount > 0, Min(20, Parent.Height * 0.45), 12)
                    RadiusBottomLeft: |-
                      =// Circular shape with radius = half of height
                      Self.Height / 2
                    RadiusBottomRight: =Self.Height / 2
                    RadiusTopLeft: =Self.Height / 2
                    RadiusTopRight: =Self.Height / 2
                    Visible: |-
                      =// Visible when there are notifications or a count to display
                      Badge.HasNotifications || Badge.BadgeCount > 0
                    Width: |-
                      =// Dynamic width based on notification count
                      If(
                          Badge.BadgeCount > 0,
                          // When showing count, width adjusts based on number size
                          Max(
                              Self.Height,        // Minimum width = height (circular)
                              If(
                                  Badge.BadgeCount > 99,
                                  24,             // Width for "99+" display
                                  If(
                                      Badge.BadgeCount > 9,
                                      20,         // Width for two-digit numbers
                                      Self.Height // Width for single digits (circular)
                                  )
                              )
                          ),
                          12                      // Simple dot width when no count
                      )
                    X: |-
                      =// Position in top-right corner with small margin
                      Parent.Width - Self.Width - 2
                    Y: =2
                  Children:
                    - lblNotificationCount:
                        Control: Text@0.0.51
                        Properties:
                          Align: |-
                            =// Center-align text
                            'TextCanvas.Align'.Center
                          Font: =Font.'Segoe UI'
                          FontColor: |-
                            =// White text
                            RGBA(255, 255, 255, 1)
                          Height: |-
                            =// Fill badge height
                            Parent.Height
                          Size: |-
                            =// Dynamic font size
                            Max(7, Parent.Height * 0.5)
                          Text: |-
                            =// Display count with "99+" cap for large numbers
                            If(
                                Badge.BadgeCount > 0,
                                If(
                                    Badge.BadgeCount > 99,
                                    "99+",                              // Cap at 99+
                                    Text(Badge.BadgeCount) // Show actual count
                                ),
                                ""                                      // Empty when no count
                            )
                          VerticalAlign: |-
                            =// Vertical center
                            VerticalAlign.Middle
                          Visible: |-
                            =// Only visible when there's a count to show
                            Badge.BadgeCount > 0
                          Weight: |-
                            =// Bold font weight
                            'TextCanvas.Weight'.Bold
                          Width: |-
                            =// Fill badge width
                            Parent.Width
              - btnBell:
                  Control: Classic/Button@2.2.0
                  Properties:
                    BorderColor: |-
                      =// No border
                      Color.Transparent
                    BorderStyle: =BorderStyle.None
                    Color: =RGBA(255, 255, 255, 1)
                    DisabledBorderColor: =RGBA(166, 166, 166, 1)
                    Fill: |-
                      =// Transparent background
                      Color.Transparent
                    FocusedBorderColor: |-
                      =// Focus border color based on theme
                      If(Badge.Theme = "Dark", RGBA(255,255,255,0.3), RGBA(0,0,0,0.3))
                    Font: =Font.'Open Sans'
                    Height: |-
                      =// Cover entire bell area
                      Parent.Height
                    HoverBorderColor: =ColorFade(Self.BorderColor, 20%)
                    HoverColor: =RGBA(255, 255, 255, 1)
                    HoverFill: |-
                      =// Hover background color based on theme
                      If(Badge.Theme = "Dark", RGBA(255,255,255,0.1), RGBA(0,0,0,0.1))
                    OnSelect: |-
                      =// Execute the OnSelect event when button is clicked
                      Badge.OnSelect()
                    PressedBorderColor: =Self.Fill
                    PressedColor: =Self.Fill
                    PressedFill: =Color.Transparent
                    RadiusBottomLeft: |-
                      =// Rounded corners matching container
                      6
                    RadiusBottomRight: =6
                    RadiusTopLeft: =6
                    RadiusTopRight: =6
                    Text: |-
                      =// No button text (invisible overlay)
                      ""
                    Tooltip: |-
                      =// Use bell's accessibility label
                      imgBell.AccessibleLabel
                    Width: |-
                      =// Cover entire bell area
                      Parent.Width
  

# ============================================
# USAGE IN YOUR APP
# ============================================
# After importing this component, you can override
# properties dynamically in your app:
#
# Badge.BadgeCount: CountRows(Filter(Notifications, Read = false))
# Badge.HasNotifications: CountRows(Notifications) > 0  
# Badge.OnSelect: Navigate(NotificationsScreen)
# Badge.HoverText: CountRows(Notifications) & " unread"
#
# The component will use your customized defaults above
# unless you override them with these formulas.
# ============================================

How to Use This Component

  1. 1
    Copy the complete YAML above
    This includes the entire component definition with your custom defaults
  2. 2
    Import into Power Apps Studio
    Go to Components → New component → Import from code
  3. 3
    Paste and import
    The Badge component will appear in your component library
  4. 4
    Use in your app
    Add Badge to screens and optionally override with dynamic formulas

💡 Tip: You can still make the badge dynamic by overriding properties like Badge.BadgeCount: CountRows(Notifications)