Skip to content

Commit a9aa59b

Browse files
feat(badge): add hue property for the ionic theme (#30307)
Issue number: internal --------- ## What is the current behavior? The badge component does not support the `hue` property. ## What is the new behavior? Adds support for the `subtle` hue for the badge. Defaults to `subtle` when the badge contains icon or text. Defaults to `bold` when the badge is empty or when it is inside of a button or tab button. ## Does this introduce a breaking change? - [ ] Yes - [x] No
1 parent 207d485 commit a9aa59b

File tree

116 files changed

+265
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+265
-11
lines changed

core/api.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ ion-backdrop,event,ionBackdropTap,void,true
314314

315315
ion-badge,shadow
316316
ion-badge,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
317+
ion-badge,prop,hue,"bold" | "subtle" | undefined,undefined,false,false
317318
ion-badge,prop,mode,"ios" | "md",undefined,false,false
318319
ion-badge,prop,shape,"round | rectangular" | "soft" | undefined,undefined,false,false
319320
ion-badge,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | "xxsmall" | undefined,undefined,false,false

core/src/components.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ export namespace Components {
429429
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
430430
*/
431431
"color"?: Color;
432+
/**
433+
* Set to `"bold"` for a badge with vibrant, bold colors or to `"subtle"` for a badge with muted, subtle colors. Only applies to the `ionic` theme.
434+
*/
435+
"hue"?: 'bold' | 'subtle';
432436
/**
433437
* The mode determines the platform behaviors of the component.
434438
*/
@@ -5870,6 +5874,10 @@ declare namespace LocalJSX {
58705874
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
58715875
*/
58725876
"color"?: Color;
5877+
/**
5878+
* Set to `"bold"` for a badge with vibrant, bold colors or to `"subtle"` for a badge with muted, subtle colors. Only applies to the `ionic` theme.
5879+
*/
5880+
"hue"?: 'bold' | 'subtle';
58735881
/**
58745882
* The mode determines the platform behaviors of the component.
58755883
*/

core/src/components/badge/badge.common.scss

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@
4343
vertical-align: baseline;
4444
}
4545

46-
:host(.ion-color) {
47-
background: #{color.current-color(base)};
48-
color: #{color.current-color(contrast)};
49-
}
50-
5146
// Badge (hint)
5247
// --------------------------------------------------
5348

core/src/components/badge/badge.ionic.scss

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
// --------------------------------------------------
66

77
:host {
8-
--background: #{globals.ion-color(primary, base)};
9-
--color: #{globals.ion-color(primary, contrast)};
108
--padding-start: #{globals.$ion-space-200};
119
--padding-end: #{globals.$ion-space-200};
1210
--padding-top: #{globals.$ion-space-0};
@@ -20,6 +18,32 @@
2018
font-weight: globals.$ion-font-weight-medium;
2119
}
2220

21+
// Bold Badge
22+
// --------------------------------------------------
23+
24+
:host(.badge-bold) {
25+
--background: #{globals.ion-color(primary, base)};
26+
--color: #{globals.ion-color(primary, contrast)};
27+
}
28+
29+
:host(.badge-bold.ion-color) {
30+
background: globals.current-color(base);
31+
color: globals.current-color(contrast);
32+
}
33+
34+
// Subtle Badge
35+
// --------------------------------------------------
36+
37+
:host(.badge-subtle) {
38+
--background: #{globals.ion-color(primary, base, $subtle: true)};
39+
--color: #{globals.ion-color(primary, contrast, $subtle: true)};
40+
}
41+
42+
:host(.badge-subtle.ion-color) {
43+
background: globals.current-color(base, $subtle: true);
44+
color: globals.current-color(contrast, $subtle: true);
45+
}
46+
2347
// Badge Shapes
2448
// --------------------------------------------------
2549

core/src/components/badge/badge.native.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
font-family: $font-family-base;
1313
}
1414

15+
:host(.ion-color) {
16+
background: current-color(base);
17+
color: current-color(contrast);
18+
}
19+
1520
// TODO(ROU-10747): Review size styles when sizes are defined for native themes.
1621
:host([vertical]:not(.in-button):not(.in-tab-button)),
1722
:host(:empty) {

core/src/components/badge/badge.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ export class Badge implements ComponentInterface {
2828
*/
2929
@Prop({ reflect: true }) color?: Color;
3030

31+
/**
32+
* Set to `"bold"` for a badge with vibrant, bold colors or to `"subtle"` for
33+
* a badge with muted, subtle colors.
34+
*
35+
* Only applies to the `ionic` theme.
36+
*/
37+
@Prop() hue?: 'bold' | 'subtle';
38+
3139
/**
3240
* Set to `"rectangular"` for non-rounded corners.
3341
* Set to `"soft"` for slightly rounded corners.
@@ -87,7 +95,33 @@ export class Badge implements ComponentInterface {
8795
return size;
8896
}
8997

98+
// The 'subtle' hue is the default for badges containing text or icons
99+
// The 'bold' hue is used when inside of an avatar, button, tab button,
100+
// or when the badge is empty (no text or icon).
101+
private getHue(): string | undefined {
102+
const { hue } = this;
103+
104+
if (hue !== undefined) {
105+
return hue;
106+
}
107+
108+
const inAvatar = hostContext('ion-avatar', this.el);
109+
const inButton = hostContext('ion-button', this.el);
110+
const inTabButton = hostContext('ion-tab-button', this.el);
111+
const hasContent = this.el.textContent?.trim() !== '' || this.el.querySelector('ion-icon') !== null;
112+
113+
// Return 'bold' if the badge is inside an avatar, button, tab button,
114+
// or has no content
115+
if (inAvatar || inButton || inTabButton || !hasContent) {
116+
return 'bold';
117+
}
118+
119+
// Return 'subtle' if the badge contains visible text or an icon
120+
return 'subtle';
121+
}
122+
90123
render() {
124+
const hue = this.getHue();
91125
const shape = this.getShape();
92126
const size = this.getSize();
93127
const theme = getIonTheme(this);
@@ -96,6 +130,7 @@ export class Badge implements ComponentInterface {
96130
<Host
97131
class={createColorClasses(this.color, {
98132
[theme]: true,
133+
[`badge-${hue}`]: hue !== undefined,
99134
[`badge-${shape}`]: shape !== undefined,
100135
[`badge-${size}`]: size !== undefined,
101136
[`badge-vertical-${this.vertical}`]: this.vertical !== undefined,
-5.06 KB
-3.98 KB
-4.74 KB
-5.06 KB

0 commit comments

Comments
 (0)