Skip to content

Commit

Permalink
refactor(Avatar): Refactor Avatar component to use CSS modules behind…
Browse files Browse the repository at this point in the history
… feature flag (#4885)

* Import postcsspresetprimer to storybook config

* Converting to CSS module

* Create tame-boats-hide.md

* Add testing in the feature flag

* Convert to require

* chore: Update postcss.config.js to use postcss-preset-primer

* convert to module

* Pass along className to StyledAvatar

* fix for lint

* Render boolean props with ''

* Adjust typescript stuff
  • Loading branch information
jonrohan authored Sep 11, 2024
1 parent f8749ee commit 373ce95
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 119 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-boats-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

Refactor Avatar component to use CSS modules behind feature flag
244 changes: 128 additions & 116 deletions e2e/components/Avatar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,139 +3,151 @@ import {visit} from '../test-helpers/storybook'
import {themes} from '../test-helpers/themes'

test.describe('Avatar', () => {
test.describe('Default', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar--default',
globals: {
colorScheme: theme,
},
})
for (const enabled of [true, false]) {
test.describe(`Feature flag enabled: ${enabled}`, () => {
test.describe('Default', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar--default',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Default.${theme}.png`)
})
// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Default.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar--default',
globals: {
colorScheme: theme,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar--default',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
})
})
})
})
}
})
}
})

test.describe('Size', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size',
globals: {
colorScheme: theme,
},
})
test.describe('Size', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Size.${theme}.png`)
})
// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Size.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size',
globals: {
colorScheme: theme,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
})
})
})
})
}
})
}
})

test.describe('Size Responsive', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size-responsive',
globals: {
colorScheme: theme,
},
})
test.describe('Size Responsive', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size-responsive',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Size Responsive.${theme}.png`)
})
// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Size Responsive.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size-responsive',
globals: {
colorScheme: theme,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--size-responsive',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
})
})
})
})
}
})
}
})

test.describe('Square', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--square',
globals: {
colorScheme: theme,
},
})
test.describe('Square', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--square',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Square.${theme}.png`)
})
// Default state
expect(await page.screenshot()).toMatchSnapshot(`Avatar.Square.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--square',
globals: {
colorScheme: theme,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-avatar-features--square',
globals: {
colorScheme: theme,
primer_react_css_modules_team: enabled,
},
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',
},
},
})
})
})
})
}
})
}
})
})
}
})
10 changes: 10 additions & 0 deletions packages/react/src/Avatar/Avatar.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ export default {

export const Square = () => <Avatar square alt="primer" src="https://avatars.githubusercontent.com/primer" />

export const SquareSxProp = () => (
<Avatar
square
sx={{border: '1px solid red'}}
size={40}
alt="primer"
src="https://avatars.githubusercontent.com/primer"
/>
)

export const Size = () => (
<div>
<Avatar size={4} alt="mona" src="https://avatars.githubusercontent.com/u/92997159?v=4" />
Expand Down
31 changes: 31 additions & 0 deletions packages/react/src/Avatar/Avatar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
:where(.Avatar) {
display: inline-block;
width: var(--avatarSize-regular);
height: var(--avatarSize-regular);
overflow: hidden; /* Ensure page layout in Firefox should images fail to load */
line-height: 1;
vertical-align: middle;
border-radius: 50%;
box-shadow: 0 0 0 1px var(--avatar-borderColor);

&:where([data-square]) {
border-radius: var(--borderRadius-medium);
}

&:where([data-responsive]) {
@media screen and (--viewportRange-narrow) {
width: var(--avatarSize-narrow);
height: var(--avatarSize-narrow);
}

@media screen and (--viewportRange-regular) {
width: var(--avatarSize-regular);
height: var(--avatarSize-regular);
}

@media screen and (--viewportRange-wide) {
width: var(--avatarSize-wide);
height: var(--avatarSize-wide);
}
}
}
Loading

0 comments on commit 373ce95

Please sign in to comment.