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

Commit

Permalink
Break up the render method logic into functions
Browse files Browse the repository at this point in the history
* Adds two components to represent a link and button.
* Removes nested if/else statements in favor of smalled named functions
  • Loading branch information
el-mapache committed Jun 30, 2017
1 parent c43ae0d commit 5cd9f0d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 70 deletions.
137 changes: 67 additions & 70 deletions static_src/components/action.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@

import React from 'react';
import style from 'cloudgov-style/css/cloudgov-style.css';

import createStyler from '../util/create_styler';

import classnames from 'classnames';
import Link from './actions/link.jsx';
import Button from './actions/button.jsx';

const BUTTON_TYPES = {
BUTTON: 'button',
OUTLINE: 'outline',
LINK: 'link',
SUBMIT: 'submit'
};
const BUTTON_STYLES = [
'warning',
'primary',
'finish',
'base',
'white'
];

const BUTTON_TYPES = [
'button',
'outline',
'outline-inverse',
'link',
'submit'
];

const propTypes = {
children: React.PropTypes.any,
classes: React.PropTypes.array,
Expand All @@ -28,77 +25,77 @@ const propTypes = {
href: React.PropTypes.string,
label: React.PropTypes.string,
style: React.PropTypes.oneOf(BUTTON_STYLES),
type: React.PropTypes.oneOf(BUTTON_TYPES)
type: React.PropTypes.oneOf(Object.keys(BUTTON_TYPES).map(key => BUTTON_TYPES[key]))
};

const defaultProps = {
style: 'primary',
classes: [],
label: '',
type: 'button',
disabled: false,
clickHandler: () => true,
children: []
clickHandler: () => true
};

export default class Action extends React.Component {
constructor(props) {
super(props);
get baseClasses() {
return `action action-${this.props.style}`;
}

get classes() {
return this.props.classes.join(' ');
}

get buttonClasses() {
if (this.typeOfLink) return {};

return classnames({
'action-outline': this.props.type === BUTTON_TYPES.OUTLINE,
'usa-button-disabled': this.props.disabled
}, 'usa-button', `usa-button-${this.props.style}`);
}

get sharedProps() {
const buttonClasses = this.buttonClasses;

return {
className: classnames(this.baseClasses, this.classes, buttonClasses),
label: this.props.label,
clickHandler: this.props.clickHandler
};
}

get buttonProps() {
const htmlButtonType = this.props.type === BUTTON_TYPES.BUTTON ?
BUTTON_TYPES.BUTTON : BUTTON_TYPES.SUBMIT;

return { disabled: this.props.disabled, type: htmlButtonType };
}

get linkProps() {
return { href: this.props.href };
}

get typeOfLink() {
return this.props.type === BUTTON_TYPES.LINK;
}

get isLink() {
return this.props.href || this.typeOfLink;
}

this.styler = createStyler(style);
get component() {
return this.isLink ? Link : Button;
}

render() {
const styleClass = `usa-button-${this.props.style}`;
let classes = this.styler(...this.props.classes);
let content = <div></div>;
const classList = [...this.props.classes];

classList.push('action');
classList.push(`action-${this.props.style}`);

if (this.props.type !== 'link') {
if (this.props.disabled) {
classList.push('usa-button-disabled');
} else {
classList.push('usa-button');
classList.push(styleClass);
if (this.props.type === 'outline') classList.push('action-outline');
}
classes = this.styler(...classList);
}

if (this.props.type === 'link' || this.props.href) {
classList.push('action-link');

classes = this.styler(...classList);

content = (
<a
className={ classes }
title={ this.props.label }
onClick={ (ev) => this.props.clickHandler(ev) }
disabled={ this.props.disabled }
href={ this.props.href || '#' }
>
{ this.props.children }
</a>
);
} else {
content = (
<button
className={ classes }
aria-label={ this.props.label }
onClick={ (ev) => this.props.clickHandler(ev) }
disabled={this.props.disabled}
type={ this.props.type === 'submit' ? this.props.type : null }
>
{ this.props.children }
</button>
);
}

return content;
const Component = this.component;
const extraProps = this.isLink ? this.linkProps : this.buttonProps;

return (
<Component { ...this.sharedProps } { ...extraProps }>
{ this.props.children }
</Component>
);
}
}

Expand Down
25 changes: 25 additions & 0 deletions static_src/components/actions/button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

const propTypes = {
children: React.PropTypes.any,
className: React.PropTypes.string,
clickHandler: React.PropTypes.func,
disabled: React.PropTypes.bool,
label: React.PropTypes.string,
type: React.PropTypes.string
};

const button = ({ className, label, clickHandler, disabled, type, children }) =>
<button
className={ className }
aria-label={ label }
onClick={ clickHandler }
disabled={ disabled }
type={type}
>
{ children }
</button>;

button.propTypes = propTypes;

export default button;
28 changes: 28 additions & 0 deletions static_src/components/actions/link.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import classnames from 'classnames';

const propTypes = {
children: React.PropTypes.any,
className: React.PropTypes.string,
clickHandler: React.PropTypes.func,
href: React.PropTypes.string,
label: React.PropTypes.string
};
const defaultPropTypes = {
href: '#'
};

const Link = ({ className, label, href, clickHandler, children }) =>
<a
className={ classnames(className, 'action-link') }
title={ label }
onClick={ clickHandler }
href={ href }
>
{ children }
</a>;

Link.propTypes = propTypes;
Link.defaultPropTypes = defaultPropTypes;

export default Link;

0 comments on commit 5cd9f0d

Please sign in to comment.