Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(avatar): DLT-1916 remove dt-icon from Avatar vue 2 #474

Merged
merged 15 commits into from
Sep 6, 2024
Merged
96 changes: 75 additions & 21 deletions apps/dialtone-documentation/docs/components/avatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@ figma_url: https://www.figma.com/file/2adf7JhZOncRyjYiy2joil/DT-Core%3A-Componen
---

<code-well-header>
<div class="d-d-flex d-ai-center d-flow16">
<dt-avatar size="lg" icon-name="user" icon-size="500" />
<dt-avatar size="lg" full-name="dp" color="1000" presence="busy" />
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" presence="active" />
</div>
<div class="d-d-flex d-ai-center d-flow16">
<dt-avatar size="lg">
<template #icon>
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
<dt-icon name="user" />
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
</template>
</dt-avatar>
<dt-avatar size="lg" full-name="dp" color="1000" presence="busy" />
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" presence="active" />
</div>
</code-well-header>

<!-- <component-combinator component-name="DtAvatar" /> -->

## Usage

The Avatar component is designed to prioritize different sources for content display. It will sequentially check for the availability of an image source (`image-src`) or an icon name (`icon-name`). If both properties are not provided, the avatar will extract and display initials from the full name (`full-name`). The resulting initials are extracted using the following logic:
The Avatar component is designed to prioritize different sources for content display. It will sequentially check for the availability of an image source (`image-src`) or an icon slot. If both are not provided, the avatar will extract and display initials from the full name (`full-name`). The resulting initials are extracted using the following logic:
ninamarina marked this conversation as resolved.
Show resolved Hide resolved

* If the string contains two or more words, the result will be the first character of the first and last word capitalized. E.g.:
`full-name: "Jaqueline Nackos"` will result in: `JN`.
Expand All @@ -45,7 +49,11 @@ The Avatar component is designed to prioritize different sources for content dis
<tbody>
<tr>
<td>
<dt-avatar icon-name="user" icon-size="400" />
<dt-avatar>
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
</template>
</dt-avatar>
</td>
<th class="d-ta-left"><a class="d-link" href="#icon">Icon</a></th>
<td>When no username can be associated with the Avatar.</td>
Expand Down Expand Up @@ -79,7 +87,11 @@ The Avatar component is designed to prioritize different sources for content dis
### Icon

<code-well-header>
<dt-avatar icon-name="user" icon-size="300" />
<dt-avatar>
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
</template>
</dt-avatar>
</code-well-header>

<code-example-tabs
Expand All @@ -92,9 +104,11 @@ htmlCode='
</div>
</div>'
vueCode='
<dt-avatar
icon-name="person"
/>
<dt-avatar>
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
'
/>

Expand Down Expand Up @@ -150,7 +164,11 @@ vueCode='

<code-well-header>
<div class="d-d-inline-flex d-ai-center d-flow8">
<dt-avatar v-for="size in sizes" :size="size" icon-name="user" />
<dt-avatar v-for="size in sizes" :size="size">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
</div>
</code-well-header>

Expand Down Expand Up @@ -183,11 +201,31 @@ htmlCode='
</div>
'
vueCode='
<dt-avatar size="xs" icon-name="user" />
<dt-avatar size="sm" icon-name="user" />
<dt-avatar size="md" icon-name="user" />
<dt-avatar size="lg" icon-name="user" />
<dt-avatar size="xl" icon-name="user" />
<dt-avatar size="xs">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
<dt-avatar size="sm" icon-name="user">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
<dt-avatar size="md" icon-name="user">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
<dt-avatar size="lg" icon-name="user">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
<dt-avatar size="xl" icon-name="user">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
'
/>

Expand Down Expand Up @@ -273,7 +311,11 @@ vueCode='

<code-well-header>
<div class="d-d-flex d-ai-center d-flow16">
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" overlay-icon="hear" />
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user">
<template #overlayIcon>
<dt-icon name="hear" />
</template>
</dt-avatar>
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" overlay-text="+3" />
</div>
</code-well-header>
Expand All @@ -295,7 +337,11 @@ htmlCode='
</div>
</div>'
vueCode='
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" overlay-icon="hear" />
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user">
<template #overlayIcon>
<dt-icon name="hear" />
</template>
</dt-avatar>
<dt-avatar size="lg" image-src="/assets/images/person.png" image-alt="avatar user" overlay-text="+3" />
'
/>
Expand All @@ -306,14 +352,22 @@ If you need to create a clickable avatar you can set the clickable prop. This wi

<code-well-header>
<div class="d-d-flex d-ai-center d-flow16">
<dt-avatar icon-name="user" clickable icon-aria-label="user" ref="example-clickable" />
<dt-avatar clickable icon-aria-label="user" ref="example-clickable">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
</div>
</code-well-header>

<code-example-tabs
:htmlCode="() => $refs['example-clickable']"
vueCode='
<dt-avatar icon-name="user" clickable icon-aria-label="user" />
<dt-avatar clickable icon-aria-label="user">
<template #icon="{ iconSize }">
<dt-icon name="user" :size="iconSize" />
</template>
</dt-avatar>
'
/>

Expand Down
Binary file added dialpad-dialtone-9.72.0.tgz
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
Binary file not shown.
14 changes: 11 additions & 3 deletions packages/dialtone-vue2/components/avatar/avatar.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createLocalVue, mount } from '@vue/test-utils';
import { DtIconUser } from '@dialpad/dialtone-icons/vue2';
import DtAvatar from './avatar.vue';
import { AVATAR_KIND_MODIFIERS, AVATAR_SIZE_MODIFIERS } from './avatar_constants';

Expand All @@ -9,7 +10,7 @@ const MOCK_INITIALS = 'JN';
const MOCK_SIZE = 'lg';
const MOCK_GROUP = 25;
const MOCK_CUSTOM_CLASS = 'my-custom-class';
const MOCK_ICON_SLOT = '<template #icon=>Icon</template>';
const MOCK_ICON_SLOT = '<dt-icon-user />';
let MOCK_ELEMENT = null;

const baseProps = {
Expand All @@ -28,18 +29,21 @@ describe('DtAvatar Tests', () => {
let image;
let count;
let presence;
let iconWrapper;

const updateWrapper = () => {
wrapper = mount(DtAvatar, {
propsData: { ...baseProps, ...mockProps },
listeners: { ...baseListeners, ...mockListeners },
localVue: testContext.localVue,
slots: { ...mockSlots },
components: { DtIconUser },
});

image = wrapper.find('[data-qa="dt-avatar-image"]');
count = wrapper.find('[data-qa="dt-avatar-count"]');
presence = wrapper.find('[data-qa="dt-presence"]');
iconWrapper = wrapper.find('[data-qa="dt-avatar-icon"]');
};

beforeAll(() => {
Expand Down Expand Up @@ -95,11 +99,15 @@ describe('DtAvatar Tests', () => {
});

it('icon should exist', () => {
expect(wrapper.find('[data-qa="dt-avatar-icon"]').exists()).toBeTruthy();
expect(iconWrapper.exists()).toBeTruthy();
});

it('should have correct class', () => {
expect(wrapper.find('[data-qa="dt-avatar-icon"]').classes(AVATAR_KIND_MODIFIERS.icon)).toBe(true);
expect(iconWrapper.classes(AVATAR_KIND_MODIFIERS.icon)).toBe(true);
});

it('should render the custom icon', () => {
expect(iconWrapper.findComponent(DtIconUser).exists()).toBe(true);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/* eslint-disable max-lines */
import { action } from '@storybook/addon-actions';
import { createRenderConfig } from '@/common/storybook_utils';
import { createRenderConfig, getIconNames } from '@/common/storybook_utils';
import DtRecipeContactInfo from './contact_info.vue';

import DtRecipeContactInfoDefaultTemplate from './contact_info_default.story.vue';
import DtRecipeContactInfoVariantsTemplate from './contact_info_variants.story.vue';
import { AVATAR_SIZE_MODIFIERS, AVATAR_COLORS } from '@/components/avatar';
import { PRESENCE_STATES_LIST } from '@/components/presence';
import { DtIconUser } from '@dialpad/dialtone-icons/vue2';

import avatarImage from '@/common/assets/avatar1.png';
const iconsList = getIconNames();

// Default Prop Values
export const argsData = {
Expand Down Expand Up @@ -39,7 +39,13 @@ export const argTypesData = {
},

avatarIcon: {
control: 'object',
options: iconsList,
control: {
type: 'select',
labels: {
undefined: '(empty)',
},
},
},

avatarColor: {
Expand Down Expand Up @@ -140,7 +146,7 @@ export const Default = {
render: (argsData) => createRenderConfig(DtRecipeContactInfo, DtRecipeContactInfoDefaultTemplate, argsData),

args: {
avatarIcon: DtIconUser,
avatarIcon: 'user',
avatarSrc: avatarImage,
avatarSeed: 'JL',
avatarFullName: 'Joseph Lumaban',
Expand Down Expand Up @@ -205,6 +211,7 @@ export const Variants = {
render: (argsData) => createRenderConfig(DtRecipeContactInfo, DtRecipeContactInfoVariantsTemplate, argsData),

args: {
avatarIcon: 'user',
avatarFullName: 'Natalie Woods',
avatarSeed: 'NW',
avatarSize: 'lg',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@
:avatar-class="[{ 'd-mln24': index > 0, 'd-bc-brand': !!avatar.halo }]"
>
<template
v-if="avatarIcon"
v-if="hasAvatarIcon"
ninamarina marked this conversation as resolved.
Show resolved Hide resolved
#icon="{ iconSize }"
>
<component
:is="avatarIcon"
:size="iconSize"
/>
<!-- @slot Slot for avatar icon in a list -->
<slot name="avatarIcon" :icon-size="iconSize" />
</template>
<template
v-if="avatar.icon"
Expand All @@ -57,13 +55,11 @@
:presence="presence"
>
<template
v-if="avatarIcon"
v-if="hasAvatarIcon"
#icon="{ iconSize }"
>
<component
:is="avatarIcon"
:size="iconSize"
/>
<!-- @slot Slot for avatar icon in a list -->
<slot name="avatarIcon" :icon-size="iconSize" />
</template>
</dt-avatar>
</button>
Expand Down Expand Up @@ -164,14 +160,6 @@ export default {
default: '',
},
/**
* Avatar icon to display if `avatarSrc` is empty.
*/
avatarIcon: {
type: Object,
default: null,
},
/**
* The size of the avatar
* @values xs, sm, md, lg, xl
Expand Down Expand Up @@ -227,6 +215,12 @@ export default {
emits: ['avatar-click'],
computed: {
hasAvatarIcon () {
return this.$scopedSlots.avatarIcon && this.$scopedSlots.avatarIcon();
},
},
methods: {
avatarClick () {
this.$emit('avatar-click');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
:avatar-src="$attrs.avatarSrc"
:avatar-full-name="$attrs.avatarFullName"
:avatar-labelledby="$attrs.avatarLabelledby"
:avatar-icon="$attrs.avatarIcon"
:avatar-size="$attrs.avatarSize"
:avatar-seed="$attrs.avatarSeed"
:avatar-color="$attrs.avatarColor"
Expand All @@ -18,6 +17,16 @@
<span v-html="$attrs.header" />
</template>

<template
#avatarIcon="{ iconSize }"
>
<dt-icon
v-if="$attrs.avatarIcon"
:name="$attrs.avatarIcon"
:size="iconSize"
/>
</template>

<template
v-if="$attrs.subtitle"
#subtitle
Expand All @@ -43,9 +52,10 @@

<script>
import DtRecipeContactInfo from './contact_info.vue';
import { DtIcon } from '@/components/icon';
export default {
name: 'DtRecipeContactInfoDefault',
components: { DtRecipeContactInfo },
components: { DtRecipeContactInfo, DtIcon },
};
</script>
Loading
Loading