Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions packages/main/cypress/specs/visuals/AvatarBadge.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,31 @@ describe("AvatarBadge visual", () => {
);
cy.screenshot();
});

it("extended color palette - all accents", () => {
cy.mount(
<div style={{ display: "flex", gap: "1rem", flexWrap: "wrap" }}>
{["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"].map((scheme) => (
<Avatar key={scheme}>
<AvatarBadge slot="badge" icon="employee" colorScheme={scheme} />
</Avatar>
))}
</div>
);
cy.screenshot();
});

it("extended color palette - semantic state overrides colorScheme", () => {
cy.mount(
<Avatar>
<AvatarBadge slot="badge" icon="alert" state="Negative" colorScheme="3" />
</Avatar>
);
// semantic state wins - Negative red styling should apply
cy.get("[ui5-avatar]")
.find("[ui5-avatar-badge]")
.should("have.attr", "state", "Negative")
.should("have.attr", "color-scheme", "3");
cy.screenshot();
});
});
18 changes: 18 additions & 0 deletions packages/main/src/AvatarBadge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,30 @@ class AvatarBadge extends UI5Element {
* - `Negative` - Red, used for error/rejected states
* - `Information` - Blue, used for informational states
*
* **Note:** `state` takes precedence over `colorScheme`. When `state` is set
* to any value other than `None`, the semantic styling applies and `colorScheme` is ignored.
*
* @default "None"
* @public
*/
@property()
state: `${ValueState}` = ValueState.None;

/**
* Defines the color scheme of the badge using the indication color palette.
*
* Available options are `"1"` through `"10"`, matching the indication colors.
*
* **Note:** `state` takes precedence - when `state` is set to any value other than `None`,
* the semantic state styling applies and `colorScheme` is ignored.
*
* @default undefined
* @public
* @since 2.27.0
*/
@property()
colorScheme?: string;

/**
* @private
*/
Expand Down
12 changes: 12 additions & 0 deletions packages/main/src/themes/AvatarBadge.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
color: var(--sapInformativeTextColor);
}

/* Extended color palette - applies only when state is None */
:host([color-scheme="1"][state="None"]) { background: var(--sapIndicationColor_1_Background); border-color: var(--sapIndicationColor_1_BorderColor); color: var(--sapIndicationColor_1_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="2"][state="None"]) { background: var(--sapIndicationColor_2_Background); border-color: var(--sapIndicationColor_2_BorderColor); color: var(--sapIndicationColor_2_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="3"][state="None"]) { background: var(--sapIndicationColor_3_Background); border-color: var(--sapIndicationColor_3_BorderColor); color: var(--sapIndicationColor_3_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="4"][state="None"]) { background: var(--sapIndicationColor_4_Background); border-color: var(--sapIndicationColor_4_BorderColor); color: var(--sapIndicationColor_4_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="5"][state="None"]) { background: var(--sapIndicationColor_5_Background); border-color: var(--sapIndicationColor_5_BorderColor); color: var(--sapIndicationColor_5_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="6"][state="None"]) { background: var(--sapIndicationColor_6_Background); border-color: var(--sapIndicationColor_6_BorderColor); color: var(--sapIndicationColor_6_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="7"][state="None"]) { background: var(--sapIndicationColor_7_Background); border-color: var(--sapIndicationColor_7_BorderColor); color: var(--sapIndicationColor_7_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="8"][state="None"]) { background: var(--sapIndicationColor_8_Background); border-color: var(--sapIndicationColor_8_BorderColor); color: var(--sapIndicationColor_8_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="9"][state="None"]) { background: var(--sapIndicationColor_9_Background); border-color: var(--sapIndicationColor_9_BorderColor); color: var(--sapIndicationColor_9_TextColor); box-shadow: var(--sapContent_Shadow1); }
:host([color-scheme="10"][state="None"]) { background: var(--sapIndicationColor_10_Background); border-color: var(--sapIndicationColor_10_BorderColor); color: var(--sapIndicationColor_10_TextColor); box-shadow: var(--sapContent_Shadow1); }

.ui5-avatar-badge-icon {
width: var(--_ui5-avatar-badge-icon-size);
height: var(--_ui5-avatar-badge-icon-size);
Expand Down
116 changes: 100 additions & 16 deletions packages/main/test/pages/Avatar.html
Original file line number Diff line number Diff line change
Expand Up @@ -287,22 +287,106 @@ <h3>Avatar Badge - With Initials and Color Schemes</h3>
</section>

<section>
<h3>Avatar Badge - With Icons</h3>
<ui5-avatar icon="employee" size="M">
<ui5-avatar-badge icon="edit" state="None" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<ui5-avatar icon="product" size="M" color-scheme="Accent10">
<ui5-avatar-badge icon="sys-enter-2" state="Positive" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<ui5-avatar icon="supplier" size="M" color-scheme="Accent9">
<ui5-avatar-badge icon="error" state="Negative" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<ui5-avatar icon="shipping-status" size="M" color-scheme="Accent4">
<ui5-avatar-badge icon="alert" state="Critical" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<ui5-avatar icon="filter" size="M" color-scheme="Accent3">
<ui5-avatar-badge icon="information" state="Information" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<h3>Avatar Badge - Extended Color Palette (Avatar color-scheme / Badge color-scheme)</h3>
<div style="display: flex; flex-direction: row; flex-wrap: wrap; align-items: end; column-gap: 0.5rem; row-gap: 1rem;">
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="edit" color-scheme="1" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / colorScheme 1</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A2" size="M" color-scheme="Accent2">
<ui5-avatar-badge icon="edit" color-scheme="2" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent2 / colorScheme 2</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A3" size="M" color-scheme="Accent3">
<ui5-avatar-badge icon="edit" color-scheme="3" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent3 / colorScheme 3</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A4" size="M" color-scheme="Accent4">
<ui5-avatar-badge icon="edit" color-scheme="4" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent4 / colorScheme 4</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A5" size="M" color-scheme="Accent5">
<ui5-avatar-badge icon="edit" color-scheme="5" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent5 / colorScheme 5</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A6" size="M" color-scheme="Accent6">
<ui5-avatar-badge icon="edit" color-scheme="6" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent6 / colorScheme 6</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A7" size="M" color-scheme="Accent7">
<ui5-avatar-badge icon="edit" color-scheme="7" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent7 / colorScheme 7</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A8" size="M" color-scheme="Accent8">
<ui5-avatar-badge icon="edit" color-scheme="8" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent8 / colorScheme 8</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A9" size="M" color-scheme="Accent9">
<ui5-avatar-badge icon="edit" color-scheme="9" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent9 / colorScheme 9</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A10" size="M" color-scheme="Accent10">
<ui5-avatar-badge icon="edit" color-scheme="10" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent10 / colorScheme 10</p>
</div>
</div>
</section>

<section>
<h3>Avatar Badge - Extended Color Palette with Value State (Avatar color-scheme / Badge state)</h3>
<p>Semantic <code>state</code> takes precedence over <code>colorScheme</code>.</p>
<div style="display: flex; flex-direction: row; flex-wrap: wrap; align-items: end; column-gap: 0.5rem; row-gap: 1rem;">
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="edit" state="None" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / None</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="sys-enter-2" state="Positive" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / Positive</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="alert" state="Critical" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / Critical</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="error" state="Negative" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / Negative</p>
</div>
<div style="text-align: center;">
<ui5-avatar initials="A1" size="M" color-scheme="Accent1">
<ui5-avatar-badge icon="information" state="Information" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Accent1 / Information</p>
</div>
</div>
</section>

<section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ slug: ../../AvatarBadge

import Basic from "../../../_samples/main/AvatarBadge/Basic/Basic.md";
import ValueStates from "../../../_samples/main/AvatarBadge/ValueStates/ValueStates.md";
import ColorSchemes from "../../../_samples/main/AvatarBadge/ColorSchemes/ColorSchemes.md";

<%COMPONENT_OVERVIEW%>

Expand All @@ -18,3 +19,8 @@ import ValueStates from "../../../_samples/main/AvatarBadge/ValueStates/ValueSta
The AvatarBadge supports different states to indicate status or notifications.

<ValueStates />

### Extended Color Palette
The AvatarBadge supports an extended color palette via the `colorScheme` property. Use values `"1"` through `"10"` to apply indication colors — vivid background, border, and text tones drawn from the SAP indication color tokens, with a subtle box shadow to enhance visibility.

<ColorSchemes />
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import html from '!!raw-loader!./sample.html';
import js from '!!raw-loader!./main.js';
import react from '!!raw-loader!./sample.tsx';

<Editor html={html} js={js} react={react} />
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import "@ui5/webcomponents/dist/Avatar.js";
import "@ui5/webcomponents/dist/AvatarBadge.js";
// Icons
import "@ui5/webcomponents-icons/dist/employee.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!-- playground-fold -->
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample</title>
</head>

<body style="background-color: var(--sapBackgroundColor); display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
<!-- playground-fold-end -->

<ui5-avatar size="M" initials="A1">
<ui5-avatar-badge icon="employee" color-scheme="1" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A2">
<ui5-avatar-badge icon="employee" color-scheme="2" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A3">
<ui5-avatar-badge icon="employee" color-scheme="3" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A4">
<ui5-avatar-badge icon="employee" color-scheme="4" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A5">
<ui5-avatar-badge icon="employee" color-scheme="5" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A6">
<ui5-avatar-badge icon="employee" color-scheme="6" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A7">
<ui5-avatar-badge icon="employee" color-scheme="7" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A8">
<ui5-avatar-badge icon="employee" color-scheme="8" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A9">
<ui5-avatar-badge icon="employee" color-scheme="9" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar size="M" initials="A10">
<ui5-avatar-badge icon="employee" color-scheme="10" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<!-- playground-fold -->
<script type="module" src="main.js"></script>
</body>

</html>
<!-- playground-fold-end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import createReactComponent from "@ui5/webcomponents-base/dist/createReactComponent.js";
import AvatarClass from "@ui5/webcomponents/dist/Avatar.js";
import "@ui5/webcomponents-icons/dist/employee.js";
import AvatarBadgeClass from "@ui5/webcomponents/dist/AvatarBadge.js";

const Avatar = createReactComponent(AvatarClass);
const AvatarBadge = createReactComponent(AvatarBadgeClass);

const schemes = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] as const;

function App() {
return (
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '0.5rem' }}>
{schemes.map((scheme) => (
<Avatar key={scheme} size="M" initials={`A${scheme}`}>
<AvatarBadge icon="employee" colorScheme={scheme} slot="badge"></AvatarBadge>
</Avatar>
))}
</div>
);
}

export default App;
Loading