feat(badge): add recipe and tokens#31043
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| :host ::slotted(ion-badge[vertical]:not(:empty)) { | ||
| @include globals.padding(2px); | ||
| } |
There was a problem hiding this comment.
Removed this completely because based on MD3, the padding should always be consistent regardless of the host component.
| private getHue(): string | undefined { | ||
| const { hue } = this; | ||
|
|
||
| if (hue !== undefined) { | ||
| return hue; | ||
| } | ||
|
|
||
| const inAvatar = hostContext('ion-avatar', this.el); | ||
| const inButton = hostContext('ion-button', this.el); | ||
| const inTabButton = hostContext('ion-tab-button', this.el); | ||
| const hasContent = this.el.textContent?.trim() !== '' || this.el.querySelector('ion-icon') !== null; | ||
|
|
||
| // Return 'bold' if the badge is inside an avatar, button, tab button, | ||
| // or has no content | ||
| if (inAvatar || inButton || inTabButton || !hasContent) { | ||
| return 'bold'; | ||
| } | ||
| /** | ||
| * Gets the badge hue. Uses the `hue` property if set, otherwise | ||
| * checks the theme config and falls back to 'subtle' if neither is provided. | ||
| */ | ||
| get hueValue(): string { | ||
| const hueConfig = config.getObjectValue('IonBadge.hue', 'bold') as string; | ||
| const hue = this.hue || hueConfig; | ||
|
|
||
| // Return 'subtle' if the badge contains visible text or an icon | ||
| return 'subtle'; |
There was a problem hiding this comment.
I opted out from implementing this complex version of hue getter. It was originally meant for the ionic theme and this might not be the desired outcome for every developer. Instead, OS will should create a wrapper to determine the hue since we want Ionic Modular to be as flexible as possible.
There was a problem hiding this comment.
There are several edge cases that are specific to OS. In order to lessen the complexity of badge, the following "breaking changes" were done:
- Border radius is not automatically changed if the badge is small and soft (
:host(.badge-small.badge-soft)). Border radius should not be tied to sizes as it can be confusing of when a dev needs to know the criteria to update their tokens. Since OS wants the border radius to be even smaller thansoftthen I created a new shape,crispfor OS to use:
<ion-button fill="clear">
<ion-icon slot="icon-only" name="add"></ion-icon>
<ion-badge shape="crisp" vertical="top"></ion-badge>
</ion-button>-
The styles for
:host([vertical]:not(:empty))were not implemented because they are the same exact styles as size medium. OS can simply update their badges to havesize="medium" -
The styles for
:host(:not(:empty).in-button)were not implemented to reduce the complexity of combinations as mentioned in number 1. OS can adjust their code by adding a small badge within the button as the styles for small as the same exact ones.
<ion-button fill="clear">
<ion-icon slot="icon-only" name="add"></ion-icon>
<ion-badge size="small" vertical="top"></ion-badge>
</ion-button>
core/src/components/badge/badge.tsx
Outdated
| * Defaults to `"soft"` if both the shape property and theme config are unset. | ||
| */ | ||
| @Prop() shape?: 'soft' | 'round | rectangular'; | ||
| @Prop() shape?: 'crisp' | 'soft' | 'round' | 'rectangular'; |
There was a problem hiding this comment.
Border radius is not automatically changed if the badge is small and soft (:host(.badge-small.badge-soft)). Border radius should not be tied to sizes as it can be confusing of when a dev needs to know the criteria to update their tokens. Since OS wants the border radius to be even smaller than soft then I created a new shape, crisp for OS to use:
<ion-button fill="clear">
<ion-icon slot="icon-only" name="add"></ion-icon>
<ion-badge shape="crisp" vertical="top"></ion-badge>
</ion-button>There was a problem hiding this comment.
I renamed the folder from hint to vertical.
| <ion-content> | ||
| <div id="avatar"> | ||
| <h2> | ||
| Inside Avatar (Navigate to the <a href="../../avatar/test/badge/index.html">Avatar Badges page</a> to see |
There was a problem hiding this comment.
Since we need to test each badge size, badge position, and badge content on each avatar size, I added the link to view all those possibilities so we don't have a large page. This section is only a small snippet for quick testing purposes.
| <div id="tab-button"> | ||
| <h2> | ||
| Inside Tab Button (Navigate to the | ||
| <a href="../../tab-button/test/badge/index.html">Tab Button Badges page</a> to see all badge variations.) |
There was a problem hiding this comment.
Since we need to test each badge size, badge position, and badge content on each icon layout, icon presence, label presence, I added the link to view all those possibilities so we don't have a large page. This section is only a small snippet for quick testing purposes.
|
|
||
| <div id="button-top"> | ||
| <h2> | ||
| Inside Button (Navigate to the <a href="../../button/test/badge/index.html">Button Badges page</a> to see |
There was a problem hiding this comment.
Since we need to test each badge size, badge position, and badge content on each button size, icon only or text, I added the link to view all those possibilities so we don't have a large page. This section is only a small snippet for quick testing purposes.
|
|
||
| // Anchored Badge | ||
| :host(.button-has-badge) .button-native { | ||
| --overflow: visible; |
There was a problem hiding this comment.
I didn't migrate this as the structure might change once button is fully migrated. This will be done when button is worked on.
| [`badge-vertical-${this.vertical}`]: this.vertical !== undefined, | ||
| 'in-button': hostContext('ion-button', this.el), | ||
| 'in-tab-button': hostContext('ion-tab-button', this.el), | ||
| 'long-badge': (this.el.textContent?.trim().length ?? 0) > 2, |
There was a problem hiding this comment.
This class was only used to position.
| 'in-button': hostContext('ion-button', this.el), | ||
| 'in-tab-button': hostContext('ion-tab-button', this.el), |
There was a problem hiding this comment.
These aren't needed anymore since position is being generated with the positionBadge utility.
| } | ||
|
|
||
| if (this.hasBadge) { | ||
| this.setupBadgeObserver(); |
There was a problem hiding this comment.
Should we also be adding an observer for the icon only slot? In case the icon changes, we might want to recalculate but that might be overkill?
| height: 'var(--ion-scaling-xxxs)', | ||
|
|
||
| min: { | ||
| width: 'var(--ion-scaling-xxxs)', | ||
| }, |
There was a problem hiding this comment.
Based on MD3, it has two sizes: small and large. The small is meant for the empty badge and the large if for the content badge. Their large is 16x16 pixels with a font size of 11px. I implemented the same values for our large size for md to be consistent. This means that the values for small and medium are scaled down. Please make sure to review the sizes carefully, as they might be too small. Maybe MD3 large should really be small for ours. Thoughts?
Issue number: resolves #
What is the current behavior?
What is the new behavior?
Does this introduce a breaking change?
Other information