diff --git a/addon/components/o-s-s/avatar.stories.js b/addon/components/o-s-s/avatar.stories.js
index 950b243d1..aa1de57da 100644
--- a/addon/components/o-s-s/avatar.stories.js
+++ b/addon/components/o-s-s/avatar.stories.js
@@ -1,6 +1,16 @@
import { hbs } from 'ember-cli-htmlbars';
const SizeTypes = ['xs', 'sm', 'md', 'lg'];
+const SkinType = [
+ 'danger',
+ 'xtd-orange',
+ 'xtd-violet-light',
+ 'xtd-violet',
+ 'xtd-lime',
+ 'primary',
+ 'primary-light',
+ 'xtd-cyan'
+];
export default {
title: 'Components/OSS::Avatar',
@@ -41,6 +51,17 @@ export default {
type: 'text'
}
},
+ skin: {
+ description: 'Adjust the skin of the avatar component',
+ table: {
+ type: {
+ summary: SkinType.join(' | ')
+ },
+ defaultValue: { summary: undefined }
+ },
+ options: [undefined, ...SkinType],
+ control: { type: 'select' }
+ },
loading: {
description: 'Display loading state',
table: {
@@ -70,12 +91,13 @@ const defaultArgs = {
size: 'md',
image: undefined,
initials: undefined,
- loading: false
+ loading: false,
+ skin: undefined
};
const Template = (args) => ({
template: hbs`
-
+
`,
context: args
});
diff --git a/addon/components/o-s-s/avatar.ts b/addon/components/o-s-s/avatar.ts
index 1ff489880..b02c93766 100644
--- a/addon/components/o-s-s/avatar.ts
+++ b/addon/components/o-s-s/avatar.ts
@@ -12,11 +12,25 @@ export const SizeDefinition: SizeDefType = {
lg: 'upf-avatar--lg'
};
+export const AvatarSkins = [
+ 'danger',
+ 'xtd-orange',
+ 'xtd-violet-light',
+ 'xtd-violet',
+ 'xtd-lime',
+ 'primary',
+ 'primary-light',
+ 'xtd-cyan'
+] as const;
+
+export type SkinType = (typeof AvatarSkins)[number];
+
export interface OSSAvatarArgs {
image?: string;
initials?: string;
size?: SizeType;
loading?: boolean;
+ skin?: SkinType;
}
export const DEFAULT_IMAGE_URL: string = '/@upfluence/oss-components/assets/images/avatar-placeholder.svg';
@@ -37,11 +51,19 @@ export default class OSSAvatar extends Component {
}
get computedClass(): string {
- let classes = 'upf-avatar ';
+ const classes = ['upf-avatar'];
const size: SizeType = this.args.size || 'md';
if (this.args.loading) {
- classes = classes.concat('upf-avatar--loading ');
+ classes.push('upf-avatar--loading');
+ }
+
+ if (this.args.skin) {
+ assert(
+ `[component][OSS::Avatar] Unknown skin. Available skins are: ${AvatarSkins.join(', ')}`,
+ AvatarSkins.includes(this.args.skin as SkinType)
+ );
+ classes.push('upf-avatar--skin', `upf-avatar--skin-${this.args.skin}`);
}
assert(
@@ -49,7 +71,8 @@ export default class OSSAvatar extends Component {
Object.keys(SizeDefinition).includes(size as SizeType)
);
- return classes.concat(SizeDefinition[size as SizeType]);
+ classes.push(SizeDefinition[size as SizeType])
+ return classes.join(' ')
}
@action
diff --git a/app/styles/atoms/avatar.less b/app/styles/atoms/avatar.less
index 705b81e45..81c49e15f 100644
--- a/app/styles/atoms/avatar.less
+++ b/app/styles/atoms/avatar.less
@@ -70,4 +70,41 @@
.upf-skeleton-effect;
.border-radius-round;
}
+
+ &--skin {
+ color: var(--color-white);
+ border: 1px solid var(--color-white);
+
+ &-danger {
+ background-color: var(--color-error-400);
+ }
+
+ &-xtd-orange {
+ background-color: var(--color-orange-400);
+ }
+
+ &-xtd-violet-light {
+ background-color: var(--color-violet-400);
+ }
+
+ &-xtd-violet {
+ background-color: var(--color-violet-500);
+ }
+
+ &-xtd-lime {
+ background-color: var(--color-lime-500);
+ }
+
+ &-primary {
+ background-color: var(--color-primary-400);
+ }
+
+ &-primary-light {
+ background-color: var(--color-primary-300);
+ }
+
+ &-xtd-cyan {
+ background-color: var(--color-cyan-500);
+ }
+ }
}
diff --git a/tests/dummy/app/templates/visual.hbs b/tests/dummy/app/templates/visual.hbs
index e6950b2e3..65f43cd82 100644
--- a/tests/dummy/app/templates/visual.hbs
+++ b/tests/dummy/app/templates/visual.hbs
@@ -385,6 +385,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/integration/components/o-s-s/avatar-test.ts b/tests/integration/components/o-s-s/avatar-test.ts
index 1339d2478..1590a3932 100644
--- a/tests/integration/components/o-s-s/avatar-test.ts
+++ b/tests/integration/components/o-s-s/avatar-test.ts
@@ -3,7 +3,7 @@ import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { find, render, setupOnerror, waitFor, waitUntil } from '@ember/test-helpers';
-import { SizeDefinition, DEFAULT_IMAGE_URL } from '@upfluence/oss-components/components/o-s-s/avatar';
+import { SizeDefinition, AvatarSkins, DEFAULT_IMAGE_URL } from '@upfluence/oss-components/components/o-s-s/avatar';
module('Integration | Component | o-s-s/avatar', function (hooks) {
setupRenderingTest(hooks);
@@ -63,6 +63,25 @@ module('Integration | Component | o-s-s/avatar', function (hooks) {
});
});
+ module('Skins', function () {
+ test('it sets no skin class when skin is not provided', async function (assert) {
+ await render(hbs``);
+
+ assert.dom('.upf-avatar').exists();
+ assert.dom('.upf-avatar').hasNoClass(`upf-avatar--skin`);
+ });
+
+ AvatarSkins.forEach((skin) => {
+ test(`it sets the right class when using a supported skin: ${skin}`, async function (assert) {
+ this.skin = skin;
+ await render(hbs``);
+
+ assert.dom('.upf-avatar').hasClass(`upf-avatar--skin`).hasClass(`upf-avatar--skin-${skin}`);
+ })
+ })
+
+ })
+
module('Sizes', function () {
test('it sets the right default class when size is not provided', async function (assert) {
await render(hbs``);
@@ -101,6 +120,17 @@ module('Integration | Component | o-s-s/avatar', function (hooks) {
await render(hbs``);
});
+ test('it throws an error if the wrong skin argument is passed', async function (assert: Assert) {
+ setupOnerror((err: Error) => {
+ assert.equal(
+ err.message,
+ `Assertion Failed: [component][OSS::Avatar] Unknown skin. Available skins are: ${AvatarSkins.join(', ')}`
+ );
+ });
+
+ await render(hbs``);
+ });
+
test('it displays the initials when both initials and image are provided and the image fails to load', async function (assert) {
await render(hbs``);
await waitFor('.upf-avatar span');