diff --git a/core/api.txt b/core/api.txt
index a8217994eef..e2757eb77ea 100644
--- a/core/api.txt
+++ b/core/api.txt
@@ -316,28 +316,84 @@ ion-badge,shadow
ion-badge,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record | undefined,undefined,false,true
ion-badge,prop,hue,"bold" | "subtle" | undefined,undefined,false,false
ion-badge,prop,mode,"ios" | "md",undefined,false,false
-ion-badge,prop,shape,"round | rectangular" | "soft" | undefined,undefined,false,false
+ion-badge,prop,shape,"crisp" | "rectangular" | "round" | "soft" | undefined,undefined,false,false
ion-badge,prop,size,"large" | "medium" | "small" | undefined,undefined,false,false
ion-badge,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-badge,prop,vertical,"bottom" | "top" | undefined,undefined,false,false
-ion-badge,css-prop,--background,ionic
-ion-badge,css-prop,--background,ios
-ion-badge,css-prop,--background,md
-ion-badge,css-prop,--color,ionic
-ion-badge,css-prop,--color,ios
-ion-badge,css-prop,--color,md
-ion-badge,css-prop,--padding-bottom,ionic
-ion-badge,css-prop,--padding-bottom,ios
-ion-badge,css-prop,--padding-bottom,md
-ion-badge,css-prop,--padding-end,ionic
-ion-badge,css-prop,--padding-end,ios
-ion-badge,css-prop,--padding-end,md
-ion-badge,css-prop,--padding-start,ionic
-ion-badge,css-prop,--padding-start,ios
-ion-badge,css-prop,--padding-start,md
-ion-badge,css-prop,--padding-top,ionic
-ion-badge,css-prop,--padding-top,ios
-ion-badge,css-prop,--padding-top,md
+ion-badge,css-prop,--ion-badge-font-family - the font family of the badge text Bold
+ion-badge,css-prop,--ion-badge-hue-bold-default-background - Background color of the `bold` hue in default state
+ion-badge,css-prop,--ion-badge-hue-bold-default-border-radius - Border radius of the `bold` hue in default state
+ion-badge,css-prop,--ion-badge-hue-bold-default-color - Text color of the `bold` hue in default state
+ion-badge,css-prop,--ion-badge-hue-bold-semantic-default-background - Background color of the `bold` hue when a semantic color is applied
+ion-badge,css-prop,--ion-badge-hue-bold-semantic-default-border-radius - Border radius of the `bold` hue when a semantic color is applied Subtle
+ion-badge,css-prop,--ion-badge-hue-bold-semantic-default-color - Text color of the `bold` hue when a semantic color is applied
+ion-badge,css-prop,--ion-badge-hue-subtle-default-background - Background color of the `subtle` hue in default state
+ion-badge,css-prop,--ion-badge-hue-subtle-default-border-radius - Border radius of the `subtle` hue in default state
+ion-badge,css-prop,--ion-badge-hue-subtle-default-color - Text color of the `subtle` hue in default state
+ion-badge,css-prop,--ion-badge-hue-subtle-semantic-default-background - Background color of the `subtle` hue when a semantic color is applied
+ion-badge,css-prop,--ion-badge-hue-subtle-semantic-default-border-radius - Border radius of the `subtle` hue when a semantic color is applied Shapes
+ion-badge,css-prop,--ion-badge-hue-subtle-semantic-default-color - Text color of the `subtle` hue when a semantic color is applied
+ion-badge,css-prop,--ion-badge-shape-crisp-border-radius - Border radius of the `crisp` shape
+ion-badge,css-prop,--ion-badge-shape-rectangular-border-radius - Border radius of the `rectangular` shape Sizes
+ion-badge,css-prop,--ion-badge-shape-round-border-radius - Border radius of the `round` shape
+ion-badge,css-prop,--ion-badge-shape-soft-border-radius - Border radius of the `soft` shape
+ion-badge,css-prop,--ion-badge-size-large-content-font-size - Font size of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-font-weight - Font weight of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-height - Height of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-icon-height - Height of the slotted `ion-icon` of the `large` size Sizes
+ion-badge,css-prop,--ion-badge-size-large-content-icon-width - Width of the slotted `ion-icon` of the `large` size
+ion-badge,css-prop,--ion-badge-size-large-content-letter-spacing - Letter spacing of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-line-height - Line height of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-min-height - Minimum height of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-min-width - Minimum width of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-padding-bottom - Bottom padding of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-content-padding-top - Top padding of the `large` size when badge has content
+ion-badge,css-prop,--ion-badge-size-large-dot-height - Height of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-large-dot-min-width - Minimum width of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-large-dot-padding-bottom - Bottom padding of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-large-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-large-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-large-dot-padding-top - Top padding of the `large` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-content-font-size - Font size of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-font-weight - Font weight of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-height - Height of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-icon-height - Height of the slotted `ion-icon` of the `medium` size
+ion-badge,css-prop,--ion-badge-size-medium-content-icon-width - Width of the slotted `ion-icon` of the `medium` size
+ion-badge,css-prop,--ion-badge-size-medium-content-letter-spacing - Letter spacing of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-line-height - Line height of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-min-height - Minimum height of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-min-width - Minimum width of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-padding-bottom - Bottom padding of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-content-padding-top - Top padding of the `medium` size when badge has content
+ion-badge,css-prop,--ion-badge-size-medium-dot-height - Height of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-dot-min-width - Minimum width of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-dot-padding-bottom - Bottom padding of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-medium-dot-padding-top - Top padding of the `medium` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-content-font-size - Font size of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-font-weight - Font weight of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-height - Height of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-icon-height - Height of the slotted `ion-icon` of the `small` size
+ion-badge,css-prop,--ion-badge-size-small-content-icon-width - Width of the slotted `ion-icon` of the `small` size
+ion-badge,css-prop,--ion-badge-size-small-content-letter-spacing - Letter spacing of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-line-height - Line height of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-min-height - Minimum height of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-min-width - Minimum width of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-padding-bottom - Bottom padding of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-content-padding-top - Top padding of the `small` size when badge has content
+ion-badge,css-prop,--ion-badge-size-small-dot-height - Height of the `small` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-dot-min-width - Minimum width of the `small` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-dot-padding-bottom - Bottom padding of the `small` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `small` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `small` size when badge is empty
+ion-badge,css-prop,--ion-badge-size-small-dot-padding-top - Top padding of the `small` size when badge is empty
ion-breadcrumb,shadow
ion-breadcrumb,prop,active,boolean,false,false,false
diff --git a/core/src/components.d.ts b/core/src/components.d.ts
index 5d1eff6638c..76403218be6 100644
--- a/core/src/components.d.ts
+++ b/core/src/components.d.ts
@@ -11,6 +11,7 @@ import { ActionSheetButton } from "./components/action-sheet/action-sheet-interf
import { OverlayEventDetail } from "./utils/overlays-interface";
import { IonicSafeString } from "./utils/sanitization";
import { AlertButton, AlertInput } from "./components/alert/alert-interface";
+import { IonBadgeHue, IonBadgeShape, IonBadgeSize, IonBadgeVerticalPosition } from "./components/badge/badge.interfaces";
import { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./components/router/utils/interface";
import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
@@ -51,6 +52,7 @@ export { ActionSheetButton } from "./components/action-sheet/action-sheet-interf
export { OverlayEventDetail } from "./utils/overlays-interface";
export { IonicSafeString } from "./utils/sanitization";
export { AlertButton, AlertInput } from "./components/alert/alert-interface";
+export { IonBadgeHue, IonBadgeShape, IonBadgeSize, IonBadgeVerticalPosition } from "./components/badge/badge.interfaces";
export { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./components/router/utils/interface";
export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
@@ -469,21 +471,21 @@ export namespace Components {
*/
"color"?: Color;
/**
- * 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.
+ * Set to `"bold"` for a badge with vibrant, bold colors or to `"subtle"` for a badge with muted, subtle colors. Defaults to `"bold"` if both the hue property and theme config are unset.
*/
- "hue"?: 'bold' | 'subtle';
+ "hue"?: IonBadgeHue;
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
- * Set to `"rectangular"` for non-rounded corners. Set to `"soft"` for slightly rounded corners. Set to `"round"` for fully rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
+ * Set to `"crisp"` for a badge with even slightly rounded corners, `"soft"` for a badge with slightly rounded corners, `"round"` for a badge with fully rounded corners, or `"rectangular"` for a badge without rounded corners. Defaults to `"soft"` if both the shape property and theme config are unset.
*/
- "shape"?: 'soft' | 'round | rectangular';
+ "shape"?: IonBadgeShape;
/**
- * Set to `"small"` for a small badge. Set to `"medium"` for a medium badge. Set to `"large"` for a large badge, when it is empty (no text or icon). Defaults to `"small"` for the `ionic` theme, undefined for all other themes.
+ * Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a larger size. Defaults to `"small"` if both the size property and theme config are unset.
*/
- "size"?: 'small' | 'medium' | 'large';
+ "size"?: IonBadgeSize;
/**
* The theme determines the visual appearance of the component.
*/
@@ -491,7 +493,7 @@ export namespace Components {
/**
* Set to `"top"` to position the badge on top right absolute position of the parent element. Set to `"bottom"` to position the badge on bottom right absolute position of the parent element.
*/
- "vertical"?: 'top' | 'bottom';
+ "vertical"?: IonBadgeVerticalPosition;
}
interface IonBreadcrumb {
/**
@@ -898,7 +900,7 @@ export namespace Components {
*/
"shape"?: IonChipShape;
/**
- * Set to `"small"` for a chip with less height and padding. Defaults to `"large"` if both the size property and theme config are unset.
+ * Set to `"small"` for a chip with less height and padding, or `"large"` for a chip with more height and padding. Defaults to `"large"` if both the size property and theme config are unset.
*/
"size"?: IonChipSize;
}
@@ -6400,21 +6402,21 @@ declare namespace LocalJSX {
*/
"color"?: Color;
/**
- * 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.
+ * Set to `"bold"` for a badge with vibrant, bold colors or to `"subtle"` for a badge with muted, subtle colors. Defaults to `"bold"` if both the hue property and theme config are unset.
*/
- "hue"?: 'bold' | 'subtle';
+ "hue"?: IonBadgeHue;
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
- * Set to `"rectangular"` for non-rounded corners. Set to `"soft"` for slightly rounded corners. Set to `"round"` for fully rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
+ * Set to `"crisp"` for a badge with even slightly rounded corners, `"soft"` for a badge with slightly rounded corners, `"round"` for a badge with fully rounded corners, or `"rectangular"` for a badge without rounded corners. Defaults to `"soft"` if both the shape property and theme config are unset.
*/
- "shape"?: 'soft' | 'round | rectangular';
+ "shape"?: IonBadgeShape;
/**
- * Set to `"small"` for a small badge. Set to `"medium"` for a medium badge. Set to `"large"` for a large badge, when it is empty (no text or icon). Defaults to `"small"` for the `ionic` theme, undefined for all other themes.
+ * Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a larger size. Defaults to `"small"` if both the size property and theme config are unset.
*/
- "size"?: 'small' | 'medium' | 'large';
+ "size"?: IonBadgeSize;
/**
* The theme determines the visual appearance of the component.
*/
@@ -6422,7 +6424,7 @@ declare namespace LocalJSX {
/**
* Set to `"top"` to position the badge on top right absolute position of the parent element. Set to `"bottom"` to position the badge on bottom right absolute position of the parent element.
*/
- "vertical"?: 'top' | 'bottom';
+ "vertical"?: IonBadgeVerticalPosition;
}
interface IonBreadcrumb {
/**
@@ -6864,7 +6866,7 @@ declare namespace LocalJSX {
*/
"shape"?: IonChipShape;
/**
- * Set to `"small"` for a chip with less height and padding. Defaults to `"large"` if both the size property and theme config are unset.
+ * Set to `"small"` for a chip with less height and padding, or `"large"` for a chip with more height and padding. Defaults to `"large"` if both the size property and theme config are unset.
*/
"size"?: IonChipSize;
}
diff --git a/core/src/components/avatar/avatar.ionic.scss b/core/src/components/avatar/avatar.ionic.scss
index 11ffcdc881a..d31e6c9c5cb 100644
--- a/core/src/components/avatar/avatar.ionic.scss
+++ b/core/src/components/avatar/avatar.ionic.scss
@@ -169,79 +169,6 @@
height: globals.$ion-scale-800;
}
-// Avatar Badge Empty (hint)
-// --------------------------------------------------
-
-:host ::slotted(ion-badge.badge-vertical-top:empty) {
- @include globals.transform(translate(globals.$ion-scale-050, calc(globals.$ion-scale-050 * -1)));
-}
-
-:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-top:empty) {
- @include globals.transform(translate(globals.$ion-scale-100, calc(globals.$ion-scale-100 * -1)));
-}
-
-:host ::slotted(ion-badge.badge-vertical-bottom:empty) {
- @include globals.transform(translate(0, globals.$ion-scale-100));
-}
-
-:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-bottom:empty) {
- @include globals.transform(translate(globals.$ion-scale-100, globals.$ion-scale-100));
-}
-
-// Avatar Badge Bottom (hint)
-// --------------------------------------------------
-
-:host ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.transform(translate(50%, 50%));
-}
-
-:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.position(null, globals.$ion-scale-100, globals.$ion-scale-100, null);
- @include globals.transform(translate(100%, 100%));
-}
-
-:host(.avatar-xsmall) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.position(null, calc(globals.$ion-scale-050 * -1), calc(globals.$ion-scale-050 * -1), null);
-}
-
-:host(.avatar-small) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)),
-:host(.avatar-medium) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)),
-:host(.avatar-large) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.position(null, globals.$ion-scale-050, globals.$ion-scale-050, null);
-}
-
-:host(.avatar-xlarge) ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.position(null, globals.$ion-scale-150, globals.$ion-scale-150, null);
-}
-
-// Avatar Badge Top (hint)
-// --------------------------------------------------
-
-:host ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.transform(translate(50%, -50%));
-}
-
-:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.position(globals.$ion-scale-050, 0, null, null);
-}
-
-:host(.avatar-xsmall) ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.position(globals.$ion-scale-100, calc(globals.$ion-scale-050 * -1), null, null);
-}
-
-:host(.avatar-small) ::slotted(ion-badge.badge-vertical-top:not(:empty)),
-:host(.avatar-medium) ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.position(globals.$ion-scale-150, 0, null, null);
-}
-
-:host(.avatar-large) ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.position(globals.$ion-scale-150, globals.$ion-scale-050, null, null);
-}
-
-:host(.avatar-xlarge) ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.position(globals.$ion-scale-150, globals.$ion-scale-150, null, null);
-}
-
// Avatar Disabled
// --------------------------------------------------
:host(.avatar-disabled)::after {
diff --git a/core/src/components/avatar/avatar.md.scss b/core/src/components/avatar/avatar.md.scss
index cfcd2520280..b7679654770 100644
--- a/core/src/components/avatar/avatar.md.scss
+++ b/core/src/components/avatar/avatar.md.scss
@@ -11,22 +11,3 @@
width: $avatar-md-width;
height: $avatar-md-height;
}
-
-// Avatar Empty Badge (hint)
-// --------------------------------------------------
-
-::slotted(ion-badge.badge-vertical-top:empty) {
- @include globals.transform(translate(-50%, 50%));
-}
-
-::slotted(ion-badge.badge-vertical-bottom:empty) {
- @include globals.transform(translateX(-100%));
-}
-
-:host ::slotted(ion-badge.badge-vertical-top:not(:empty)) {
- @include globals.transform(translate(0, 100%));
-}
-
-:host ::slotted(ion-badge.badge-vertical-bottom:not(:empty)) {
- @include globals.transform(translate(0, -100%));
-}
diff --git a/core/src/components/avatar/avatar.tsx b/core/src/components/avatar/avatar.tsx
index da5ccb81707..5066dd1fc99 100644
--- a/core/src/components/avatar/avatar.tsx
+++ b/core/src/components/avatar/avatar.tsx
@@ -1,5 +1,6 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, h } from '@stencil/core';
+import { createBadgeManager } from '@utils/badge-position';
import { getIonTheme } from '../../global/ionic-global';
@@ -19,6 +20,10 @@ import { getIonTheme } from '../../global/ionic-global';
export class Avatar implements ComponentInterface {
@Element() el!: HTMLElement;
+ private badgeManager = createBadgeManager(this.el, () => ({
+ target: this.el,
+ }));
+
/**
* Set to `"xxsmall"` for the smallest size.
* Set to `"xsmall"` for a very small size.
@@ -45,6 +50,14 @@ export class Avatar implements ComponentInterface {
*/
@Prop() disabled = false;
+ componentDidLoad() {
+ this.badgeManager.init();
+ }
+
+ disconnectedCallback() {
+ this.badgeManager.destroy();
+ }
+
get hasImage() {
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
}
@@ -53,15 +66,13 @@ export class Avatar implements ComponentInterface {
return !!this.el.querySelector('ion-icon');
}
+ private onSlotChanged = () => {
+ this.badgeManager.onSlotChanged();
+ };
+
private getSize(): string | undefined {
- const theme = getIonTheme(this);
const { size } = this;
- // TODO(ROU-10752): Remove theme check when sizes are defined for all themes.
- if (theme !== 'ionic') {
- return undefined;
- }
-
if (size === undefined) {
return 'medium';
}
@@ -102,7 +113,7 @@ export class Avatar implements ComponentInterface {
[`avatar-disabled`]: disabled,
}}
>
-
+
);
}
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts b/core/src/components/avatar/test/badge/badge.e2e.ts
new file mode 100644
index 00000000000..7176fec4587
--- /dev/null
+++ b/core/src/components/avatar/test/badge/badge.e2e.ts
@@ -0,0 +1,51 @@
+import { expect } from '@playwright/test';
+import { configs, test } from '@utils/test/playwright';
+
+configs({ directions: ['ltr'], modes: ['md', 'ios', 'ionic-md'] }).forEach(({ config, screenshot, title }) => {
+ test.describe(title('avatar: badge'), () => {
+ ['xxsmall', 'xsmall', 'small', 'medium', 'large', 'xlarge'].forEach((avatarSize) => {
+ test(`${avatarSize} - should not have visual regressions with badges`, async ({ page }) => {
+ const badgeSizes = ['small', 'medium', 'large'];
+ const positions = ['top', 'bottom'];
+ const contents = ['', '1', '999+', ''];
+
+ const avatars = positions
+ .flatMap((position) =>
+ badgeSizes.flatMap((badgeSize) =>
+ contents.map(
+ (html) => `
+
+
+ ${html}
+
+ `
+ )
+ )
+ )
+ .join('\n');
+
+ await page.setContent(
+ `
+
+
+
+ ${avatars}
+
+ `,
+ config
+ );
+
+ const container = page.locator('#container');
+
+ await expect(container).toHaveScreenshot(screenshot(`avatar-${avatarSize}-badge`));
+ });
+ });
+ });
+});
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..2dcb09e3f96
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..e943e55203e
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..743ff522f1f
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-large-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..7c44a607705
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..549f20adeb8
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..48512aa1c2f
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-medium-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..fdf26479da9
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..5df79c1a2e6
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..41431643075
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-small-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..586ba35ed7b
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..57092d038e6
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..a7d69c99a8d
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xlarge-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..e94729651bc
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..76eec6bb7df
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..ad3751577a2
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xsmall-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..e6ec834a863
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..b0eed9f59a5
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..35936cec0ed
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..b457a33ec19
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..80579033c44
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..b2b84962d62
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Chrome-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..3120d2d677c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Firefox-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..f1836da3898
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Safari-linux.png b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..f3deff4827c
Binary files /dev/null and b/core/src/components/avatar/test/badge/badge.e2e.ts-snapshots/avatar-xxsmall-badge-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/avatar/test/badge/index.html b/core/src/components/avatar/test/badge/index.html
new file mode 100644
index 00000000000..e85d76017c6
--- /dev/null
+++ b/core/src/components/avatar/test/badge/index.html
@@ -0,0 +1,106 @@
+
+
+
+
+ Avatar - Badge
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Avatar - Badge
+
+
+
+
+
+
+
+
+
diff --git a/core/src/components/badge/badge.common.scss b/core/src/components/badge/badge.common.scss
deleted file mode 100644
index 1523886ea5e..00000000000
--- a/core/src/components/badge/badge.common.scss
+++ /dev/null
@@ -1,47 +0,0 @@
-@use "../../themes/functions.color" as color;
-@import "../../themes/mixins";
-
-// Badge
-// --------------------------------------------------
-
-:host {
- /**
- * @prop --background: Background of the badge
- * @prop --color: Text color of the badge
- *
- * @prop --padding-top: Top padding of the badge
- * @prop --padding-end: Right padding if direction is left-to-right, and left padding if direction is right-to-left of the badge
- * @prop --padding-bottom: Bottom padding of the badge
- * @prop --padding-start: Left padding if direction is left-to-right, and right padding if direction is right-to-left of the badge
- */
- @include font-smoothing();
- @include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
-
- display: inline-block;
-
- background: var(--background);
- color: var(--color);
-
- text-align: center;
-
- white-space: nowrap;
-
- contain: content;
- vertical-align: baseline;
-}
-
-// Badge (hint)
-// --------------------------------------------------
-
-:host([vertical]:not(.in-tab-button)) {
- @include position(null, 0, null, null);
- position: absolute;
-}
-
-:host(:not(.in-tab-button)[vertical].badge-vertical-top) {
- top: 0;
-}
-
-:host(:not(.in-tab-button)[vertical].badge-vertical-bottom) {
- bottom: 0;
-}
diff --git a/core/src/components/badge/badge.interfaces.ts b/core/src/components/badge/badge.interfaces.ts
new file mode 100644
index 00000000000..08e7c455f62
--- /dev/null
+++ b/core/src/components/badge/badge.interfaces.ts
@@ -0,0 +1,94 @@
+import type { IonPadding } from '../../themes/themes.interfaces';
+
+export type IonBadgeRecipe = {
+ font?: {
+ family?: string;
+ };
+
+ // Hues
+ hue?: {
+ [K in IonBadgeHue]?: IonBadgeStateDefinition & {
+ semantic?: IonBadgeStateDefinition;
+ };
+ };
+
+ // Shapes
+ shape?: {
+ [K in IonBadgeShape]?: IonBadgeShapeDefinition;
+ };
+
+ // Sizes
+ size?: {
+ [K in IonBadgeSize]?: {
+ /* Badge with content (i.e. text or an icon) */
+ content?: IonBadgeSizeContentDefinition;
+
+ /* Badge without content (i.e. dot badge) */
+ dot?: IonBadgeSizeDotDefinition;
+ };
+ };
+};
+
+type IonBadgeColorDefinition = {
+ background?: string;
+ color?: string;
+ border?: {
+ radius?: string;
+ };
+};
+
+type IonBadgeStateDefinition = {
+ default?: IonBadgeColorDefinition;
+};
+
+type IonBadgeShapeDefinition = {
+ border?: {
+ radius?: string;
+ };
+};
+
+type IonBadgeSizeDefinition = {
+ height?: string;
+
+ padding?: IonPadding;
+};
+
+type IonBadgeSizeContentDefinition = IonBadgeSizeDefinition & {
+ letterSpacing?: string | number;
+
+ min?: {
+ height?: string;
+ width?: string;
+ };
+
+ font?: {
+ size?: string;
+ weight?: string | number;
+ };
+
+ line?: {
+ height?: string | number;
+ };
+
+ icon?: {
+ width?: string;
+ height?: string;
+ };
+};
+
+type IonBadgeSizeDotDefinition = IonBadgeSizeDefinition & {
+ min?: {
+ width?: string;
+ };
+};
+
+export type IonBadgeConfig = {
+ hue?: IonBadgeHue;
+ size?: IonBadgeSize;
+ shape?: IonBadgeShape;
+};
+
+export type IonBadgeHue = 'bold' | 'subtle';
+export type IonBadgeShape = 'crisp' | 'soft' | 'round' | 'rectangular';
+export type IonBadgeSize = 'small' | 'medium' | 'large';
+export type IonBadgeVerticalPosition = 'top' | 'bottom';
diff --git a/core/src/components/badge/badge.ionic.scss b/core/src/components/badge/badge.ionic.scss
deleted file mode 100644
index 4342c2b51d3..00000000000
--- a/core/src/components/badge/badge.ionic.scss
+++ /dev/null
@@ -1,176 +0,0 @@
-@use "../../themes/ionic/ionic.globals.scss" as globals;
-@use "./badge.common";
-
-// Ionic Badge
-// --------------------------------------------------
-
-:host {
- --padding-start: #{globals.$ion-space-200};
- --padding-end: #{globals.$ion-space-200};
- --padding-top: #{globals.$ion-space-0};
- --padding-bottom: #{globals.$ion-space-0};
-
- @include globals.typography(globals.$ion-body-sm-medium);
-
- display: inline-flex;
-
- align-items: center;
- justify-content: center;
-
- min-width: globals.$ion-scale-250;
-}
-
-// Bold Badge
-// --------------------------------------------------
-
-:host(.badge-bold) {
- --background: #{globals.ion-color(primary, base)};
- --color: #{globals.ion-color(primary, contrast)};
-}
-
-:host(.badge-bold.ion-color) {
- background: globals.current-color(base);
- color: globals.current-color(contrast);
-}
-
-// Subtle Badge
-// --------------------------------------------------
-
-:host(.badge-subtle) {
- --background: #{globals.ion-color(primary, base, $subtle: true)};
- --color: #{globals.ion-color(primary, contrast, $subtle: true)};
-}
-
-:host(.badge-subtle.ion-color) {
- background: globals.current-color(base, $subtle: true);
- color: globals.current-color(contrast, $subtle: true);
-}
-
-// Badge Shapes
-// --------------------------------------------------
-
-/* Soft Badge */
-:host(.badge-soft) {
- @include globals.border-radius(globals.$ion-soft-xs);
-}
-
-:host(.badge-small.badge-soft) {
- @include globals.border-radius(globals.$ion-soft-2xs);
-}
-
-/* Round Badge */
-:host(.badge-round) {
- @include globals.border-radius(globals.$ion-round-sm);
-}
-
-/* Rectangular Badge */
-:host(.badge-rectangular) {
- @include globals.border-radius(globals.$ion-rectangular-sm);
-}
-
-// Badge Sizes
-// --------------------------------------------------
-
-/* Small Badge */
-:host(.badge-small) {
- --padding-start: #{globals.$ion-space-050};
- --padding-end: #{globals.$ion-space-050};
-
- min-width: globals.$ion-scale-400;
- height: globals.$ion-scale-400;
-}
-
-:host(.badge-small) ::slotted(ion-icon) {
- width: globals.$ion-scale-300;
- height: globals.$ion-scale-300;
-}
-
-/* Medium Badge */
-/* Large size defaults to the medium size to avoid styles breakage */
-:host(.badge-medium),
-:host(.badge-large) {
- --padding-start: #{globals.$ion-space-100};
- --padding-end: #{globals.$ion-space-100};
-
- @include globals.typography(globals.$ion-body-md-medium);
-
- min-width: globals.$ion-scale-600;
- height: globals.$ion-scale-600;
-}
-
-:host(.badge-medium) ::slotted(ion-icon),
-:host(.badge-large) ::slotted(ion-icon) {
- width: globals.$ion-scale-400;
- height: globals.$ion-scale-400;
-}
-
-// Badge (hint)
-// --------------------------------------------------
-
-:host(:empty) {
- --padding-start: 0;
- --padding-end: 0;
-}
-
-:host([vertical]:not(:empty)) {
- --padding-start: #{globals.$ion-scale-100};
- --padding-end: #{globals.$ion-scale-100};
- --padding-top: #{globals.$ion-scale-100};
- --padding-bottom: #{globals.$ion-scale-100};
-}
-
-// Badge (hint) Sizes
-// --------------------------------------------------
-
-/* sm */
-:host(.badge-small:empty) {
- min-width: globals.$ion-scale-200;
- height: globals.$ion-scale-200;
-}
-
-/* md */
-:host(.badge-medium:empty) {
- min-width: globals.$ion-scale-300;
- height: globals.$ion-scale-300;
-}
-
-/* lg */
-:host(.badge-large:empty) {
- min-width: globals.$ion-scale-400;
- height: globals.$ion-scale-400;
-}
-
-// Badge Inside Tab Button
-// --------------------------------------------------
-
-:host([vertical].in-tab-button) {
- position: relative;
-}
-
-// Icon Inside Badge Hint
-// --------------------------------------------------
-:host([vertical]) ::slotted(ion-icon) {
- @include globals.position(50%, null, null, 50%);
-
- position: absolute;
-
- transform: translate(-50%, -50%);
-}
-
-// Badge in Button
-// --------------------------------------------------
-
-:host(:not(:empty).in-button) {
- --padding-start: #{globals.$ion-scale-050};
- --padding-end: #{globals.$ion-scale-050};
-
- @include globals.typography(globals.$ion-body-action-xs);
-
- min-width: globals.$ion-scale-400;
- height: globals.$ion-scale-400;
-
- ::slotted(ion-icon) {
- width: globals.$ion-scale-300;
- height: globals.$ion-scale-300;
- }
-}
diff --git a/core/src/components/badge/badge.ios.scss b/core/src/components/badge/badge.ios.scss
deleted file mode 100644
index 2d61ad713f9..00000000000
--- a/core/src/components/badge/badge.ios.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-@import "./badge.native";
-@import "./badge.ios.vars";
-
-// iOS Badge
-// --------------------------------------------------
-
-:host {
- @include border-radius($badge-ios-border-radius);
-
- /**
- * "-apple-system-body" on iOS never goes smaller than
- * 14px according to https://developer.apple.com/design/human-interface-guidelines/typography#Specifications.
- * However, we still keep the max() usage here for consistency
- * with other components and in case "-apple-system-body" does
- * go smaller than 14px in the future.
- */
- font-size: dynamic-font-min(1, $badge-baseline-font-size);
-}
-
-// Badge Inside Tab Button
-// --------------------------------------------------
-
-:host([vertical].in-tab-button) {
- position: relative;
-
- min-width: $badge-ios-in-tab-button-min-width;
-}
-
-:host([vertical].in-tab-button) ::slotted(ion-icon) {
- @include position(50%, null, null, 50%);
-
- position: absolute;
-
- width: $badge-ios-in-tab-button-icon-size;
- height: $badge-ios-in-tab-button-icon-size;
-
- transform: translate(-50%, -50%);
-}
diff --git a/core/src/components/badge/badge.ios.vars.scss b/core/src/components/badge/badge.ios.vars.scss
deleted file mode 100644
index a9294899dc1..00000000000
--- a/core/src/components/badge/badge.ios.vars.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-@import "../../themes/native/native.globals.ios";
-
-// iOS Badge
-// --------------------------------------------------
-
-/// @prop - Border radius of the badge
-$badge-ios-border-radius: 10px;
-
-// Badge inside a Tab Button
-// --------------------------------------------------
-
-/// @prop - Minimum width of the badge inside a Tab Button
-$badge-ios-in-tab-button-min-width: 8px;
-
-/// @prop - Height of the badge inside a Tab Button
-$badge-ios-in-tab-button-height: 8px;
-
-/// @prop - Badge icon size inside a Tab Button
-$badge-ios-in-tab-button-icon-size: 12px;
diff --git a/core/src/components/badge/badge.md.scss b/core/src/components/badge/badge.md.scss
deleted file mode 100644
index 3d0e94bbde4..00000000000
--- a/core/src/components/badge/badge.md.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@import "./badge.native";
-@import "./badge.md.vars";
-
-// Material Design Badge
-// --------------------------------------------------
-
-:host {
- --padding-top: 3px;
- --padding-end: 4px;
- --padding-bottom: 4px;
- --padding-start: 4px;
-
- @include border-radius($badge-md-border-radius);
-}
diff --git a/core/src/components/badge/badge.md.vars.scss b/core/src/components/badge/badge.md.vars.scss
deleted file mode 100644
index d458dcb51ce..00000000000
--- a/core/src/components/badge/badge.md.vars.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@import "../../themes/native/native.globals.md";
-
-// Material Design Badge
-// --------------------------------------------------
-
-/// @prop - Border radius of the badge
-$badge-md-border-radius: 4px;
diff --git a/core/src/components/badge/badge.native.scss b/core/src/components/badge/badge.native.scss
deleted file mode 100644
index 0afa59779d6..00000000000
--- a/core/src/components/badge/badge.native.scss
+++ /dev/null
@@ -1,64 +0,0 @@
-@import "../../themes/native/native.globals.md";
-@import "./badge.common";
-@import "./badge.native.vars";
-
-// Badge
-// --------------------------------------------------
-
-:host {
- --padding-top: #{$badge-padding-top};
- --padding-end: #{$badge-padding-end};
- --padding-bottom: #{$badge-padding-bottom};
- --padding-start: #{$badge-padding-start};
- --background: #{ion-color(primary, base)};
- --color: #{ion-color(primary, contrast)};
-
- min-width: $badge-min-width;
-
- font-family: $font-family-base;
-
- font-size: $badge-font-size;
- font-weight: $badge-font-weight;
-
- line-height: 1;
-}
-
-:host(.ion-color) {
- background: current-color(base);
- color: current-color(contrast);
-}
-
-// TODO(ROU-10747): Review size styles when sizes are defined for native themes.
-:host([vertical]:not(.in-button):not(.in-tab-button)),
-:host(:empty) {
- --padding-start: 0;
- --padding-end: 0;
- --padding-bottom: 0;
- --padding-top: 0;
-
- @include border-radius(999px);
-
- width: $badge-min-width;
- height: $badge-min-width;
-
- font-size: $badge-hint-font-size;
-
- line-height: 10px;
-}
-
-// Badge in Button
-// --------------------------------------------------
-
-:host(:not(:empty).in-button) {
- min-width: $badge-size-in-button;
- height: $badge-size-in-button;
-
- font-size: $badge-font-size-in-button;
-
- line-height: $badge-line-height-in-button;
-
- ::slotted(ion-icon) {
- width: $badge-icon-size-in-button;
- height: $badge-icon-size-in-button;
- }
-}
diff --git a/core/src/components/badge/badge.native.vars.scss b/core/src/components/badge/badge.native.vars.scss
deleted file mode 100644
index aad738da58e..00000000000
--- a/core/src/components/badge/badge.native.vars.scss
+++ /dev/null
@@ -1,47 +0,0 @@
-@import "../../themes/functions.font";
-@import "../../themes/functions.sizes";
-
-// Badge
-// --------------------------------------------------
-
-/// @prop - Font size of the badge hint
-$badge-hint-baseline-font-size: 8px;
-
-/// @prop - Font size of the badge hint
-$badge-hint-font-size: dynamic-font($badge-hint-baseline-font-size);
-
-/// @prop - Size of the badge when inside button
-$badge-size-in-button: 16px;
-
-/// @prop - Font size of the badge when inside button
-$badge-font-size-in-button: px-to-rem(12);
-
-/// @prop - Line height of the badge when inside button
-$badge-line-height-in-button: 20px;
-
-/// @prop - Size of of the badge icon when inside button
-$badge-icon-size-in-button: 12px;
-
-/// @prop - Padding top of the badge
-$badge-padding-top: 3px;
-
-/// @prop - Padding end of the badge
-$badge-padding-end: 8px;
-
-/// @prop - Padding bottom of the badge
-$badge-padding-bottom: $badge-padding-top;
-
-/// @prop - Padding start of the badge
-$badge-padding-start: $badge-padding-end;
-
-/// @prop - Minimum width of the badge
-$badge-min-width: 10px;
-
-/// @prop - Baseline font size of the badge
-$badge-baseline-font-size: 13px;
-
-/// @prop - Font size of the badge
-$badge-font-size: dynamic-font($badge-baseline-font-size);
-
-/// @prop - Font weight of the badge
-$badge-font-weight: bold;
diff --git a/core/src/components/badge/badge.scss b/core/src/components/badge/badge.scss
new file mode 100644
index 00000000000..01763d30cb6
--- /dev/null
+++ b/core/src/components/badge/badge.scss
@@ -0,0 +1,288 @@
+@use "../../themes/mixins" as mixins;
+@use "../../themes/functions.color" as colors;
+
+// Badge: Common Styles
+// --------------------------------------------------
+
+:host {
+ /**
+ * @prop --ion-badge-font-family - the font family of the badge text
+ *
+ * Bold
+ * @prop --ion-badge-hue-bold-default-background - Background color of the `bold` hue in default state
+ * @prop --ion-badge-hue-bold-default-color - Text color of the `bold` hue in default state
+ * @prop --ion-badge-hue-bold-default-border-radius - Border radius of the `bold` hue in default state
+ * @prop --ion-badge-hue-bold-semantic-default-background - Background color of the `bold` hue when a semantic color is applied
+ * @prop --ion-badge-hue-bold-semantic-default-color - Text color of the `bold` hue when a semantic color is applied
+ * @prop --ion-badge-hue-bold-semantic-default-border-radius - Border radius of the `bold` hue when a semantic color is applied
+ *
+ * Subtle
+ * @prop --ion-badge-hue-subtle-default-background - Background color of the `subtle` hue in default state
+ * @prop --ion-badge-hue-subtle-default-color - Text color of the `subtle` hue in default state
+ * @prop --ion-badge-hue-subtle-default-border-radius - Border radius of the `subtle` hue in default state
+ * @prop --ion-badge-hue-subtle-semantic-default-background - Background color of the `subtle` hue when a semantic color is applied
+ * @prop --ion-badge-hue-subtle-semantic-default-color - Text color of the `subtle` hue when a semantic color is applied
+ * @prop --ion-badge-hue-subtle-semantic-default-border-radius - Border radius of the `subtle` hue when a semantic color is applied
+ *
+ * Shapes
+ * @prop --ion-badge-shape-crisp-border-radius - Border radius of the `crisp` shape
+ * @prop --ion-badge-shape-soft-border-radius - Border radius of the `soft` shape
+ * @prop --ion-badge-shape-round-border-radius - Border radius of the `round` shape
+ * @prop --ion-badge-shape-rectangular-border-radius - Border radius of the `rectangular` shape
+ *
+ * Sizes: Content (with text or an icon)
+ * @prop --ion-badge-size-small-content-height - Height of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-min-height - Minimum height of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-min-width - Minimum width of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-padding-top - Top padding of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-padding-bottom - Bottom padding of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-letter-spacing - Letter spacing of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-font-size - Font size of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-font-weight - Font weight of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-line-height - Line height of the `small` size when badge has content
+ * @prop --ion-badge-size-small-content-icon-width - Width of the slotted `ion-icon` of the `small` size
+ * @prop --ion-badge-size-small-content-icon-height - Height of the slotted `ion-icon` of the `small` size
+ * @prop --ion-badge-size-medium-content-height - Height of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-min-height - Minimum height of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-min-width - Minimum width of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-padding-top - Top padding of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-padding-bottom - Bottom padding of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-letter-spacing - Letter spacing of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-font-size - Font size of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-font-weight - Font weight of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-line-height - Line height of the `medium` size when badge has content
+ * @prop --ion-badge-size-medium-content-icon-width - Width of the slotted `ion-icon` of the `medium` size
+ * @prop --ion-badge-size-medium-content-icon-height - Height of the slotted `ion-icon` of the `medium` size
+ * @prop --ion-badge-size-large-content-height - Height of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-min-height - Minimum height of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-min-width - Minimum width of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-padding-top - Top padding of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-padding-bottom - Bottom padding of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-letter-spacing - Letter spacing of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-font-size - Font size of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-font-weight - Font weight of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-line-height - Line height of the `large` size when badge has content
+ * @prop --ion-badge-size-large-content-icon-width - Width of the slotted `ion-icon` of the `large` size
+ * @prop --ion-badge-size-large-content-icon-height - Height of the slotted `ion-icon` of the `large` size
+ *
+ * Sizes: Dot (empty with no text or icon)
+ * @prop --ion-badge-size-small-dot-height - Height of the `small` size when badge is empty
+ * @prop --ion-badge-size-small-dot-min-width - Minimum width of the `small` size when badge is empty
+ * @prop --ion-badge-size-small-dot-padding-top - Top padding of the `small` size when badge is empty
+ * @prop --ion-badge-size-small-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `small` size when badge is empty
+ * @prop --ion-badge-size-small-dot-padding-bottom - Bottom padding of the `small` size when badge is empty
+ * @prop --ion-badge-size-small-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `small` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-height - Height of the `medium` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-min-width - Minimum width of the `medium` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-padding-top - Top padding of the `medium` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `medium` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-padding-bottom - Bottom padding of the `medium` size when badge is empty
+ * @prop --ion-badge-size-medium-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `medium` size when badge is empty
+ * @prop --ion-badge-size-large-dot-height - Height of the `large` size when badge is empty
+ * @prop --ion-badge-size-large-dot-min-width - Minimum width of the `large` size when badge is empty
+ * @prop --ion-badge-size-large-dot-padding-top - Top padding of the `large` size when badge is empty
+ * @prop --ion-badge-size-large-dot-padding-end - Right padding if direction is left-to-right, left padding if direction is right-to-left of the `large` size when badge is empty
+ * @prop --ion-badge-size-large-dot-padding-bottom - Bottom padding of the `large` size when badge is empty
+ * @prop --ion-badge-size-large-dot-padding-start - Left padding if direction is left-to-right, right padding if direction is right-to-left of the `large` size when badge is empty
+ */
+ @include mixins.font-smoothing();
+
+ display: inline-flex;
+
+ align-items: center;
+ justify-content: center;
+
+ font-family: var(--ion-badge-font-family, inherit);
+
+ white-space: nowrap;
+
+ contain: content;
+ vertical-align: baseline;
+}
+
+// Badge: Bold
+// ---------------------------------------------
+
+// Default
+:host(.badge-hue-bold) {
+ background: var(--ion-badge-hue-bold-default-background);
+ color: var(--ion-badge-hue-bold-default-color);
+}
+
+// Colors
+:host(.badge-hue-bold.ion-color) {
+ background: var(--ion-badge-hue-bold-semantic-default-background);
+ color: var(--ion-badge-hue-bold-semantic-default-color);
+}
+
+// Badge: Subtle
+// ---------------------------------------------
+
+// Default
+:host(.badge-hue-subtle) {
+ background: var(--ion-badge-hue-subtle-default-background);
+ color: var(--ion-badge-hue-subtle-default-color);
+}
+
+// Colors
+:host(.badge-hue-subtle.ion-color) {
+ background: var(--ion-badge-hue-subtle-semantic-default-background);
+ color: var(--ion-badge-hue-subtle-semantic-default-color);
+}
+
+// Badge Shapes
+// ---------------------------------------------
+
+:host(.badge-shape-crisp) {
+ @include mixins.border-radius(var(--ion-badge-shape-crisp-border-radius));
+}
+
+:host(.badge-shape-soft) {
+ @include mixins.border-radius(var(--ion-badge-shape-soft-border-radius));
+}
+
+:host(.badge-shape-round) {
+ @include mixins.border-radius(var(--ion-badge-shape-round-border-radius));
+}
+
+:host(.badge-shape-rectangular) {
+ @include mixins.border-radius(var(--ion-badge-shape-rectangular-border-radius));
+}
+
+// Badge Sizes: Content (with text or an icon)
+// ---------------------------------------------
+
+// Small
+:host(.badge-size-small) {
+ @include mixins.padding(
+ var(--ion-badge-size-small-content-padding-top),
+ var(--ion-badge-size-small-content-padding-end),
+ var(--ion-badge-size-small-content-padding-bottom),
+ var(--ion-badge-size-small-content-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-small-content-min-width);
+ height: var(--ion-badge-size-small-content-height);
+ min-height: var(--ion-badge-size-small-content-min-height);
+
+ font-size: var(--ion-badge-size-small-content-font-size);
+ font-weight: var(--ion-badge-size-small-content-font-weight);
+
+ line-height: var(--ion-badge-size-small-content-line-height);
+}
+
+:host(.badge-size-small) ::slotted(ion-icon) {
+ width: var(--ion-badge-size-small-content-icon-width, revert-layer);
+ height: var(--ion-badge-size-small-content-icon-height, revert-layer);
+}
+
+// Medium
+:host(.badge-size-medium) {
+ @include mixins.padding(
+ var(--ion-badge-size-medium-content-padding-top),
+ var(--ion-badge-size-medium-content-padding-end),
+ var(--ion-badge-size-medium-content-padding-bottom),
+ var(--ion-badge-size-medium-content-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-medium-content-min-width);
+ height: var(--ion-badge-size-medium-content-height);
+ min-height: var(--ion-badge-size-medium-content-min-height);
+
+ font-size: var(--ion-badge-size-medium-content-font-size);
+ font-weight: var(--ion-badge-size-medium-content-font-weight);
+
+ line-height: var(--ion-badge-size-medium-content-line-height);
+}
+
+:host(.badge-size-medium) ::slotted(ion-icon) {
+ width: var(--ion-badge-size-medium-content-icon-width, revert-layer);
+ height: var(--ion-badge-size-medium-content-icon-height, revert-layer);
+}
+
+// Large
+:host(.badge-size-large) {
+ @include mixins.padding(
+ var(--ion-badge-size-large-content-padding-top),
+ var(--ion-badge-size-large-content-padding-end),
+ var(--ion-badge-size-large-content-padding-bottom),
+ var(--ion-badge-size-large-content-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-large-content-min-width);
+ height: var(--ion-badge-size-large-content-height);
+ min-height: var(--ion-badge-size-large-content-min-height);
+
+ font-size: var(--ion-badge-size-large-content-font-size);
+ font-weight: var(--ion-badge-size-large-content-font-weight);
+
+ line-height: var(--ion-badge-size-large-content-line-height);
+}
+
+:host(.badge-size-large) ::slotted(ion-icon) {
+ width: var(--ion-badge-size-large-content-icon-width, revert-layer);
+ height: var(--ion-badge-size-large-content-icon-height, revert-layer);
+}
+
+// Badge Sizes: Dot (empty with no text or icon)
+// ---------------------------------------------
+
+// Small
+:host(.badge-size-small:empty) {
+ @include mixins.padding(
+ var(--ion-badge-size-small-dot-padding-top),
+ var(--ion-badge-size-small-dot-padding-end),
+ var(--ion-badge-size-small-dot-padding-bottom),
+ var(--ion-badge-size-small-dot-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-small-dot-min-width);
+ height: var(--ion-badge-size-small-dot-height);
+
+ min-height: unset;
+}
+
+// Medium
+:host(.badge-size-medium:empty) {
+ @include mixins.padding(
+ var(--ion-badge-size-medium-dot-padding-top),
+ var(--ion-badge-size-medium-dot-padding-end),
+ var(--ion-badge-size-medium-dot-padding-bottom),
+ var(--ion-badge-size-medium-dot-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-medium-dot-min-width);
+ height: var(--ion-badge-size-medium-dot-height);
+
+ min-height: unset;
+}
+
+// Large
+:host(.badge-size-large:empty) {
+ @include mixins.padding(
+ var(--ion-badge-size-large-dot-padding-top),
+ var(--ion-badge-size-large-dot-padding-end),
+ var(--ion-badge-size-large-dot-padding-bottom),
+ var(--ion-badge-size-large-dot-padding-start)
+ );
+
+ min-width: var(--ion-badge-size-large-dot-min-width);
+ height: var(--ion-badge-size-large-dot-height);
+
+ min-height: unset;
+}
+
+// Anchored Badge (positioned at a specific corner of its parent element)
+// ---------------------------------------------
+
+:host([vertical]) {
+ position: absolute;
+
+ z-index: 1;
+}
diff --git a/core/src/components/badge/badge.tsx b/core/src/components/badge/badge.tsx
index 369c2ad199b..bbd9e007135 100644
--- a/core/src/components/badge/badge.tsx
+++ b/core/src/components/badge/badge.tsx
@@ -1,21 +1,19 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, h } from '@stencil/core';
-import { createColorClasses, hostContext } from '@utils/theme';
+import { createColorClasses } from '@utils/theme';
-import { getIonTheme } from '../../global/ionic-global';
+import { config } from '../../global/config';
import type { Color } from '../../interface';
+import type { IonBadgeHue, IonBadgeShape, IonBadgeSize, IonBadgeVerticalPosition } from './badge.interfaces';
+
/**
* @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.
*/
@Component({
tag: 'ion-badge',
- styleUrls: {
- ios: 'badge.ios.scss',
- md: 'badge.md.scss',
- ionic: 'badge.ionic.scss',
- },
+ styleUrl: 'badge.scss',
shadow: true,
})
export class Badge implements ComponentInterface {
@@ -32,108 +30,77 @@ export class Badge implements ComponentInterface {
* 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.
+ * Defaults to `"bold"` if both the hue property and theme config are unset.
*/
- @Prop() hue?: 'bold' | 'subtle';
+ @Prop() hue?: IonBadgeHue;
/**
- * Set to `"rectangular"` for non-rounded corners.
- * Set to `"soft"` for slightly rounded corners.
- * Set to `"round"` for fully rounded corners.
+ * Set to `"crisp"` for a badge with even slightly rounded corners,
+ * `"soft"` for a badge with slightly rounded corners,
+ * `"round"` for a badge with fully rounded corners,
+ * or `"rectangular"` for a badge without rounded corners.
*
- * Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
+ * Defaults to `"soft"` if both the shape property and theme config are unset.
*/
- @Prop() shape?: 'soft' | 'round | rectangular';
+ @Prop() shape?: IonBadgeShape;
/**
- * Set to `"small"` for a small badge.
- * Set to `"medium"` for a medium badge.
- * Set to `"large"` for a large badge, when it is empty (no text or icon).
+ * Set to `"small"` for a smaller size.
+ * Set to `"medium"` for a medium size.
+ * Set to `"large"` for a larger size.
*
- * Defaults to `"small"` for the `ionic` theme, undefined for all other themes.
+ * Defaults to `"small"` if both the size property and theme config are unset.
*/
- @Prop() size?: 'small' | 'medium' | 'large';
+ @Prop() size?: IonBadgeSize;
/**
* Set to `"top"` to position the badge on top right absolute position of the parent element.
* Set to `"bottom"` to position the badge on bottom right absolute position of the parent element.
*/
- @Prop() vertical?: 'top' | 'bottom';
-
- private getShape(): string | undefined {
- const theme = getIonTheme(this);
- const { shape } = this;
-
- // TODO(ROU-10777): Remove theme check when shapes are defined for all themes.
- if (theme !== 'ionic') {
- return undefined;
- }
+ @Prop() vertical?: IonBadgeVerticalPosition;
- if (shape === undefined) {
- return 'round';
- }
+ /**
+ * Gets the badge shape. Uses the `shape` property if set, otherwise
+ * checks the theme config and falls back to 'soft' if neither is provided.
+ */
+ get shapeValue(): IonBadgeShape {
+ const shapeConfig = config.getObjectValue('IonBadge.shape', 'soft') as IonBadgeShape;
+ const shape = this.shape || shapeConfig;
return shape;
}
- private getSize(): string | undefined {
- const theme = getIonTheme(this);
- const { size } = this;
-
- // TODO(FW-6355): Remove theme check when sizes are defined for all themes.
- if (theme !== 'ionic') {
- return undefined;
- }
-
- if (size === undefined) {
- return 'small';
- }
+ /**
+ * Gets the badge size. Uses the `size` property if set, otherwise
+ * checks the theme config and falls back to 'small' if neither is provided.
+ */
+ get sizeValue(): IonBadgeSize {
+ const sizeConfig = config.getObjectValue('IonBadge.size', 'small') as IonBadgeSize;
+ const size = this.size || sizeConfig;
return size;
}
- // The 'subtle' hue is the default for badges containing text or icons
- // The 'bold' hue is used when inside of an avatar, button, tab button,
- // or when the badge is empty (no text or icon).
- 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';
- }
-
- // Return 'subtle' if the badge contains visible text or an icon
- return 'subtle';
+ /**
+ * Gets the badge hue. Uses the `hue` property if set, otherwise
+ * checks the theme config and falls back to 'bold' if neither is provided.
+ */
+ get hueValue(): IonBadgeHue {
+ const hueConfig = config.getObjectValue('IonBadge.hue', 'bold') as IonBadgeHue;
+ const hue = this.hue || hueConfig;
+
+ return hue;
}
render() {
- const hue = this.getHue();
- const shape = this.getShape();
- const size = this.getSize();
- const theme = getIonTheme(this);
+ const { hueValue, shapeValue, sizeValue, color } = this;
return (
2,
+ class={createColorClasses(color, {
+ [`badge-hue-${hueValue}`]: true,
+ [`badge-shape-${shapeValue}`]: true,
+ [`badge-size-${sizeValue}`]: true,
})}
>
diff --git a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Chrome-linux.png
index 726dd09099f..fce1c134362 100644
Binary files a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Chrome-linux.png and b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Firefox-linux.png
index 83689947665..53d6943ea43 100644
Binary files a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Safari-linux.png b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Safari-linux.png
index e7a7fb6b1d0..7d712a998e3 100644
Binary files a/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Safari-linux.png and b/core/src/components/badge/test/a11y/badge.e2e.ts-snapshots/badge-scale-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/badge/test/basic/badge.e2e.ts b/core/src/components/badge/test/basic/badge.e2e.ts
index e6a6a871f96..422ac783f10 100644
--- a/core/src/components/badge/test/basic/badge.e2e.ts
+++ b/core/src/components/badge/test/basic/badge.e2e.ts
@@ -4,11 +4,67 @@ import { configs, test } from '@utils/test/playwright';
configs({ modes: ['md', 'ios', 'ionic-md'] }).forEach(({ config, screenshot, title }) => {
test.describe(title('badge: rendering'), () => {
test('should not have visual regressions', async ({ page }) => {
- await page.goto('/src/components/badge/test/basic', config);
+ await page.setContent(
+ `
+