Skip to content

Commit

Permalink
feat(Banner): update Banner to use CSS Modules behind feature flag (#…
Browse files Browse the repository at this point in the history
…4913)

* feat(Banner): update Banner to use CSS Modules behind feature flag

* chore: add changeset

* chore: remove autogenerated pnpm packageManager change

* chore: fix stylelint errors

* chore: add back in underline for fallback case

* refactor: update autofix and eslint warning

* chore: update class order for tests

* chore: fix stylelint errors

* Update packages/react/src/Banner/Banner.module.css

Co-authored-by: Katie Langerman <18661030+langermank@users.noreply.github.com>

---------

Co-authored-by: Josh Black <joshblack@users.noreply.github.com>
Co-authored-by: Katie Langerman <18661030+langermank@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 17, 2024
1 parent c8fe1c6 commit 6c9121e
Show file tree
Hide file tree
Showing 8 changed files with 507 additions and 143 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-rings-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Update Banner to use CSS Modules behind feature flag
57 changes: 57 additions & 0 deletions e2e/components/Banner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ test.describe('Banner', () => {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules_team: true,
},
},
})

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

test('default (styled-components) @vrt', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules_team: false,
},
},
})

Expand All @@ -89,6 +107,22 @@ test.describe('Banner', () => {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules_team: true,
},
},
})
await expect(page).toHaveNoViolations()
})

test('axe (styled-components) @aat', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules_team: false,
},
},
})
await expect(page).toHaveNoViolations()
Expand All @@ -101,6 +135,29 @@ test.describe('Banner', () => {
test(`${name} @vrt`, async ({page}) => {
await visit(page, {
id: story.id,
globals: {
featureFlags: {
primer_react_css_modules_team: true,
},
},
})
const width = viewports[name]

await page.setViewportSize({
width,
height: 667,
})
expect(await page.screenshot()).toMatchSnapshot(`Banner.${story.title}.${name}.png`)
})

test(`${name} (styled-components) @vrt`, async ({page}) => {
await visit(page, {
id: story.id,
globals: {
featureFlags: {
primer_react_css_modules_team: false,
},
},
})
const width = viewports[name]

Expand Down
5 changes: 5 additions & 0 deletions packages/react/src/Banner/Banner.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
"type": "string",
"description": "Provide an optional label to override the default name for the Banner landmark region"
},
{
"name": "className",
"type": "string",
"description": "Provide an optional className to add to the outermost element rendered by the Banner"
},
{
"name": "description",
"type": "React.ReactNode",
Expand Down
196 changes: 196 additions & 0 deletions packages/react/src/Banner/Banner.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
.Banner {
display: grid;
padding: var(--base-size-8);
background-color: var(--banner-bgColor);
border: var(--borderWidth-thin, 1px) solid var(--banner-borderColor);
border-radius: var(--borderRadius-medium);
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: start;

@supports (container-type: inline-size) {
container: banner / inline-size;
}

&[data-variant='critical'] {
--banner-bgColor: var(--bgColor-danger-muted);
--banner-borderColor: var(--borderColor-danger-muted);
--banner-icon-fgColor: var(--fgColor-danger);
}

&[data-variant='info'] {
--banner-bgColor: var(--bgColor-accent-muted);
--banner-borderColor: var(--borderColor-accent-muted);
--banner-icon-fgColor: var(--fgColor-accent);
}

&[data-variant='success'] {
--banner-bgColor: var(--bgColor-success-muted);
--banner-borderColor: var(--borderColor-success-muted);
--banner-icon-fgColor: var(--fgColor-success);
}

&[data-variant='upsell'] {
--banner-bgColor: var(--bgColor-upsell-muted);
--banner-borderColor: var(--borderColor-upsell-muted);
--banner-icon-fgColor: var(--fgColor-upsell);
}

&[data-variant='warning'] {
--banner-bgColor: var(--bgColor-attention-muted);
--banner-borderColor: var(--borderColor-attention-muted);
--banner-icon-fgColor: var(--fgColor-attention);
}
}

/* BannerContainer -------------------------------------------------------- */

.BannerContainer {
font-size: var(--text-body-size-medium);
align-items: start;
line-height: var(--text-body-lineHeight-medium);
row-gap: var(--base-size-4);
column-gap: var(--base-size-4);
}

.Banner :where(.BannerContainer) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.Banner[data-dismissible]:not([data-title-hidden='']) .BannerContainer {
display: grid;
grid-template-columns: auto;
grid-template-rows: auto;
}

/* BannerContent ---------------------------------------------------------- */

.BannerContent {
display: grid;
row-gap: var(--base-size-4);
grid-column-start: 1;
margin-block: var(--base-size-8);
}

.Banner[data-title-hidden] .BannerContent {
margin-block: var(--base-size-6);
}

@media screen and (min-width: 544px) {
.BannerContent {
flex: 1 1 0%;
}
}

.BannerTitle {
margin: 0;
font-size: inherit;
font-weight: var(--base-text-weight-semibold);
}

/* BannerIcon ------------------------------------------------------------- */

.BannerIcon {
display: grid;
place-items: center;
padding: var(--base-size-8);
}

.BannerIcon svg {
/* 20px is the line box height of the trailing action buttons */
height: var(--base-size-20);
color: var(--banner-icon-fgColor);
fill: var(--banner-icon-fgColor);
}

.Banner[data-title-hidden] .BannerIcon svg {
height: var(--base-size-16);
}

/* BannerDismiss ---------------------------------------------------------- */

.BannerDismiss {
display: grid;
place-items: center;
padding: var(--base-size-8);
margin-inline-start: var(--base-size-4);
}

.BannerDismiss svg {
color: var(--banner-icon-fgColor);
}

/* BannerActions ---------------------------------------------------------- */

.BannerActionsContainer {
display: flex;
column-gap: var(--base-size-12);
align-items: center;
}

.BannerActions :where([data-primary-action='trailing']) {
display: none;
}

@media screen and (--viewportRange-regular) {
.BannerActions :where([data-primary-action='trailing']) {
display: flex;
}

.BannerActions :where([data-primary-action='leading']) {
display: none;
}
}

.Banner[data-dismissible] .BannerActions {
margin-block-end: var(--base-size-6);
}

/* stylelint-disable-next-line selector-max-specificity */
.Banner[data-dismissible]:not([data-title-hidden]) .BannerActionsContainer[data-primary-action='trailing'] {
display: none;
}

/* stylelint-disable-next-line selector-max-specificity */
.Banner[data-dismissible]:not([data-title-hidden]) .BannerActionsContainer[data-primary-action='leading'] {
display: flex;
}

/* Layout ------------------------------------------------------------------- */

/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
@container banner (max-width: 500px) {
.BannerContainer {
display: grid;
grid-template-rows: auto auto;
}

.BannerActions {
margin-block-end: var(--base-size-6);
}

.BannerActions [data-primary-action='trailing'] {
display: none;
}

.BannerActions [data-primary-action='leading'] {
display: flex;
}
}

/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
@container banner (min-width: 500px) {
.BannerContainer {
display: grid;
grid-template-columns: auto auto;
}

.BannerActions [data-primary-action='trailing'] {
display: flex;
}

.BannerActions [data-primary-action='leading'] {
display: none;
}
}
5 changes: 5 additions & 0 deletions packages/react/src/Banner/Banner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ describe('Banner', () => {
expect(screen.getByRole('heading', {name: 'test'})).toBeInTheDocument()
})

it('should support a custom `className` on the outermost element', () => {
const {container} = render(<Banner title="test" className="test" />)
expect(container.firstChild).toHaveClass('test')
})

it('should label the landmark element with the corresponding variant label text', () => {
render(<Banner title="test" />)
expect(screen.getByRole('region')).toEqual(screen.getByLabelText('Information'))
Expand Down
Loading

0 comments on commit 6c9121e

Please sign in to comment.