Skip to content

Commit

Permalink
refactor(Blankslate): add support for css modules to Blankslate (#4810)
Browse files Browse the repository at this point in the history
* test(e2e): add snapshots for Blankslate

* test(e2e): add support for feature flags in globals

* refactor(Blankslate): add support for css modules to Blankslate

* chore: remove local snapshots

* test(e2e): add fallback snapshots for styled-components

* chore: add changeset

* fix(stylelint): address stylelint errors

* chore: fix export size script

* chore: fix feature flag on action

* test(vrt): update snapshots

* test(vrt): update snapshots

* test(e2e): remove styled-components snapshots

* refactor(e2e): update snapshots to point to same image

---------

Co-authored-by: Josh Black <joshblack@users.noreply.github.com>
  • Loading branch information
joshblack and joshblack authored Aug 7, 2024
1 parent a6f6296 commit c0425ff
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-pans-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Update Blankslate component to use CSS Modules behind a feature flag
8 changes: 4 additions & 4 deletions .stylelintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
docs/public/**/*.css
lib-esm/**/*.css
lib/**/*.css
dist/**/*.css
.next/**/*.css
**/lib-esm/**/*.css
**/lib/**/*.css
**/dist/**/*.css
**/.next/**/*.css
55 changes: 54 additions & 1 deletion e2e/components/Blankslate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ test.describe('Blankslate', () => {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules: true,
},
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Blankslate.${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: false,
},
},
})

Expand All @@ -59,6 +77,19 @@ test.describe('Blankslate', () => {
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules: true,
},
},
})
await expect(page).toHaveNoViolations()
})

test('axe (styled-components) @aat', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
Expand All @@ -75,7 +106,29 @@ test.describe('Blankslate', () => {
test(`${name} @vrt`, async ({page}) => {
await visit(page, {
id: story.id,
globals: {},
globals: {
featureFlags: {
primer_react_css_modules: true,
},
},
})
const width = viewports[name]

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

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

Expand Down
37 changes: 34 additions & 3 deletions e2e/test-helpers/storybook.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type {Page} from '@playwright/test'
import {waitForImages} from './waitForImages'

type Value =
| string
| boolean
| number
| {
[Key: string]: Value
}

interface Options {
id: string
args?: Record<string, string | boolean>
globals?: Record<string, string>
globals?: Record<string, Value>
}

const {STORYBOOK_URL = 'http://localhost:6006'} = process.env
Expand All @@ -28,9 +36,13 @@ export async function visit(page: Page, options: Options) {
let params = ''
for (const [key, value] of Object.entries(globals)) {
if (params !== '') {
params += '&'
params += ';'
}
if (typeof value === 'object') {
params += serializeObject(value, key)
} else {
params += `${key}:${value}`
}
params += `${key}:${value}`
}
url.searchParams.set('globals', params)
}
Expand All @@ -46,3 +58,22 @@ export async function visit(page: Page, options: Options) {

await waitForImages(page)
}

function serializeObject<T extends {[Key: string]: Value}>(object: T, parentPath: string): string {
return Object.entries(object)
.map(([key, value]) => {
if (typeof value === 'object') {
return serializeObject(value, `${parentPath}.${key}`)
}
return `${parentPath}.${key}:${serialize(value)}`
})
.join(';')
}

function serialize(value: Value): string {
if (typeof value === 'boolean') {
return `!${value}`
}

return `${value}`
}
26 changes: 15 additions & 11 deletions packages/react/script/get-export-sizes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ const {rollup} = require('rollup')
const {minify} = require('terser')
const gzipSize = require('gzip-size')

const noopCSSModules = {
name: 'empty-css-modules',

transform(_code, id) {
if (!id.endsWith('.css')) {
return
}
return {
code: `export default {}`,
}
},
}

async function main() {
const rootDirectory = path.resolve(__dirname, '..')
const packageJsonPath = path.join(rootDirectory, 'package.json')
Expand Down Expand Up @@ -41,6 +54,7 @@ async function main() {
commonjs({
include: [/node_modules/],
}),
noopCSSModules,
],
onwarn: () => {},
})
Expand All @@ -63,17 +77,7 @@ async function main() {
commonjs({
include: /node_modules/,
}),
{
name: 'empty-css-modules',
transform(_code, id) {
if (!id.endsWith('.css')) {
return
}
return {
code: `export default {}`,
}
},
},
noopCSSModules,
virtual({
__entrypoint__: `export { ${identifier} } from '${filepath}';`,
}),
Expand Down
109 changes: 109 additions & 0 deletions packages/react/src/Blankslate/Blankslate.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.Container {
container: blankslate / inline-size;
}

.Blankslate {
--blankslate-outer-padding-block: var(--base-size-32, 2rem);
--blankslate-outer-padding-inline: var(--base-size-32, 2rem);

display: grid;
justify-items: center;
/* stylelint-disable-next-line primer/spacing */
padding: var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);
}

.Blankslate[data-spacious='true'] {
--blankslate-outer-padding-block: var(--base-size-80, 5rem);
--blankslate-outer-padding-inline: var(--base-size-40, 2.5rem);
}

.Blankslate[data-border='true'] {
border: var(--borderWidth-thin) solid var(--borderColor-default);
border-radius: var(--borderRadius-medium);
}

.Blankslate[data-narrow='true'] {
max-width: 485px;
margin: 0 auto;
}

.Heading,
.Description {
margin: 0;
/* stylelint-disable-next-line primer/spacing */
margin-bottom: var(--stack-gap-condensed, var(--base-size-8));
}

.Heading {
font-size: var(--text-title-size-medium, 1.25rem);
font-weight: var(--text-title-weight-medium, 600);
}

.Description {
font-size: var(--text-body-size-large, 1rem);
line-height: var(--text-body-lineHeight-large, 1.5);
color: var(--fgColor-muted);
}

.Action {
/* stylelint-disable-next-line primer/spacing */
margin-top: var(--stack-gap-normal, var(--base-size-16));
}

.Action:first-of-type {
/* stylelint-disable-next-line primer/spacing */
margin-top: var(--stack-gap-spacious, var(--base-size-24));
}

.Action:last-of-type {
/* stylelint-disable-next-line primer/spacing */
margin-bottom: var(--stack-gap-condensed, var(--base-size-8));
}

/* At the time these styles were written, 34rem was our "small" breakpoint width */
/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
@container blankslate (max-width: 34rem) {
.Blankslate {
--blankslate-outer-padding-block: var(--base-size-20);
--blankslate-outer-padding-inline: var(--base-size-20);
}

.Blankslate[data-spacious='true'] {
--blankslate-outer-padding-block: var(--base-size-44);
--blankslate-outer-padding-inline: var(--base-size-28);
}

.Visual {
max-width: var(--base-size-24);
/* stylelint-disable-next-line primer/spacing */
margin-bottom: var(--stack-gap-condensed, var(--base-size-8));
}

/* stylelint-disable-next-line selector-max-type */
.Visual svg {
width: 100%;
}

.Heading {
font-size: var(--text-title-size-small);
}

.Description {
font-size: var(--text-body-size-medium);
}

.Action {
/* stylelint-disable-next-line primer/spacing */
margin-top: var(--stack-gap-condensed, var(--base-size-8));
}

.Action:first-of-type {
/* stylelint-disable-next-line primer/spacing */
margin-top: var(--stack-gap-normal, var(--base-size-16));
}

.Action:last-of-type {
/* stylelint-disable-next-line primer/spacing */
margin-bottom: calc(var(--stack-gap-condensed, var(--base-size-8)) / 2);
}
}
Loading

0 comments on commit c0425ff

Please sign in to comment.