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

style(Button): update typings and propTypes usage #1216

Merged
merged 2 commits into from
Jan 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
127 changes: 57 additions & 70 deletions src/elements/Button/Button.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'lodash'
import cx from 'classnames'
import _ from 'lodash'
import React, { Component, PropTypes } from 'react'

import {
Expand All @@ -16,37 +16,14 @@ import {
} from '../../lib'
import Icon from '../Icon/Icon'
import Label from '../Label/Label'

import ButtonContent from './ButtonContent'
import ButtonGroup from './ButtonGroup'
import ButtonOr from './ButtonOr'

const debug = makeDebugger('button')

const _meta = {
name: 'Button',
type: META.TYPES.ELEMENT,
props: {
animated: ['fade', 'vertical'],
attached: ['left', 'right', 'top', 'bottom'],
color: [
...SUI.COLORS,
'facebook',
'twitter',
'google plus',
'vk',
'linkedin',
'instagram',
'youtube',
],
floated: SUI.FLOATS,
labelPosition: ['right', 'left'],
size: SUI.SIZES,
},
}

/**
* A Button indicates a possible user action
* A Button indicates a possible user action.
Copy link
Member Author

Choose a reason for hiding this comment

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

Dots.

* @see Form
* @see Icon
* @see Label
Expand All @@ -56,19 +33,19 @@ class Button extends Component {
/** An element type to render as (string or function). */
as: customPropTypes.as,

/** A button can show it is currently the active user selection */
/** A button can show it is currently the active user selection. */
active: PropTypes.bool,

/** A button can animate to show hidden content */
/** A button can animate to show hidden content. */
animated: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(_meta.props.animated),
PropTypes.oneOf(['fade', 'vertical']),
]),

/** A button can be attached to the top or bottom of other content */
attached: PropTypes.oneOf(_meta.props.attached),
/** A button can be attached to the top or bottom of other content. */
attached: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),

Copy link
Member Author

Choose a reason for hiding this comment

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

It's gone 😄

Copy link
Member

Choose a reason for hiding this comment

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

🎉

/** A basic button is less pronounced */
/** A basic button is less pronounced. */
basic: PropTypes.bool,

/** Primary content. */
Expand All @@ -87,55 +64,58 @@ class Button extends Component {
),
]),

/** A button can be circular */
circular: PropTypes.bool,

/** Additional classes. */
className: PropTypes.string,

/** Shorthand for primary content. */
content: customPropTypes.contentShorthand,
/** A button can be circular. */
circular: PropTypes.bool,

/** A button can have different colors */
color: PropTypes.oneOf(_meta.props.color),
color: PropTypes.oneOf([
...SUI.COLORS,
'facebook', 'google plus', 'instagram', 'linkedin', 'twitter', 'vk', 'youtube',
]),

/** A button can reduce its padding to fit into tighter spaces */
/** A button can reduce its padding to fit into tighter spaces. */
compact: PropTypes.bool,

/** A button can show it is currently unable to be interacted with */
/** Shorthand for primary content. */
content: customPropTypes.contentShorthand,

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

/** A button can be aligned to the left or right of its container */
floated: PropTypes.oneOf(_meta.props.floated),
/** A button can be aligned to the left or right of its container. */
floated: PropTypes.oneOf(SUI.FLOATS),

/** A button can take the width of its container */
/** A button can take the width of its container. */
fluid: PropTypes.bool,

/** Add an Icon by name, props object, or pass an <Icon /> */
/** Add an Icon by name, props object, or pass an <Icon />. */
icon: customPropTypes.some([
PropTypes.bool,
PropTypes.string,
PropTypes.object,
PropTypes.element,
]),

/** A button can be formatted to appear on dark backgrounds */
/** A button can be formatted to appear on dark backgrounds. */
inverted: PropTypes.bool,

/** A labeled button can format a Label or Icon to appear on the left or right */
labelPosition: PropTypes.oneOf(_meta.props.labelPosition),

/** Add a Label by text, props object, or pass a <Label /> */
/** Add a Label by text, props object, or pass a <Label />. */
label: customPropTypes.some([
PropTypes.string,
PropTypes.object,
PropTypes.element,
]),

/** A button can show a loading indicator */
/** A labeled button can format a Label or Icon to appear on the left or right. */
labelPosition: PropTypes.oneOf(['right', 'left']),

/** A button can show a loading indicator. */
loading: PropTypes.bool,

/** A button can hint towards a negative consequence */
/** A button can hint towards a negative consequence. */
negative: PropTypes.bool,

/**
Expand All @@ -145,33 +125,37 @@ class Button extends Component {
*/
onClick: PropTypes.func,

/** A button can hint towards a positive consequence */
/** A button can hint towards a positive consequence. */
positive: PropTypes.bool,

/** A button can be formatted to show different levels of emphasis */
/** A button can be formatted to show different levels of emphasis. */
primary: PropTypes.bool,

/** A button can be formatted to show different levels of emphasis */
/** A button can be formatted to show different levels of emphasis. */
secondary: PropTypes.bool,

/** A button can have different sizes */
size: PropTypes.oneOf(_meta.props.size),
/** A button can have different sizes. */
size: PropTypes.oneOf(SUI.SIZES),

/** A button can receive focus. */
tabIndex: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.string,
]),

/** A button can be formatted to toggle on and off */
/** A button can be formatted to toggle on and off. */
toggle: PropTypes.bool,
}

static defaultProps = {
as: 'button',
}

static _meta = _meta
static _meta = {
name: 'Button',
type: META.TYPES.ELEMENT,
}

static Content = ButtonContent
static Group = ButtonGroup
static Or = ButtonOr
Expand All @@ -187,6 +171,14 @@ class Button extends Component {
if (onClick) onClick(e, this.props)
}

computeTabIndex = ElementType => {
const { disabled, tabIndex } = this.props

if (!_.isNil(tabIndex)) return tabIndex
if (disabled) return -1
if (ElementType === 'div') return 0
}

render() {
const {
active,
Expand All @@ -212,7 +204,6 @@ class Button extends Component {
primary,
secondary,
size,
tabIndex,
toggle,
} = this.props

Expand All @@ -224,13 +215,10 @@ class Button extends Component {
color,
size,
useKeyOnly(active, 'active'),
useKeyOrValueAndKey(animated, 'animated'),
useKeyOrValueAndKey(attached, 'attached'),
useKeyOnly(basic, 'basic'),
useKeyOnly(circular, 'circular'),
useKeyOnly(compact, 'compact'),
useKeyOnly(disabled, 'disabled'),
useValueAndKey(floated, 'floated'),
useKeyOnly(fluid, 'fluid'),
useKeyOnly(icon === true || icon && (labelPosition || !children && !content), 'icon'),
useKeyOnly(inverted, 'inverted'),
Expand All @@ -240,22 +228,21 @@ class Button extends Component {
useKeyOnly(primary, 'primary'),
useKeyOnly(secondary, 'secondary'),
useKeyOnly(toggle, 'toggle'),
useKeyOrValueAndKey(animated, 'animated'),
useKeyOrValueAndKey(attached, 'attached'),
useValueAndKey(floated, 'floated'),
)
const rest = getUnhandledProps(Button, this.props)
const ElementType = getElementType(Button, this.props, () => {
if (!_.isNil(label) || !_.isNil(attached)) return 'div'
})

let computedTabIndex
if (!_.isNil(tabIndex)) computedTabIndex = tabIndex
else if (disabled) computedTabIndex = -1
else if (ElementType === 'div') computedTabIndex = 0
const tabIndex = this.computeTabIndex(ElementType)

if (!_.isNil(children)) {
const classes = cx('ui', baseClasses, labeledClasses, 'button', className)
debug('render children:', { classes })
return (
<ElementType {...rest} className={classes} tabIndex={computedTabIndex} onClick={this.handleClick}>
<ElementType {...rest} className={classes} tabIndex={tabIndex} onClick={this.handleClick}>
{children}
</ElementType>
)
Expand Down Expand Up @@ -285,7 +272,7 @@ class Button extends Component {
const classes = cx('ui', labeledClasses, baseClasses, 'button', className)
debug('render icon && !label:', { classes })
return (
<ElementType {...rest} className={classes} tabIndex={computedTabIndex} onClick={this.handleClick}>
<ElementType {...rest} className={classes} tabIndex={tabIndex} onClick={this.handleClick}>
{Icon.create(icon)} {content}
</ElementType>
)
Expand All @@ -295,7 +282,7 @@ class Button extends Component {
debug('render default:', { classes })

return (
<ElementType {...rest} className={classes} tabIndex={computedTabIndex} onClick={this.handleClick}>
<ElementType {...rest} className={classes} tabIndex={tabIndex} onClick={this.handleClick}>
{content}
</ElementType>
)
Expand Down
19 changes: 12 additions & 7 deletions src/elements/Button/ButtonContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import {
} from '../../lib'

/**
* Used in some Button types, such as `animated`
* Used in some Button types, such as `animated`.
*/
function ButtonContent(props) {
const { children, className, hidden, visible } = props
const {
children,
className,
hidden,
visible,
} = props
const classes = cx(
useKeyOnly(visible, 'visible'),
useKeyOnly(hidden, 'hidden'),
Expand All @@ -36,16 +41,16 @@ ButtonContent.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

/** Additional classes. */
className: PropTypes.string,

/** Primary content. */
children: PropTypes.node,

/** Initially hidden, visible on hover */
/** Additional classes. */
className: PropTypes.string,

/** Initially hidden, visible on hover. */
hidden: PropTypes.bool,

/** Initially visible, hidden on hover */
/** Initially visible, hidden on hover. */
visible: PropTypes.bool,
}

Expand Down
Loading