Skip to content

Commit

Permalink
Merge pull request #26 from fyndiq/button-link
Browse files Browse the repository at this point in the history
Button link
  • Loading branch information
thibautRe authored Sep 18, 2017
2 parents 1e8a097 + 194d5ad commit fd542b5
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 59 deletions.
13 changes: 13 additions & 0 deletions packages/fyndiq-component-button/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ import Button from 'fyndiq-component-button'

// Disabled usage
<Button disabled>My disabled Button</Button>

// Render a link as a button
<Button link="#hello">My link</Button>

// Use a custom Link element
import { Link } from 'react-router-dom'
<Button
link={<Link to="my/path" />}
>
My link
</Button>
```

# API
Expand All @@ -50,7 +61,9 @@ The component `Button` has the following customizable props:
| Name | Type | Description | Default value |
|---|---|---|---|
| **type** | String | One of `primary`, `cancel`, `blue`, `inverted`. Changes the color style of the button | `normal` |
| **htmlType** | String | Set the original html type for `button`. See: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | `undefined` |
| **size** | String | One of `xs`, `s`, `l`, `xl`. Changes the size of the button | `m` |
| **disabled** | Boolean | If true, will disable the button. | `false` |
| **pressed** | Boolean | Show the button as pressed | `false` |
| **link** | String or Element | Uses an `<a>` tag or a custom element to render the button | `undefined` |
| **onClick** | Function | Callback when the button is pressed | `noop => noop` |
3 changes: 2 additions & 1 deletion packages/fyndiq-component-button/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"fyndiq-styles-colors": "^1.1.1"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0"
"prop-types": "^15.0.0",
"react": "^15.0.0"
}
}
135 changes: 93 additions & 42 deletions packages/fyndiq-component-button/src/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`fyndiq-component-button should be renderable as a custom link element 1`] = `
<Link
className="
button
type-normal
size-s
false
false
interactive
"
to="my/path"
>
Hello
</Link>
`;

exports[`fyndiq-component-button should be renderable as a link 1`] = `
<a
className="
button
type-normal
size-s
false
false
interactive
"
href="#hello"
onClick={[Function]}
>
Hello
</a>
`;

exports[`fyndiq-component-button should be rendered without props 1`] = `
<button
className="
button
type-normal
size-s
false
false
interactive
"
button
type-normal
size-s
false
false
interactive
"
disabled={false}
onClick={[Function]}
>
Expand All @@ -20,13 +53,13 @@ exports[`fyndiq-component-button should be rendered without props 1`] = `
exports[`fyndiq-component-button should have a disabled prop 1`] = `
<button
className="
button
type-normal
size-s
false
false
disabled
"
button
type-normal
size-s
false
false
disabled
"
disabled={true}
onClick={[Function]}
>
Expand All @@ -37,15 +70,33 @@ exports[`fyndiq-component-button should have a disabled prop 1`] = `
exports[`fyndiq-component-button should have a horizontal prop 1`] = `
<button
className="
button
type-normal
size-s
horizontal
false
interactive
"
button
type-normal
size-s
horizontal
false
interactive
"
disabled={false}
onClick={[Function]}
>
Hello
</button>
`;

exports[`fyndiq-component-button should have a htmlType prop 1`] = `
<button
className="
button
type-normal
size-s
false
false
interactive
"
disabled={false}
onClick={[Function]}
type="submit"
>
Hello
</button>
Expand All @@ -54,13 +105,13 @@ exports[`fyndiq-component-button should have a horizontal prop 1`] = `
exports[`fyndiq-component-button should have a pressed prop 1`] = `
<button
className="
button
type-normal
size-s
false
pressed
interactive
"
button
type-normal
size-s
false
pressed
interactive
"
disabled={false}
onClick={[Function]}
>
Expand All @@ -71,13 +122,13 @@ exports[`fyndiq-component-button should have a pressed prop 1`] = `
exports[`fyndiq-component-button should have a size prop 1`] = `
<button
className="
button
type-normal
size-xs
false
false
interactive
"
button
type-normal
size-xs
false
false
interactive
"
disabled={false}
onClick={[Function]}
>
Expand All @@ -88,13 +139,13 @@ exports[`fyndiq-component-button should have a size prop 1`] = `
exports[`fyndiq-component-button should have a type prop 1`] = `
<button
className="
button
type-primary
size-s
false
false
interactive
"
button
type-primary
size-s
false
false
interactive
"
disabled={false}
onClick={[Function]}
>
Expand Down
80 changes: 64 additions & 16 deletions packages/fyndiq-component-button/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,63 @@ import React from 'react'
import PropTypes from 'prop-types'
import styles from '../styles.less'

const Button = ({ children, onClick, type, size, horizontal, disabled, pressed }) => (
<button
className={`
${styles.button}
${styles['type-' + type]}
${styles['size-' + size]}
${horizontal && styles.horizontal}
${pressed && styles.pressed}
${disabled ? styles.disabled : styles.interactive}
`}
onClick={onClick}
disabled={disabled}
>
{children}
</button>
)
const Button = ({
children,
onClick,
type,
size,
horizontal,
disabled,
pressed,
htmlType,
link,
}) => {
const className = `
${styles.button}
${styles['type-' + type]}
${styles['size-' + size]}
${horizontal && styles.horizontal}
${pressed && styles.pressed}
${disabled ? styles.disabled : styles.interactive}
`

// If the button is a link defined as a string,
// render the button as an <a> tag
if (typeof link === 'string') {
return (
<a
className={className}
onClick={onClick}
href={link}
>
{children}
</a>
)
// If the link is a React Element
// This case is usefull for integrating with react-router API
} else if (React.isValidElement(link)) {
return (
React.cloneElement(link, {
// Just pass the children and the className to the
// custom link element
className,
children,
})
)
}

// Default case: render a button.
return (
<button
className={className}
onClick={onClick}
disabled={disabled}
type={htmlType}
>
{children}
</button>
)
}

Button.propTypes = {
children: PropTypes.node.isRequired,
Expand All @@ -27,6 +68,11 @@ Button.propTypes = {
horizontal: PropTypes.bool,
disabled: PropTypes.bool,
pressed: PropTypes.bool,
htmlType: PropTypes.string,
link: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
]),
}

Button.defaultProps = {
Expand All @@ -36,6 +82,8 @@ Button.defaultProps = {
horizontal: false,
disabled: false,
pressed: false,
htmlType: undefined,
link: undefined,
}

export default Button
23 changes: 23 additions & 0 deletions packages/fyndiq-component-button/src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,29 @@ describe('fyndiq-component-button', () => {
expect(component).toMatchSnapshot()
})

test('should have a htmlType prop', () => {
const component = shallow(<Button htmlType="submit">Hello</Button>)
expect(component).toMatchSnapshot()
})

test('should be renderable as a link', () => {
const component = shallow(<Button link="#hello">Hello</Button>)
expect(component).toMatchSnapshot()
})

test('should be renderable as a custom link element', () => {
// Create Link element that follows react-router API
const Link = ({ to, children }) => (
<a href={to}>
{children}
</a>
)
const component = shallow(<Button link={<Link to="my/path" />}>
Hello
</Button>)
expect(component).toMatchSnapshot()
})

test('should call the onClick handler when clicked on', () => {
const clickSpy = jest.fn()
const component = shallow(<Button onClick={clickSpy}>Hello</Button>)
Expand Down
1 change: 1 addition & 0 deletions packages/fyndiq-component-button/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
background-color: @palegrey;
color: @black;
font-family: inherit;
text-decoration: none;

&:focus {
outline: 0;
Expand Down
3 changes: 3 additions & 0 deletions packages/fyndiq-ui-test/stories/component-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ storiesOf('Button', module)
.addWithInfo('disabled button', () => (
<Button disabled>Disabled Button</Button>
))
.addWithInfo('<a> tag', () => (
<Button link="#hello">I am a link</Button>
))

0 comments on commit fd542b5

Please sign in to comment.