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
9 changes: 8 additions & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ const preview: Preview = {
options: {
storySort: {
method: 'alphabetical',
order: ['Reactist', 'Design tokens', 'Design system', 'Hooks', 'Components'],
order: [
'Reactist',
'Design tokens',
'Design system',
'Hooks',
'Components',
'Deprecated Components',
],
},
},
chromatic: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`DeprecatedAvatar renders a background image when avatarUrl is supplied 1`] = `
<div
class="deprecated-avatar deprecated-size-xl box"
data-testid="avatar"
style="background-image: url(https://foo.bar/com.png); text-indent: -9999px;"
>
HM
</div>
`;
128 changes: 128 additions & 0 deletions src/deprecated-avatar/deprecated-avatar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
:root {
--reactist-deprecated-avatar-size-xxsmall: 16px;
--reactist-deprecated-avatar-size-xsmall: 20px;
--reactist-deprecated-avatar-size-small: 30px;
--reactist-deprecated-avatar-size-medium: 32px;
--reactist-deprecated-avatar-size-large: 34px;
--reactist-deprecated-avatar-size-xlarge: 48px;
--reactist-deprecated-avatar-size-xxlarge: 70px;
--reactist-deprecated-avatar-size-xxxlarge: 100px;

--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-large);
}

.deprecated-avatar {
flex-shrink: 0;
background-position: center;
color: white;
text-align: center;
border-radius: 50%;

width: var(--reactist-deprecated-avatar-size);
height: var(--reactist-deprecated-avatar-size);
line-height: var(--reactist-deprecated-avatar-size);
background-size: var(--reactist-deprecated-avatar-size);
font-size: calc(var(--reactist-deprecated-avatar-size) / 2);
}

.deprecated-size-xxs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxsmall);
}

.deprecated-size-xs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xsmall);
}

.deprecated-size-s {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-small);
}

.deprecated-size-m {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-medium);
}

.deprecated-size-l {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-large);
}

.deprecated-size-xl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xlarge);
}

.deprecated-size-xxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxlarge);
}

.deprecated-size-xxxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxxlarge);
}

/* avatar size for tablet */
@media (min-width: 768px /* --reactist-breakpoint-tablet */) {
.tablet-deprecated-size-xxs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxsmall);
}

.tablet-deprecated-size-xs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xsmall);
}

.tablet-deprecated-size-s {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-small);
}

.tablet-deprecated-size-m {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-medium);
}

.tablet-deprecated-size-l {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-large);
}

.tablet-deprecated-size-xl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xlarge);
}

.tablet-deprecated-size-xxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxlarge);
}

.tablet-deprecated-size-xxxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxxlarge);
}
}

/* avatar size for desktop */
@media (min-width: 992px /* --reactist-breakpoint-desktop */) {
.desktop-deprecated-size-xxs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxsmall);
}

.desktop-deprecated-size-xs {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xsmall);
}

.desktop-deprecated-size-s {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-small);
}

.desktop-deprecated-size-m {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-medium);
}

.desktop-deprecated-size-l {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-large);
}

.desktop-deprecated-size-xl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xlarge);
}

.desktop-deprecated-size-xxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxlarge);
}

.desktop-deprecated-size-xxxl {
--reactist-deprecated-avatar-size: var(--reactist-deprecated-avatar-size-xxxlarge);
}
}
155 changes: 155 additions & 0 deletions src/deprecated-avatar/deprecated-avatar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import '../../stories/components/styles/avatar_story.css'

import * as React from 'react'

import { Box, DeprecatedAvatar, Inline } from '../index'

export default {
title: 'Deprecated Components/Avatar',
component: DeprecatedAvatar,
parameters: {
badges: ['deprecated'],
},
}

const exampleData = [
{
size: 'xxs',
user: { name: 'Henning Mu', email: 'henning@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'xs',
user: { name: 'Joao Va', email: 'joao@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 's',
user: { name: 'Amir Sa', email: 'amir@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'm',
user: { name: 'Alex Mu', email: 'alex@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'l',
user: { name: 'Julia', email: 'julia@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'xl',
user: { name: 'Janusz Gr', email: 'janusz@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'xxl',
user: { name: 'Jaime Az', email: 'jaime@foo.com' },
image: 'https://loremflickr.com/320/320',
},
{
size: 'xxxl',
user: { name: 'Igor Kh', email: 'igor@foo.com' },
image: 'https://loremflickr.com/320/320',
},
] as const

type DeprecatedAvatarPlaygroundArgs = {
size: React.ComponentProps<typeof DeprecatedAvatar>['size']
avatarUrl: string
userName: string
email: string
}

export const InitialsAvatarStory = () => (
<Inline space="small">
{exampleData.map((data, index) => (
<DeprecatedAvatar key={index} size={data.size} user={data.user} />
))}
</Inline>
)

export const CustomColorAvatarStory = () => (
<Inline space="small">
{exampleData.map((data, index) => (
<DeprecatedAvatar
colorList={['palevioletred', 'palegoldenrod', 'palegreen', 'paleturquoise']}
key={index}
size={data.size}
user={data.user}
/>
))}
</Inline>
)

export const PictureAvatarStory = () => (
<Inline space="small">
{exampleData.map((data, index) => (
<DeprecatedAvatar
key={index}
size={data.size}
user={data.user}
avatarUrl={data.image}
/>
))}
</Inline>
)

export const AvatarPlaygroundStory = (args: DeprecatedAvatarPlaygroundArgs) => {
return (
<Box className="story Avatar">
<DeprecatedAvatar
{...args}
user={{
name: args.userName,
email: args.email,
}}
/>
</Box>
)
}

AvatarPlaygroundStory.args = {
size: 'l',
avatarUrl: 'https://loremflickr.com/320/320',
userName: '',
email: '',
}

AvatarPlaygroundStory.argTypes = {
size: {
type: 'select',
options: ['xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl', 'xxxl'],
},
avatarUrl: {
control: {
type: 'text',
},
},
userName: {
control: {
type: 'text',
},
},
email: {
control: {
type: 'text',
},
},
className: {
control: {
type: null,
},
},
user: {
control: {
type: null,
},
},
colorList: {
control: {
type: null,
},
},
}
64 changes: 64 additions & 0 deletions src/deprecated-avatar/deprecated-avatar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as React from 'react'

import { render, screen } from '@testing-library/react'

import { DeprecatedAvatar } from './deprecated-avatar'

describe('DeprecatedAvatar', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 P2 This suite never exercises the restored colorList prop, even though preserving that legacy API is one of the goals of this PR. Please add a case that passes a custom list and asserts the resulting backgroundColor, otherwise a regression here will slip through while the initials-only tests still pass.

it('renders a background image when avatarUrl is supplied', () => {
render(getAvatar({ avatarUrl: 'https://foo.bar/com.png' }))

const avatar = screen.getByTestId('avatar')

expect(avatar).toMatchSnapshot()
})

it('renders initials of user name when avatarUrl is not supplied', () => {
render(getAvatar())

const avatar = screen.getByTestId('avatar')

expect(avatar).toHaveTextContent('HM')
})

it('renders initials of user email when avatarUrl is not supplied', () => {
render(getAvatar({ user: { email: 'henning@doist.com' } }))

const avatar = screen.getByTestId('avatar')

expect(avatar).toHaveTextContent('H')
})

it('supports responsive values', () => {
render(
getAvatar({
size: {
mobile: 's',
desktop: 'xl',
tablet: 'xxl',
},
}),
)
const avatar = screen.getByTestId('avatar')

expect(avatar).toHaveClass('deprecated-size-s')
expect(avatar).toHaveClass('desktop-deprecated-size-xl')
expect(avatar).toHaveClass('tablet-deprecated-size-xxl')
})

// Helpers ================================================================
function getAvatar(
props?: Omit<React.ComponentProps<typeof DeprecatedAvatar>, 'user'> & {
user?: { name?: string; email: string }
},
) {
return (
<DeprecatedAvatar
data-testid="avatar"
user={{ name: 'Henning Mus', email: 'henning@doist.com' }}
size="xl"
{...props}
/>
)
}
})
Loading
Loading