Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

Commit

Permalink
feat(button): adding disabled prop to Button (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandru Buliga authored Jul 31, 2018
1 parent 48d735a commit c7b7621
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Features
- Add Icon `xSpacing` prop @Bugaa92 ([#22](https://github.com/stardust-ui/react/pull/22))
- Add Button `icon` prop and Text `truncated` prop @Bugaa92 ([#13](https://github.com/stardust-ui/react/pull/13))
- Add Button `disabled` prop @Bugaa92 ([#14](https://github.com/stardust-ui/react/pull/14))

<!--------------------------------[ v0.2.3 ]------------------------------- -->
## [v0.2.3](https://github.com/stardust-ui/react/tree/v0.2.3) (2018-07-24)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import { Button } from '@stardust-ui/react'

const ButtonExampleDisabled = () => (
<div>
<Button disabled content="Default" />
<Button disabled type="primary" content="Primary" />
<Button disabled type="secondary" content="Secondary" />
<Button disabled type="primary" icon="book" content="Click me" iconPosition="before" />
<Button disabled circular icon="coffee" />
<br />
<br />
<Button disabled fluid content="Fluid" />
</div>
)

export default ButtonExampleDisabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { Button, Icon, Text } from '@stardust-ui/react'

const ButtonExampleDisabled = () => (
<div>
<Button disabled>Default</Button>
<Button disabled type="primary">
Primary
</Button>
<Button disabled type="secondary">
Secondary
</Button>
<Button disabled type="primary" icon iconPosition="before">
<Icon name="book" color="white" xSpacing="after" />
<Text content="Click me" />
</Button>
<Button disabled circular>
<Icon name="coffee" xSpacing="none" />
</Button>
<br />
<br />
<Button disabled fluid>
Fluid
</Button>
</div>
)

export default ButtonExampleDisabled
15 changes: 15 additions & 0 deletions docs/src/examples/components/Button/States/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const States = () => (
<ExampleSection title="States">
<ComponentExample
title="Disabled"
description="A button can show it is currently unable to be interacted with."
examplePath="components/Button/States/ButtonExampleDisabled"
/>
</ExampleSection>
)

export default States
2 changes: 2 additions & 0 deletions docs/src/examples/components/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react'
import Types from './Types'
import Variations from './Variations'
import States from './States'

const ButtonExamples = () => (
<div>
<Types />
<States />
<Variations />
</div>
)
Expand Down
38 changes: 35 additions & 3 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React, { ReactNode, CSSProperties } from 'react'
import React, { ReactNode, CSSProperties, SyntheticEvent } from 'react'

import { UIComponent, childrenExist, customPropTypes, IRenderResultConfig } from '../../lib'
import buttonRules from './buttonRules'
Expand All @@ -16,9 +16,11 @@ export interface IButtonProps {
circular?: boolean
className?: string
content?: ReactNode
disabled?: boolean
fluid?: boolean
icon?: boolean | string
iconPosition?: IconPosition
onClick?: (e: SyntheticEvent, props: IButtonProps) => void
style?: CSSProperties
type?: ButtonType
}
Expand Down Expand Up @@ -50,6 +52,9 @@ class Button extends UIComponent<IButtonProps, any> {
/** Additional classes. */
className: PropTypes.string,

/** A button can show it is currently unable to be interacted with. */
disabled: PropTypes.bool,

/** Shorthand for primary content. */
content: customPropTypes.contentShorthand,

Expand All @@ -62,6 +67,13 @@ class Button extends UIComponent<IButtonProps, any> {
/** An icon button can format an Icon to appear before or after the button */
iconPosition: PropTypes.oneOf(['before', 'after']),

/**
* Called after user's click.
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onClick: PropTypes.func,

/** A button can be formatted to show different levels of emphasis. */
type: PropTypes.oneOf(['primary', 'secondary']),
}
Expand All @@ -72,9 +84,11 @@ class Button extends UIComponent<IButtonProps, any> {
'circular',
'className',
'content',
'disabled',
'fluid',
'icon',
'iconPosition',
'onClick',
'type',
]

Expand All @@ -87,7 +101,7 @@ class Button extends UIComponent<IButtonProps, any> {
classes,
rest,
}: IRenderResultConfig<IButtonProps>): ReactNode {
const { children, content, icon, iconPosition, type } = this.props
const { children, content, disabled, icon, iconPosition, type } = this.props
const primary = type === 'primary'

const getContent = (): ReactNode => {
Expand All @@ -113,11 +127,29 @@ class Button extends UIComponent<IButtonProps, any> {
}

return (
<ElementType {...rest} className={classes.root}>
<ElementType
className={classes.root}
disabled={disabled}
onClick={this.handleClick}
{...rest}
>
{getContent()}
</ElementType>
)
}

private handleClick = (e: SyntheticEvent) => {
const { onClick, disabled } = this.props

if (disabled) {
e.preventDefault()
return
}

if (onClick) {
onClick(e, this.props)
}
}
}

export default Button
29 changes: 21 additions & 8 deletions src/components/Button/buttonRules.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { pxToRem } from '../../lib'
import { truncateStyle } from '../../styles/customCSS'
import { disabledStyle, truncateStyle } from '../../styles/customCSS'
import { IButtonVariables } from './buttonVariables'
import { IButtonProps } from './Button'

export default {
root: ({ props, variables }: { props: IButtonProps; variables: IButtonVariables }) => {
const { circular, fluid, icon, iconPosition, type } = props
const { circular, disabled, fluid, icon, iconPosition, type } = props
const primary = type === 'primary'
const secondary = type === 'secondary'

Expand All @@ -27,7 +27,7 @@ export default {
typeSecondaryBorderColor,
} = variables

return {
const rules = {
height,
minWidth,
maxWidth,
Expand All @@ -37,12 +37,8 @@ export default {
padding: `0 ${pxToRem(paddingLeftRightValue)}`,
margin: `0 ${pxToRem(8)} 0 0`,
verticalAlign: 'middle',
cursor: 'pointer',
borderWidth: `${secondary ? (circular ? 1 : 2) : 0}px`,
borderRadius: pxToRem(2),
':hover': {
backgroundColor: backgroundColorHover,
},
borderWidth: 0,

...truncateStyle,

Expand All @@ -67,6 +63,23 @@ export default {
width: '100%',
maxWidth: '100%',
}),
}

if (disabled) {
return {
...rules,
...disabledStyle,
}
}

return {
...rules,

borderWidth: `${secondary ? (circular ? 1 : 2) : 0}px`,
cursor: 'pointer',
':hover': {
backgroundColor: backgroundColorHover,
},

...(primary && {
color: typePrimaryColor,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/buttonVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default (siteVars: any): IButtonVariables => {
maxWidth: pxToRem(280),
backgroundColor: siteVars.gray08,
backgroundColorHover: siteVars.gray06,
paddingLeftRightValue: 20,
circularRadius: pxToRem(999),
paddingLeftRightValue: 20,
typePrimaryColor: siteVars.white,
typePrimaryBackgroundColor: siteVars.brand,
typePrimaryBackgroundColorHover: siteVars.brand04,
Expand Down
12 changes: 11 additions & 1 deletion test/specs/components/Button/Button-test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'

import { isConformant } from 'test/specs/commonTests'
import { getTestingRenderedComponent } from 'test/utils'
import { getTestingRenderedComponent, mountWithProvider } from 'test/utils'

import Button from 'src/components/Button/Button'

Expand Down Expand Up @@ -47,4 +47,14 @@ describe('Button', () => {
expect(btnCircular).toEqual(true)
})
})

describe('onClick', () => {
it('does not call onClick when the button is disabled', () => {
const onClick = jest.fn()
const button = mountWithProvider(<Button disabled onClick={onClick} />).find('Button')
button.simulate('click')

expect(onClick).not.toHaveBeenCalled()
})
})
})

0 comments on commit c7b7621

Please sign in to comment.