Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Button and ButtonLink ✨ #30

Merged
merged 15 commits into from
May 25, 2018
20 changes: 10 additions & 10 deletions docs/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html

Large diffs are not rendered by default.

14 changes: 5 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,20 @@
"version": "0.0.1",
"description": "Primer react components",
"repository": "primer/primer-react",
"scripts": {
"start": "x0 dev src/Index.js -op 8888",
"build": "x0 build src/Index.js --out-dir docs",
"test": "jest"
},
"keywords": [
"react",
"components",
"library",
"design-system"
],
"author": "GitHub, Inc.",
"contributors": [
"Diana Mounter <diana.mounter@gmail.com>",
"Shawn Allen <shawn.allen@github.com>"
],
"license": "MIT",
"main": "index.js",
"scripts": {
"start": "x0 dev src/Index.js -op 8888",
"build": "x0 build src/Index.js --out-dir docs",
"test": "jest"
},
"x0": {
"cssLibrary": "styled-components",
"basename": "/primer-react"
Expand Down
20 changes: 13 additions & 7 deletions src/Button.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import React from 'react'
import classnames from 'classnames'

const Button = props => (
const Button = ({ size, disabled, block, linkStyle, onClick, children }) => (
<button
{...props}
disabled={disabled}
onClick={onClick}
type="button"
className={classnames(
props.className,
'btn', {
'btn-sm': props.small,
'btn-large': props.large,
{
'btn': !linkStyle,
'btn-link': linkStyle,
'btn-sm': size === 'small',
'btn-large': size === 'large',
'btn-block': block,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know a lot of people like do this with buttons because it feels good to dry up the code, but I think it actually makes a simpler api to keep buttons separate around their theme. It does mean there are more components to know about, but it means there are fewer props to use with a single button component.

Instead of <Button primary block large/> you'd do <ButtonPrimary block large /> etc.

It also means we can be very intentional with which props we make available to which button themes. Later (which we will!) when we want to add new button variations or props (especially for marketing), we can be more deliberate and choose what props are available for each button. For example, we might never want to use an Octicon in a ButtonOutline or ButtonDanger but we do for primary and etc. (just using examples here).

I think there are definitely cases where we want color themes to be props such as for States, but buttons are pretty complex and we're likely to add onto this component.

}
)}
/>
>
{children}
</button>
)

export default Button
21 changes: 14 additions & 7 deletions src/ButtonDanger.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import React from 'react'
import classnames from 'classnames'

const ButtonDanger = props => (
const ButtonDanger = ({ size, disabled, block, linkStyle, onClick, children }) => (
<button
{...props}
disabled={disabled}
onClick={onClick}
type="button"
className={classnames(
props.className,
'btn btn-danger', {
'btn-sm': props.small,
'btn-large': props.large,
'btn-danger',
{
'btn': !linkStyle,
'btn-link': linkStyle,
'btn-sm': size === 'small',
'btn-large': size === 'large',
'btn-block': block,
}
)}
/>
>
{children}
</button>
)

export default ButtonDanger
24 changes: 24 additions & 0 deletions src/ButtonLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'
import classnames from 'classnames'

const ButtonLink = ({ size, type, block, href, children }) => (
<button
href={href}
role="button"
className={classnames(
'btn',
{
'btn-sm': size === 'small',
'btn-large': size === 'large',
'btn-primary': type === 'primary',
'btn-danger': type === 'danger',
'btn-outline': type === 'outline',
'btn-block': block,
}
)}
>
{children}
</button>
)

export default ButtonLink
24 changes: 24 additions & 0 deletions src/ButtonOutline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'
import classnames from 'classnames'

const ButtonOutline = ({ size, disabled, block, linkStyle, onClick, children }) => (
<button
disabled={disabled}
onClick={onClick}
type="button"
className={classnames(
'btn-outline',
{
'btn': !linkStyle,
'btn-link': linkStyle,
'btn-sm': size === 'small',
'btn-large': size === 'large',
'btn-block': block,
}
)}
>
{children}
</button>
)

export default ButtonOutline
21 changes: 14 additions & 7 deletions src/ButtonPrimary.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import React from 'react'
import classnames from 'classnames'

const ButtonPrimary = props => (
const ButtonPrimary = ({ size, disabled, block, linkStyle, onClick, children }) => (
<button
{...props}
disabled={disabled}
onClick={onClick}
type="button"
className={classnames(
props.className,
'btn btn-primary', {
'btn-sm': props.small,
'btn-large': props.large,
'btn-primary',
{
'btn': !linkStyle,
'btn-link': linkStyle,
'btn-sm': size === 'small',
'btn-large': size === 'large',
'btn-block': block,
}
)}
/>
>
{children}
</button>
)

export default ButtonPrimary
17 changes: 0 additions & 17 deletions src/ButtonSecondary.js

This file was deleted.

50 changes: 25 additions & 25 deletions src/Index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import Flex from './Flex'
import Heading from './Heading'
import Link from './Link'
import Button from './Button'
import ButtonDanger from './ButtonDanger'
import ButtonPrimary from './ButtonPrimary'
import ButtonOutline from './ButtonOutline'
import ButtonLink from './ButtonLink'
import theme from './theme'
import Text from './Text'
import ButtonPrimary from './ButtonPrimary'
import ButtonSecondary from './ButtonSecondary'
import ButtonDanger from './ButtonDanger'
import Flash from './Flash'
import CounterLabel from './CounterLabel'

Expand Down Expand Up @@ -61,32 +62,31 @@ const Index = props => (
</UtilityBox>
</Example>
<Example name='Button'>
<Button> Button </Button>
<Button onClick={() => window.alert('Clicked!')}> Button </Button>
</Example>
<Example name='ButtonPrimary'>
<ButtonPrimary>
button primary
</ButtonPrimary>
<Example name='Button - small'>
<Button size="small" onClick={() => window.alert('Clicked!')}> Button </Button>
</Example>
<Example name='ButtonSecondary'>
<ButtonSecondary>
button secondary
</ButtonSecondary>
<Example name='Button - large'>
<Button size="large" onClick={() => window.alert('Clicked!')}> Button </Button>
</Example>
<Example name='ButtonDanger'>
<ButtonDanger>
button danger
</ButtonDanger>
</Example>
<Example name='Button small'>
<ButtonSecondary small>
button small
</ButtonSecondary>
</Example>
<Example name='Button large'>
<ButtonSecondary large>
button large
</ButtonSecondary>
<ButtonDanger onClick={() => window.alert('Clicked!')}> Button </ButtonDanger>
</Example>
<Example name='ButtonPrimary'>
<ButtonPrimary onClick={() => window.alert('Clicked!')}> Button </ButtonPrimary>
</Example>
<Example name='ButtonOutline'>
<ButtonOutline onClick={() => window.alert('Clicked!')}> Button </ButtonOutline>
</Example>
<Example name='Button - full width'>
<Button block onClick={() => window.alert('Clicked!')}> Button </Button>
</Example>
<Example name='Button - styled as link'>
<Button linkStyle onClick={() => window.alert('Clicked!')}> Button </Button>
</Example>
<Example name='ButtonLink'>
<ButtonLink href="https://www.goatslive.com/">This is an {"<a>"} styled as a button</ButtonLink>
</Example>
<Example name='Flash themes'>
<ExampleBox>
Expand Down