Skip to content

Implement badge component#463

Merged
SKProCH merged 17 commits intoAvaloniaCommunity:masterfrom
Hyz-sui:feature-badge-control
Mar 21, 2026
Merged

Implement badge component#463
SKProCH merged 17 commits intoAvaloniaCommunity:masterfrom
Hyz-sui:feature-badge-control

Conversation

@Hyz-sui
Copy link
Copy Markdown
Contributor

@Hyz-sui Hyz-sui commented May 28, 2025

Created Badge and Badged controls. Closes #347.

Badge in m2 has not been completed, so I strongly referred to badge in m3.

I also created demo page for badges ( 2f95c4f ).

Screenshot

image

Badge

The Badge control is a simple badge. Users can place a single inline badge with this. It can be implemented using Badged with BadgePlacement.Right, but more intuitive.

Small badge (just a dot) is also implemented with HasContent property.

Badged

The Badged control is a content wrapper that makes it easy to attach a badge to the content.

You can customize the badge through BadgeContent, BadgeBackground, BadgeForeground, BadgeCornerRadius, BadgeHasContent, BadgeWidth, BadgeHeight, and BadgeFontSize properties.

The badge can be hidden with IsBadgeVisible.

You can choose the placement of the badge with BadgePlacement.
It should be TopLeft (default), Right (inline badge / place on the ending edge), or TopLeft (RTL) according to m3 guidelines, but is not limited technically in this control.

Other Changes

  • A new brush MaterialValidationErrorForegroundBrush has been added.
  • ITheme.ValidationError has been changed from Color to ColorPair type. I am not sure that this is breaking change or not.

Hyz-sui added 3 commits May 27, 2025 09:59
Used for badge control. ITheme.ValidationError prop is now ColorPair.
Create badge and badged controls. Badge is a simple badge. Badged makes it easy to attach a badge to button, icon, or other controls.
@SKProCH SKProCH added the enhancement New feature or request label May 28, 2025
@SKProCH SKProCH self-requested a review May 28, 2025 15:55
Copy link
Copy Markdown
Collaborator

@SKProCH SKProCH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While i appreciate the work (and i like the results!) i have some thoughts:
Probably we shouldn't make 2 separate controls, since Badged can be used as Badge is there is no Content specified? What do you think?

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented May 28, 2025

And currently large sized badges go beyond not equally:

image

While in MDiX it do it equally (half width "in control" half out, half height "in control" half out):

image

I don't know which variant is the best and should this be fixed, but leaving it here just in case you missed that.

P.S. Probably this is should be just another option in placement enum?

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented May 28, 2025

The bed under my body is just about to take me to sleep right now, so I will work on the change requests at another day.

As for small badge, just my feeling, I have concerns with the implementation where the shape of a control is implicitly and heavily modified by a property that does not directly mention it.

As for "beyond", I believe the m3 guideline shows a layout that goes beyond on the outside.
It is not half-width, but almost like is left-aligned on the top right.
I guess this is partially because m3 does not put a badge on a button (m3 buttons are round so it would look terribly clunky ).
But for example, imagine putting badges on buttons in a StackPanel.
It would be odd that the badges would dynamically go beyond the right side, and push and pull the contents on the right side.
I mentioned buttons as a simple example, but I think m3 badges are basically expected to be attached to a child element of a container with a fixed width.

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented May 30, 2025

implementation where the shape of a control is implicitly and heavily modified by a property that does not directly mention it.

Probably yes, but I don't see usecases, where the user will specify BadgeContent and don't want to show it (and display the small dot instead).

@appleneko2001
Copy link
Copy Markdown
Contributor

Probably yes, but I don't see usecases, where the user will specify BadgeContent and don't want to show it (and display the small dot instead).

wait do I miss something? wheres the "BadgeContent" came from? It's a thing from official AvaloniaUI?

@appleneko2001
Copy link
Copy Markdown
Contributor

honestly, idk how bout creating a lot content somehow, unless its necessary, but I have a different approach about Badged
we can just simply add new ContentControl theme with "BadgedContentControl" key or some sort of thing, then use BadgeAssist to modify their contents,
or just use boolean BadgeAssist.UseBadge, if it have some changes, it should notify the listener to create or delete UI element

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented May 31, 2025

wait do I miss something? wheres the "BadgeContent" came from? It's a thing from official AvaloniaUI?

No, this is a new property from Badged class in this PR

honestly, idk how bout creating a lot content somehow, unless its necessary, but I have a different approach about Badged
we can just simply add new ContentControl theme with "BadgedContentControl" key or some sort of thing, then use BadgeAssist to modify their contents,
or just use boolean BadgeAssist.UseBadge, if it have some changes, it should notify the listener to create or delete UI element

I am against this. Adding something via AttachedProperty is only necessary in cases where we need to add something to an existing control that we cannot change (or in other rare cases, like when we need to hide some internal information or something like that).

In cases where we are doing something new, it is reasonable to create a new control to make it easier for third-party users to use, there is nothing wrong with that.

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented May 31, 2025

implementation where the shape of a control is implicitly and heavily modified by a property that does not directly mention it.

Probably yes, but I don't see usecases, where the user will specify BadgeContent and don't want to show it (and display the small dot instead).

Here is my intended use case:
An application has "Slim Layout" boolean option. With slim layout, the amount of content on the screen is reduced.
As part of that, the badge that indicates new notifications would be small.

In this case, BadgeContent is bound to the number of new items; HasContent is bound to the negation of the slim layout option. It is pretty simple.

honestly, idk how bout creating a lot content somehow, unless its necessary, but I have a different approach about Badged we can just simply add new ContentControl theme with "BadgedContentControl" key or some sort of thing, then use BadgeAssist to modify their contents, or just use boolean BadgeAssist.UseBadge, if it have some changes, it should notify the listener to create or delete UI element

I am not sure if you are suggesting to make all of Badge or only Badged an assist, so I respond with both patterns.

The Badge is a meaningful UI component and is not just a decoration.
It is defined as a Badge component in m3, so it is not unnatural to add Badge as a new control.
In addition, if we make Badge an assist, it would make inline badge or some use cases difficult.
Here is an instance of Google AI Studio where a component similar to an inline badge is used.

Screenshot_20250531-200257

It might be possible to recreate Badged as an assist, but the assist class would have too many properties.
If we take the same approach for other components attached to the main content, ContentControl will be a "God Control" and it will be difficult to coexist with other attached components.

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented May 31, 2025

An application has "Slim Layout" boolean option. With slim layout, the amount of content on the screen is reduced.
As part of that, the badge that indicates new notifications would be small.

In this case, BadgeContent is bound to the number of new items; HasContent is bound to the negation of the slim layout option. It is pretty simple.

This makes sense. But probably defining a new theme for control and just swapping it globally (in parent/app resources) wasn't the better way then binding every control to some global property?

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented May 31, 2025

An application has "Slim Layout" boolean option. With slim layout, the amount of content on the screen is reduced.
As part of that, the badge that indicates new notifications would be small.

In this case, BadgeContent is bound to the number of new items; HasContent is bound to the negation of the slim layout option. It is pretty simple.

This makes sense. But probably defining a new theme for control and just swapping it globally (in parent/app resources) wasn't the better way then binding every control to some global property?

If the application has 100 badges and all of them are large badges, then yes.
However, in most cases, they would not use a huge number of badges, and some of those badges could always be small.
In that case, many of them will choose to switch boolean properties of the 3 badges directly, rather than implementing dynamic switching of resources depending on the settings.
Even if they choose to swap resources, the HasContent property makes it easier to define the styles.
In other words, the HasContent property allows users to choose which way to do it.

Screenshot_20250531-233615

This is the official Bluesky app for Android (I usually use another client so I have tons of notifications lol) . The badge on notifications is large, but the badge on "Scroll to Top" (🔼) is small. In this case, only the badge on notifications can be slimmed down.

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented May 31, 2025

Maybe yes, but I still think it should be determined by the data. However, I respect your opinion as an author, so let's leave it as you see it.

P.S. Maybe make it a bool? property? And so that by default it would be controlled by content, but if user explicitly set - use that value.

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented Jun 1, 2025

Maybe yes, but I still think it should be determined by the data. However, I respect your opinion as an author, so let's leave it as you see it.

P.S. Maybe make it a bool? property? And so that by default it would be controlled by content, but if user explicitly set - use that value.

Yes, I was considering making HasContent an enum and allowing users to choose between True, False, and Auto.
But I think bool? would be better too.

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented Oct 1, 2025

Hello, I'm so sorry for leaving this for so long.

I have been focusing on some other areas lately, so I will not be able to work on this PR for a while at least.
I'm sorry again that I cannot complete its implementation.

Of course, feel free to use any code or ideas from this PR, or the PR itself. Thank you!

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented Oct 20, 2025

@Hyz-sui can you check "Allow edit for maintainers"? I can't push to your branch currently.

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented Oct 21, 2025

@Hyz-sui can you check "Allow edit for maintainers"? I can't push to your branch currently.

Done @SKProCH

@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented Mar 21, 2026

I've fixed all the changes requested, but there is still plenty things to implement, like:

  • Allow badges go beyond equally in width
  • Split background and borders, allowing ai studio like badges

But currently keeping things simple, as i don't have so much time to this. PR are appreciated if anybody wants to do this

@SKProCH SKProCH merged commit d2e1611 into AvaloniaCommunity:master Mar 21, 2026
@SKProCH
Copy link
Copy Markdown
Collaborator

SKProCH commented Mar 21, 2026

Also, thanks, @Hyz-sui, its awesome work!

@Hyz-sui
Copy link
Copy Markdown
Contributor Author

Hyz-sui commented Mar 22, 2026

Awesome, thank you for completing the PR! @SKProCH
Also, big thanks to @appleneko2001 for providing feedback ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement a badge control

3 participants