Skip to content

feat(badge): add recipe and tokens#31043

Open
thetaPC wants to merge 88 commits intoionic-modularfrom
FW-6837
Open

feat(badge): add recipe and tokens#31043
thetaPC wants to merge 88 commits intoionic-modularfrom
FW-6837

Conversation

@thetaPC
Copy link
Copy Markdown
Contributor

@thetaPC thetaPC commented Mar 27, 2026

Issue number: internal


What is the current behavior?

Component styles for ion-badge are fragmented across multiple files (ios, md). Developers were restricted to those themes and how those themes structured the logic and styles.

What is the new behavior?

  • Unified Style Architecture: Combined theme-specific styling into a single badge.scss file that consumes CSS variables, ensuring a single source of truth for component logic.
  • Defined TypeScript Interface: Added badge.interfaces.ts
  • Updated Test Page: Updated the badge test page to be simple since new test pages with more in depth use cases were created
  • Added Test Pages: Badge has multiple use cases based on which component it's slotted into. Test pages were added due to that.

Does this introduce a breaking change?

  • Yes
  • No

This PR introduces a breaking change to how IonBadge is styled. Existing manual CSS overrides targeting internal badge structures or old token names will no longer work due to the shift to thew new token hierarchy and a unified base SCSS file.

Migration Path:

  1. Token Updates: Update any custom theme configurations to match the new nested structure.

  2. CSS Overrides: Ensure selectors align with the new slotted element logic and variable names (e.g., --ion-badge-hue-bold-default-background).

--background should no longer be used. Setting the value, Badge.hue.bold.background, within the tokens file should be used to change the background for the bold hue. Setting the value, Badge.hue.subtle.background, within the tokens file should be used to change the background for the subtle hue.

  1. Theme classes: Remove any instances that target the theme classes: badge.md

Other information

This PR significantly improves the developer experience for theming. By moving logic into default.tokens.ts and away from hardcoded SCSS functions, designers and developers can now override styles (like the size on a slotted avatar) purely through token configuration.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ionic-framework Ready Ready Preview, Comment Apr 29, 2026 11:10pm

Request Review

Comment on lines -59 to -61
:host ::slotted(ion-badge[vertical]:not(:empty)) {
@include globals.padding(2px);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed this completely because based on MD3, the padding should always be consistent regardless of the host component.


/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Forgot to remove this in the first iteration of review.

Copy link
Copy Markdown
Member

@brandyscarney brandyscarney left a comment

Choose a reason for hiding this comment

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

Most of my feedback is related to styles and tests. 👍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can this be fixed so that the badge isn't cut off at the end of row 3?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can this be fixed so that the badge isn't cut off at the end of row 3?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I was thinking that the grid for this would always display the same number of avatars before wrapping. This looks different than the Safari screenshot for this same test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are the medium and large badges the same size except for the hints?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Medium and large buttons have the same exact styling for ionic. While I was grabbing the link, I decided to check the designs in case something changed since then. That's when I noticed that large is not provided for content badges. That would explain why it was styled to match medium. So I decided to make my best judgement on what large would look like and added the styles. 9a199bd

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't the badge always be a circle at minimum (when it contains only a 1)?

Image

Copy link
Copy Markdown
Contributor Author

@thetaPC thetaPC Apr 29, 2026

Choose a reason for hiding this comment

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

I was trying to keep it as close to the original styling in main but that lead to the inconsistent styles that you see now. I've updated it based on the MD3 specs since they seem similar to MD2. f3b59c2

I left the icon sizes alone so they're still using the sizes from main. Let me now if you prefer them to also be completely round. The reason that I left them alone is because native MD does not support icon badges.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds good. Can we add this to the button ticket?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should either split the test into two screenshots based on badge position (top vs bottom) or add some kind of heading / separation to the test like this:

Top:

Image

Bottom:

Image

Prefer 4 columns over 5 though for easier scanning.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

0c5648c

I also switched to 3 columns to match button.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here is how it looks in a native Swift app in iOS 18:

iOS18

and iOS 26:

iOS26

It does look like the small size matches better but the font weight is off for both and the padding is off when it contains 999+:

Image

I think the lack of padding on 999+ (in this image 123) is what makes it look off.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It does look better but there is still wrapping like in core/src/components/button/test/badge/badge.e2e.ts-snapshots/button-large-badge-md-ltr-Mobile-Firefox-linux.png. You may want to adjust the size of the view so it uses a larger width to capture them all on one line.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think we need a lot of these, in particular:

The icon-only examples - we should just have 1 example for this (combine top, bottom, start, end, label-hide and do not include icon-hide)
The label-only examples - we should just have 1 example for this (combine top, bottom, start, end, icon-hide and do not include label-hide)

Unless you think the positioning really needs the visual tests here, these all render the same and we don’t really support showing just a badge so we don’t need to verify it. This feedback applies to both badge positions.

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

Labels

package: angular @ionic/angular package package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants