Skip to content

Commit

Permalink
Sync Label component with PVC's Label component (#1797)
Browse files Browse the repository at this point in the history
* introduces new label component

* updates storybook stories and adds React docs for Label components

* adds tests

* uses hacky fix for rendering the correct Label component in the docs

* reduces scope of new label components

* rm StateLabel2

* fix React docs

* syncs Label styling with PVC/PCSS

* adds a changeset

* renames 'scheme' prop to 'variant'

* Update src/Label2.tsx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update src/Label2.tsx

Co-authored-by: Cole Bemis <colebemis@github.com>

* addresses more PR feedback

* Update docs/content/drafts/Label2.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/drafts/Label2.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update src/Label2.tsx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update src/Label2.tsx

Co-authored-by: Cole Bemis <colebemis@github.com>

* does not export Label as the default export of Label2.tsx

* Update docs/content/drafts/Label2.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* fix imports

* Update src/Label2.tsx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/drafts/Label2.mdx

Co-authored-by: Rez <rezrah@github.com>

* Update docs/content/drafts/Label2.mdx

Co-authored-by: Rez <rezrah@github.com>

* addresses more PR feedback

* revert package-lock to main

Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Rez <rezrah@github.com>
  • Loading branch information
3 people committed Jan 25, 2022
1 parent 8ff114b commit 8b376b9
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-badgers-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Introduces a draft for component to replace the existing Label component
102 changes: 102 additions & 0 deletions docs/content/drafts/Label2.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: Label v2
componentId: label2
status: Alpha
source: https://github.com/primer/react/tree/main/src/Label2
storybook: '/react/storybook?path=story/labels-label--label'
description: Use Label components to add contextual metadata to a design.
---

## Examples

### Basic

```javascript live noinline
// import {Label} from '@primer/react/drafts'
const {Label} = drafts // ignore docs silliness; import like that ↑

render(<Label>Default</Label>)
```

### Variants

```javascript live noinline
// import {Label} from '@primer/react/drafts'
const {Label} = drafts // ignore docs silliness; import like that ↑
render(
<>
<Label>Default</Label>
<Label variant="primary">Primary</Label>
<Label variant="secondary">Secondary</Label>
<Label variant="accent">Accent</Label>
<Label variant="success">Success</Label>
<Label variant="attention">Attention</Label>
<Label variant="severe">Severe</Label>
<Label variant="danger">Danger</Label>
<Label variant="done">Done</Label>
<Label variant="sponsors">Sponsors</Label>
</>
)
```

### Sizes

```javascript live noinline
// import {Label} from '@primer/react/drafts'
const {Label} = drafts // ignore docs silliness; import like that ↑
render(
<>
<Label>Small (default)</Label>
<Label size="large">Large</Label>
</>
)
```

## Props

### Label

<PropsTable>
<PropsTableRow
name="variant"
type={`| 'default'
| 'primary'
| 'secondary'
| 'accent'
| 'success'
| 'attention'
| 'severe'
| 'danger'
| 'done'
| 'sponsors'`}
defaultValue="'default'"
description="The color of the label"
/>
<PropsTableRow
name="size"
type="'small' | 'large'"
defaultValue="'small'"
description="How large the label is rendered"
/>
</PropsTable>

## Status

<ComponentChecklist
items={{
propsDocumented: true,
noUnnecessaryDeps: true,
adaptsToThemes: true,
adaptsToScreenSizes: true,
fullTestCoverage: true,
usedInProduction: false,
usageExamplesDocumented: true,
hasStorybookStories: true,
designReviewed: false,
a11yReviewed: false,
stableApi: false,
addressedApiFeedback: false,
hasDesignGuidelines: false,
hasFigmaComponent: false
}}
/>
98 changes: 98 additions & 0 deletions src/Label2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import styled from 'styled-components'
import {variant} from 'styled-system'
import sx, {SxProp, BetterSystemStyleObject} from './sx'
import {get} from './constants'

export type LabelProps = {
/** The color of the label */
variant?: LabelColorOptions
/** How large the label is rendered */
size?: LabelSizeKeys
} & SxProp

export type LabelColorOptions =
| 'default'
| 'primary'
| 'secondary'
| 'accent'
| 'success'
| 'attention'
| 'severe'
| 'danger'
| 'done'
| 'sponsors'

type LabelSizeKeys = 'small' | 'large'

export const variants: Record<LabelColorOptions, BetterSystemStyleObject> = {
default: {
borderColor: 'border.default'
},
primary: {
borderColor: 'fg.default'
},
secondary: {
borderColor: 'border.muted',
color: 'fg.muted'
},
accent: {
borderColor: 'accent.emphasis',
color: 'accent.fg'
},
success: {
borderColor: 'success.emphasis',
color: 'success.fg'
},
attention: {
borderColor: 'attention.emphasis',
color: 'attention.fg'
},
severe: {
borderColor: 'severe.emphasis',
color: 'severe.fg'
},
danger: {
borderColor: 'danger.emphasis',
color: 'danger.fg'
},
done: {
borderColor: 'done.fg',
color: 'done.emphasis'
},
sponsors: {
borderColor: 'sponsors.fg',
color: 'sponsors.emphasis'
}
}

const sizes: Record<LabelSizeKeys, BetterSystemStyleObject> = {
small: {
height: '20px',
padding: '0 7px' // hard-coded to align with Primer ViewCompnents and Primer CSS
},
large: {
height: '24px',
padding: '0 10px' // hard-coded to align with Primer ViewCompnents and Primer CSS
}
}

export const Label = styled.span<LabelProps>`
align-items: center;
background-color: transparent;
border-width: 1px;
border-radius: 999px;
border-style: solid;
display: inline-flex;
font-weight: ${get('fontWeights.bold')};
font-size: ${get('fontSizes.0')};
line-height: 1;
white-space: nowrap;
${variant({variants})};
${variant({prop: 'size', variants: sizes})};
${sx};
`

Label.defaultProps = {
size: 'small',
variant: 'default'
}
40 changes: 40 additions & 0 deletions src/__tests__/Label2.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import {render, cleanup} from '@testing-library/react'
import {axe, toHaveNoViolations} from 'jest-axe'
import 'babel-polyfill'
import {Label, variants, LabelColorOptions} from '../Label2'
import {renderStyles} from '../utils/testing'
expect.extend(toHaveNoViolations)

describe('Label2', () => {
it('renders text node child', () => {
const container = render(<Label>Default</Label>)
const label = container.baseElement
expect(label.textContent).toEqual('Default')
})
it('default size is rendered as "small"', () => {
const expectedStyles = {
height: '20px',
padding: '0 7px'
}
const defaultStyles = renderStyles(<Label />)

expect(defaultStyles).toEqual(expect.objectContaining(expectedStyles))
})
it('default variant is rendered as "default"', () => {
const expectedStyles = {
['border-color']: '#d0d7de'
}
const defaultStyles = renderStyles(<Label />)

expect(defaultStyles).toEqual(expect.objectContaining(expectedStyles))
})
it('should have no axe violations', async () => {
for (const variant in variants) {
const {container} = render(<Label variant={variant as LabelColorOptions}>Default</Label>)
const results = await axe(container)
expect(results).toHaveNoViolations()
cleanup()
}
})
})
1 change: 1 addition & 0 deletions src/drafts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './ActionList2'
export * from './Button2'
export * from './ActionMenu2'
export * from './DropdownMenu2'
export * from './Label2'
53 changes: 53 additions & 0 deletions src/stories/Label2.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react'
import {Meta} from '@storybook/react'
import {BaseStyles, ThemeProvider} from '..'
import {ComponentProps} from '../utils/types'
import {Label} from '../Label2'

type Args = ComponentProps<typeof Label>

export default {
// TODO: update story nesting
title: 'Labels/Label',
component: Label,
argTypes: {
variant: {
defaultValue: 'default',
control: {
options: [
'default',
'primary',
'secondary',
'accent',
'success',
'attention',
'severe',
'danger',
'done',
'sponsors'
],
type: 'select'
}
},
size: {
defaultValue: 'large',
control: {
options: ['small', 'large'],
type: 'radio'
}
}
},
decorators: [
Story => {
return (
<ThemeProvider>
<BaseStyles>
<Story />
</BaseStyles>
</ThemeProvider>
)
}
]
} as Meta

export const label = (args: Args) => <Label {...args}>Label</Label>

0 comments on commit 8b376b9

Please sign in to comment.