Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .changeset/clean-lions-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Update CounterLabel to use CSS Modules behind feature flag
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 68 additions & 57 deletions e2e/components/CounterLabel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,83 @@ import {test, expect} from '@playwright/test'
import {visit} from '../test-helpers/storybook'
import {themes} from '../test-helpers/themes'

test.describe('CounterLabel', () => {
test.describe('Default', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-counterlabel--default',
globals: {
colorScheme: theme,
},
})
const stories = [
{
title: 'Default',
id: 'components-counterlabel--default',
},
{
title: 'Primary Theme',
id: 'components-counterlabel-features--primary-theme',
},
{
title: 'Secondary Theme',
id: 'components-counterlabel-features--secondary-theme',
},
] as const

// Default state
expect(await page.screenshot()).toMatchSnapshot(`CounterLabel.Default.${theme}.png`)
})
test.describe('CounterLabel', () => {
for (const story of stories) {
test.describe(story.title, () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
featureFlags: {
primer_react_css_modules_team: true,
},
},
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-counterlabel--default',
globals: {
colorScheme: theme,
},
// Default state
expect(await page.screenshot()).toMatchSnapshot(`CounterLabel.${story.title}.${theme}.png`)
})
await expect(page).toHaveNoViolations({
rules: {
'color-contrast': {
enabled: theme !== 'dark_dimmed',

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

test.describe('Primary Theme', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-counterlabel-features--primary-theme',
globals: {
colorScheme: theme,
},
// Default state
expect(await page.screenshot()).toMatchSnapshot(`CounterLabel.${story.title}.${theme}.png`)
})

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

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

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()
})
})
})
}
})
}
})
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export default {
} as Meta<typeof CounterLabel>

export const PrimaryTheme: StoryFn<typeof CounterLabel> = () => <CounterLabel scheme="primary">12</CounterLabel>

export const SecondaryTheme: StoryFn<typeof CounterLabel> = () => <CounterLabel scheme="secondary">12</CounterLabel>
25 changes: 25 additions & 0 deletions packages/react/src/CounterLabel/CounterLabel.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.CounterLabel {
display: inline-block;
padding: var(--base-size-2) var(--base-size-6);
font-size: var(--text-body-size-small);
font-weight: var(--base-text-weight-semibold);
/* stylelint-disable-next-line primer/typography */
line-height: 1;
border: var(--borderWidth-thin) solid var(--counter-borderColor);
/* stylelint-disable-next-line primer/borders */
border-radius: 20px;

&[data-scheme='primary'] {
color: var(--fgColor-onEmphasis);
background-color: var(--bgColor-neutral-emphasis);
}

&[data-scheme='secondary'] {
color: var(--fgColor-default);
background-color: var(--bgColor-neutral-muted);
}

&:empty {
display: none;
}
}
16 changes: 15 additions & 1 deletion packages/react/src/CounterLabel/CounterLabel.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import React from 'react'
import type {StoryFn, Meta} from '@storybook/react'
import type {StoryFn, Meta, StoryObj} from '@storybook/react'
import CounterLabel from './CounterLabel'

export default {
title: 'Components/CounterLabel',
component: CounterLabel,
} as Meta<typeof CounterLabel>

export const Default: StoryFn<typeof CounterLabel> = () => <CounterLabel>12</CounterLabel>

export const Playground: StoryObj<typeof CounterLabel> = {
render: args => <CounterLabel {...args}>12</CounterLabel>,
args: {
scheme: 'primary',
},
argTypes: {
scheme: {
control: 'select',
options: ['primary', 'secondary'],
},
},
}
101 changes: 69 additions & 32 deletions packages/react/src/CounterLabel/CounterLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {clsx} from 'clsx'
import type {HTMLAttributes} from 'react'
import React, {forwardRef} from 'react'
import Box from '../Box'
import type {BetterSystemStyleObject, SxProp} from '../sx'
import {merge} from '../sx'
import VisuallyHidden from '../_VisuallyHidden'
import styled from 'styled-components'
import {get} from '../constants'
import sx from '../sx'
import type {SxProp} from '../sx'
import {VisuallyHidden} from '../VisuallyHidden'
import {defaultSxProp} from '../utils/defaultSxProp'
import {useFeatureFlag} from '../FeatureFlags'
import Box from '../Box'
import classes from './CounterLabel.module.css'

export type CounterLabelProps = React.PropsWithChildren<
HTMLAttributes<HTMLSpanElement> & {
Expand All @@ -14,42 +19,74 @@ export type CounterLabelProps = React.PropsWithChildren<
>

const CounterLabel = forwardRef<HTMLSpanElement, CounterLabelProps>(
({scheme = 'secondary', sx = defaultSxProp, children, className, ...props}, forwardedRef) => {
({scheme = 'secondary', sx = defaultSxProp, className, children, ...rest}, forwardedRef) => {
const enabled = useFeatureFlag('primer_react_css_modules_team')
const label = <VisuallyHidden>&nbsp;({children})</VisuallyHidden>
const counterProps = {
ref: forwardedRef,
['aria-hidden']: 'true' as const,
['data-scheme']: scheme,
...rest,
}

if (enabled) {
if (sx !== defaultSxProp) {
return (
<>
<Box as="span" {...counterProps} className={clsx(className, classes.CounterLabel)} sx={sx}>
{children}
</Box>
{label}
</>
)
}
return (
<>
<span {...counterProps} className={clsx(className, classes.CounterLabel)}>
{children}
</span>
{label}
</>
)
}

return (
<>
<Box
aria-hidden="true"
className={className}
sx={merge<BetterSystemStyleObject>(
{
display: 'inline-block',
padding: '2px 5px',
fontSize: 0,
fontWeight: 'bold',
lineHeight: 'condensedUltra',
borderRadius: '20px',
backgroundColor: scheme === 'primary' ? 'neutral.emphasis' : 'neutral.muted',
border:
'var(--borderWidth-thin,max(1px, 0.0625rem)) solid var(--counter-borderColor,var(--color-counter-border))',
color: scheme === 'primary' ? 'fg.onEmphasis' : 'fg.default',
'&:empty': {
display: 'none',
},
},
sx,
)}
{...props}
as="span"
ref={forwardedRef}
>
<StyledCounterLabel {...counterProps} className={className} sx={sx}>
{children}
</Box>
<VisuallyHidden>&nbsp;({children})</VisuallyHidden>
</StyledCounterLabel>
{label}
</>
)
},
)

const StyledCounterLabel = styled.span`
display: inline-block;
padding: var(--base-size-2, 0.125rem) var(--base-size-6, 0.375rem);
font-size: 12px;
font-weight: var(--base-text-weight-semibold, bold);
line-height: 1;
border-radius: 20px;
border: var(--borderWidth-thin, max(1px, 0.0625rem)) solid var(--counter-borderColor, var(--color-counter-border));

&[data-scheme='primary'] {
background-color: ${get('colors.neutral.emphasis')};
color: ${get('colors.fg.onEmphasis')};
}

&[data-scheme='secondary'] {
background-color: ${get('colors.neutral.muted')};
color: ${get('colors.fg.default')};
}

&:empty {
display: none;
}

${sx}
`

CounterLabel.displayName = 'CounterLabel'

export default CounterLabel
Loading