Ivan - Use ES6 Classes in core components [skip ci]

This commit is contained in:
ivan 2016-08-12 01:20:14 -03:00
parent 35cf17b114
commit eaef9b42db
11 changed files with 204 additions and 222 deletions

View File

@ -6,13 +6,13 @@ import classNames from 'classnames';
// CORE LIBS
import callback from 'lib-core/callback';
const Button = React.createClass({
class Button extends React.Component {
contextTypes: {
static contextTypes = {
router: React.PropTypes.object
},
};
propTypes: {
static propTypes = {
children: React.PropTypes.node,
type: React.PropTypes.oneOf([
'primary',
@ -24,13 +24,11 @@ const Button = React.createClass({
params: React.PropTypes.object,
query: React.PropTypes.query
})
},
};
getDefaultProps() {
return {
type: 'primary'
};
},
static defaultProps = {
type: 'primary'
};
render() {
return (
@ -38,19 +36,19 @@ const Button = React.createClass({
{this.props.children}
</button>
);
},
}
getProps() {
let props = _.clone(this.props);
props.onClick = callback(this.handleClick, this.props.onClick);
props.onClick = callback(this.handleClick.bind(this), this.props.onClick);
props.className = this.getClass();
delete props.route;
delete props.type;
return props;
},
}
getClass() {
let classes = {
@ -62,13 +60,13 @@ const Button = React.createClass({
classes[this.props.className] = (this.props.className);
return classNames(classes);
},
}
handleClick() {
if (this.props.route) {
this.context.router.push(this.props.route.to);
}
}
});
}
export default Button;

View File

@ -5,25 +5,25 @@ import _ from 'lodash';
import callback from 'lib-core/callback';
import getIcon from 'lib-core/get-icon';
let CheckBox = React.createClass({
class CheckBox extends React.Component {
propTypes: {
static propTypes = {
alignment: React.PropTypes.string,
label: React.PropTypes.string,
value: React.PropTypes.bool
},
};
getDefaultProps() {
return {
alignment: 'right'
};
},
static defaultProps = {
alignment: 'right'
};
getInitialState() {
return {
constructor(props) {
super(props);
this.state = {
checked: false
};
},
}
render() {
return (
@ -35,7 +35,7 @@ let CheckBox = React.createClass({
<input {...this.getProps()}/>
</label>
);
},
}
getProps() {
let props = _.clone(this.props);
@ -45,7 +45,7 @@ let CheckBox = React.createClass({
props['aria-hidden'] = true;
props.className = 'checkbox--box';
props.checked = this.getValue();
props.onChange = callback(this.handleChange, this.props.onChange);
props.onChange = callback(this.handleChange.bind(this), this.props.onChange);
delete props.alignment;
delete props.error;
@ -53,7 +53,7 @@ let CheckBox = React.createClass({
delete props.value;
return props;
},
}
getClass() {
let classes = {
@ -64,29 +64,29 @@ let CheckBox = React.createClass({
};
return classNames(classes);
},
}
getIconProps() {
return {
'aria-checked': this.getValue(),
className: 'checkbox--icon',
onKeyDown: callback(this.handleIconKeyDown, this.props.onKeyDown),
onKeyDown: callback(this.handleIconKeyDown.bind(this), this.props.onKeyDown),
role: "checkbox",
tabIndex: 0
};
},
}
getValue() {
return (this.props.value === undefined) ? this.state.checked : this.props.value;
},
}
handleChange: function (event) {
handleChange(event) {
this.setState({
checked: event.target.checked
});
},
}
handleIconKeyDown: function (event) {
handleIconKeyDown(event) {
if (event.keyCode == 32) {
event.preventDefault();
@ -97,6 +97,6 @@ let CheckBox = React.createClass({
});
}
}
});
}
export default CheckBox;

View File

@ -1,32 +1,30 @@
const React = require('react');
const classNames = require('classnames');
const _ = require('lodash');
const {Motion, spring} = require('react-motion');
const callback = require('lib-core/callback');
import React from 'react';
import classNames from 'classnames';
import {Motion, spring} from 'react-motion';
const Menu = require('core-components/menu');
const Icon = require('core-components/icon');
import Menu from 'core-components/menu';
import Icon from 'core-components/icon';
const DropDown = React.createClass({
class DropDown extends React.Component {
propTypes: {
static propTypes = {
defaultSelectedIndex: React.PropTypes.number,
selectedIndex: React.PropTypes.number,
items: Menu.propTypes.items
},
};
getDefaultProps() {
return {
defaultSelectedIndex: 0
};
},
static defaultProps = {
defaultSelectedIndex: 2
};
getInitialState() {
return {
constructor(props) {
super(props);
this.state = {
selectedIndex: 0,
opened: false
};
},
}
getAnimationStyles() {
let closedStyle = {
@ -42,7 +40,7 @@ const DropDown = React.createClass({
defaultStyle: closedStyle,
style: (this.state.opened) ? openedStyle : closedStyle
};
},
}
render() {
let animation = this.getAnimationStyles();
@ -52,18 +50,18 @@ const DropDown = React.createClass({
<div className={this.getClass()}>
{this.renderCurrentItem(selectedItem)}
<Motion defaultStyle={animation.defaultStyle} style={animation.style}>
{this.renderList}
{this.renderList.bind(this)}
</Motion>
</div>
);
},
}
renderList({opacity, translateY}) {
let style = { opacity: opacity, transform: `translateY(${translateY}px)`};
let menuProps = {
items: this.props.items,
onItemClick: this.handleItemClick,
onMouseDown: this.handleListMouseDown,
onItemClick: this.handleItemClick.bind(this),
onMouseDown: this.handleListMouseDown.bind(this),
selectedIndex: this.state.selectedIndex
};
@ -72,7 +70,7 @@ const DropDown = React.createClass({
<Menu {...menuProps} />
</div>
);
},
}
renderCurrentItem(item) {
var iconNode = null;
@ -82,11 +80,11 @@ const DropDown = React.createClass({
}
return (
<div className="drop-down--current-item" onBlur={this.handleBlur} onClick={this.handleClick} tabIndex="0">
<div className="drop-down--current-item" onBlur={this.handleBlur.bind(this)} onClick={this.handleClick.bind(this)} tabIndex="0">
{iconNode}{item.content}
</div>
);
},
}
getClass() {
let classes = {
@ -97,19 +95,19 @@ const DropDown = React.createClass({
};
return classNames(classes);
},
}
handleBlur() {
this.setState({
opened: false
});
},
}
handleClick() {
this.setState({
opened: !this.state.opened
});
},
}
handleItemClick(index) {
this.setState({
@ -122,15 +120,15 @@ const DropDown = React.createClass({
index
});
}
},
}
handleListMouseDown(event) {
event.preventDefault();
},
}
getSelectedIndex() {
return (this.props.selectedIndex !== undefined) ? this.props.selectedIndex : this.state.selectedIndex;
}
});
}
export default DropDown;

View File

@ -1,64 +1,66 @@
const React = require('react');
const _ = require('lodash');
const classNames = require('classnames');
import React from 'react';
import _ from 'lodash';
import classNames from 'classnames';
const {reactDFS, renderChildrenWithProps} = require('lib-core/react-dfs');
const ValidationFactory = require('lib-app/validations/validations-factory');
import {reactDFS, renderChildrenWithProps} from 'lib-core/react-dfs';
import ValidationFactory from 'lib-app/validations/validations-factory';
const Input = require('core-components/input');
const Checkbox = require('core-components/checkbox');
import Input from 'core-components/input';
import Checkbox from 'core-components/checkbox';
const Form = React.createClass({
class Form extends React.Component {
propTypes: {
static propTypes = {
loading: React.PropTypes.bool,
errors: React.PropTypes.object,
onValidateErrors: React.PropTypes.func,
onSubmit: React.PropTypes.func
},
};
childContextTypes: {
static childContextTypes = {
loading: React.PropTypes.bool
},
};
constructor(props) {
super(props);
this.state = {
form: {},
validations: {},
errors: {}
};
}
getChildContext() {
return {
loading: this.props.loading
};
},
getInitialState() {
return {
form: {},
validations: {},
errors: {}
};
},
}
componentDidMount() {
this.setState(this.getInitialFormAndValidations());
},
}
render() {
return (
<form {...this.getProps()}>
{renderChildrenWithProps(this.props.children, this.getFieldProps)}
{renderChildrenWithProps(this.props.children, this.getFieldProps.bind(this))}
</form>
);
},
}
getProps() {
let props = _.clone(this.props);
props.className = this.getClass();
props.onSubmit = this.handleSubmit;
props.onSubmit = this.handleSubmit.bind(this);
delete props.errors;
delete props.loading;
delete props.onValidateErrors;
return props;
},
}
getClass() {
let classes = {
@ -68,7 +70,7 @@ const Form = React.createClass({
classes[this.props.className] = (this.props.className);
return classNames(classes);
},
}
getFieldProps({props, type}) {
let additionalProps = {};
@ -86,7 +88,7 @@ const Form = React.createClass({
}
return additionalProps;
},
}
getFieldError(fieldName) {
let error = this.state.errors[fieldName];
@ -95,7 +97,7 @@ const Form = React.createClass({
error = this.props.errors[fieldName]
}
return error;
},
}
getFirstErrorField() {
let fieldName = _.findKey(this.state.errors);
@ -106,7 +108,7 @@ const Form = React.createClass({
}
return fieldNode;
},
}
getAllFieldErrors() {
let form = this.state.form;
@ -118,7 +120,7 @@ const Form = React.createClass({
});
return errors;
},
}
getErrorsWithValidatedField(fieldName, form = this.state.form, errors = this.state.errors) {
let newErrors = _.clone(errors);
@ -128,7 +130,7 @@ const Form = React.createClass({
}
return newErrors;
},
}
getInitialFormAndValidations() {
let form = {};
@ -154,17 +156,17 @@ const Form = React.createClass({
form: form,
validations: validations
}
},
}
handleSubmit(event) {
event.preventDefault();
if (this.hasFormErrors()) {
this.updateErrors(this.getAllFieldErrors(), this.focusFirstErrorField);
this.updateErrors(this.getAllFieldErrors(), this.focusFirstErrorField.bind(this));
} else if (this.props.onSubmit) {
this.props.onSubmit(this.state.form);
}
},
}
handleFieldChange(fieldName, type, event) {
let form = _.clone(this.state.form);
@ -178,19 +180,19 @@ const Form = React.createClass({
this.setState({
form: form
});
},
}
isValidFieldType(child) {
return child.type === Input || child.type === Checkbox;
},
}
hasFormErrors() {
return _.some(this.getAllFieldErrors());
},
}
validateField(fieldName) {
this.updateErrors(this.getErrorsWithValidatedField(fieldName));
},
}
updateErrors(errors, callback) {
this.setState({
@ -200,7 +202,7 @@ const Form = React.createClass({
if (this.props.onValidateErrors) {
this.props.onValidateErrors(errors);
}
},
}
focusFirstErrorField() {
let firstErrorField = this.getFirstErrorField();
@ -209,6 +211,6 @@ const Form = React.createClass({
firstErrorField.focus();
}
}
});
}
export default Form;

View File

@ -1,34 +1,32 @@
const React = require('react');
const classNames = require('classnames');
import React from 'react';
import classNames from 'classnames';
const Icon = React.createClass({
class Icon extends React.Component {
propTypes: {
static propTypes = {
name: React.PropTypes.string.isRequired,
size: React.PropTypes.string
},
};
getDefaultProps() {
return {
size: 'lg'
};
},
static defaultProps = {
size: 'lg'
};
render() {
return (this.props.name.length > 2) ? this.renderFontIcon() : this.renderFlag();
},
}
renderFontIcon() {
return (
<span className={this.getFontIconClass()} aria-hidden="true" />
);
},
}
renderFlag() {
return (
<img className={this.props.className} src={`/images/icons/${this.props.name}.png`} aria-hidden="true" />
);
},
}
getFontIconClass() {
let classes = {
@ -40,6 +38,6 @@ const Icon = React.createClass({
return classNames(classes);
}
});
}
export default Icon;

View File

@ -1,16 +1,16 @@
const React = require('react');
const classNames = require('classnames');
const _ = require('lodash');
import React from 'react';
import classNames from 'classnames';
import _ from 'lodash';
const Icon = require('core-components/icon');
import Icon from 'core-components/icon';
const Input = React.createClass({
class Input extends React.Component {
contextTypes: {
static contextTypes = {
loading: React.PropTypes.bool
},
};
propTypes: {
static propTypes = {
value: React.PropTypes.string,
validation: React.PropTypes.string,
onChange: React.PropTypes.func,
@ -19,13 +19,11 @@ const Input = React.createClass({
required: React.PropTypes.bool,
icon: React.PropTypes.string,
error: React.PropTypes.string
},
};
getDefaultProps() {
return {
static defaultProps = {
inputType: 'primary'
};
},
};
render() {
return (
@ -36,7 +34,7 @@ const Input = React.createClass({
{this.renderError()}
</label>
);
},
}
renderError() {
let error = null;
@ -46,7 +44,7 @@ const Input = React.createClass({
}
return error;
},
}
renderIcon() {
let icon = null;
@ -56,7 +54,7 @@ const Input = React.createClass({
}
return icon;
},
}
getInputProps() {
let props = _.clone(this.props);
@ -73,7 +71,7 @@ const Input = React.createClass({
delete props.password;
return props;
},
}
getClass() {
let classes = {
@ -86,13 +84,13 @@ const Input = React.createClass({
};
return classNames(classes);
},
}
focus() {
if (this.refs.nativeInput) {
this.refs.nativeInput.focus();
}
}
});
}
export default Input;

View File

@ -1,34 +1,32 @@
const React = require('react');
const _ = require('lodash');
const classNames = require('classnames');
import React from 'react';
import _ from 'lodash';
import classNames from 'classnames';
const Icon = require('core-components/icon');
import Icon from 'core-components/icon';
const Menu = React.createClass({
class Menu extends React.Component {
propTypes: {
static propTypes = {
type: React.PropTypes.oneOf(['primary', 'secondary']),
items: React.PropTypes.arrayOf(React.PropTypes.shape({
content: React.PropTypes.string.isRequired,
icon: React.PropTypes.string
})).isRequired,
selectedIndex: React.PropTypes.number
},
};
getDefaultProps() {
return {
type: 'primary',
selectedIndex: 0
};
},
static defaultProps = {
type: 'primary',
selectedIndex: 0
};
render() {
return (
<ul {...this.getProps()}>
{this.props.items.map(this.renderListItem)}
{this.props.items.map(this.renderListItem.bind(this))}
</ul>
)
},
}
renderListItem(item, index) {
let iconNode = null;
@ -42,7 +40,7 @@ const Menu = React.createClass({
{iconNode}{item.content}
</li>
);
},
}
getProps() {
var props = _.clone(this.props);
@ -55,7 +53,7 @@ const Menu = React.createClass({
delete props.type;
return props;
},
}
getClass() {
let classes = {
@ -66,7 +64,7 @@ const Menu = React.createClass({
classes[this.props.className] = true;
return classNames(classes);
},
}
getItemProps(index) {
return {
@ -74,7 +72,7 @@ const Menu = React.createClass({
onClick: this.handleItemClick.bind(this, index),
key: index
};
},
}
getItemClass(index) {
let classes = {
@ -83,13 +81,13 @@ const Menu = React.createClass({
};
return classNames(classes);
},
}
handleItemClick(index) {
if (this.props.onItemClick) {
this.props.onItemClick(index);
}
}
});
}
export default Menu;

View File

@ -4,29 +4,27 @@ import classNames from 'classnames';
import {Motion, spring} from 'react-motion';
import Icon from 'core-components/icon';
const Message = React.createClass({
class Message extends React.Component {
propTypes: {
static propTypes = {
title: React.PropTypes.string,
children: React.PropTypes.node,
leftAligned: React.PropTypes.bool,
type: React.PropTypes.oneOf(['success', 'error', 'info'])
},
};
getDefaultProps() {
return {
type: 'info',
leftAligned: false
};
},
static defaultProps = {
type: 'info',
leftAligned: false
};
render() {
return (
<Motion {...this.getAnimationProps()}>
{this.renderMessage}
{this.renderMessage.bind(this)}
</Motion>
);
},
}
getAnimationProps() {
return {
@ -37,7 +35,7 @@ const Message = React.createClass({
opacity: spring(1, [100, 30])
}
};
},
}
renderMessage(style) {
return (
@ -47,7 +45,7 @@ const Message = React.createClass({
<div className="message__content">{this.props.children}</div>
</div>
)
},
}
getClass() {
let classes = {
@ -62,7 +60,7 @@ const Message = React.createClass({
};
return classNames(classes);
},
}
getIconName() {
let iconNames = {
@ -72,11 +70,11 @@ const Message = React.createClass({
};
return iconNames[this.props.type];
},
}
getIconSize() {
return (this.props.title) ? '2x' : 'lg';
}
});
}
export default Message;

View File

@ -6,21 +6,19 @@ import classNames from 'classnames';
// CORE LIBS
import Button from 'core-components/button';
const SubmitButton = React.createClass({
class SubmitButton extends React.Component {
contextTypes: {
static contextTypes = {
loading: React.PropTypes.bool
},
};
propTypes: {
static propTypes = {
children: React.PropTypes.node
},
};
getDefaultProps() {
return {
type: 'primary'
};
},
static defaultProps = {
type: 'primary'
};
render() {
return (
@ -28,20 +26,20 @@ const SubmitButton = React.createClass({
{(this.context.loading) ? this.renderLoading() : this.props.children}
</Button>
);
},
}
renderLoading() {
return (
<div className="submit-button__loader"></div>
);
},
}
getProps() {
return _.extend({}, this.props, {
disabled: this.context.loading,
className: this.getClass()
});
},
}
getClass() {
let classes = {
@ -53,6 +51,6 @@ const SubmitButton = React.createClass({
return classNames(classes);
}
});
}
export default SubmitButton;

View File

@ -3,35 +3,31 @@ import classNames from 'classnames';
import _ from 'lodash';
import {Motion, spring} from 'react-motion';
import Widget from 'core-components/widget';
class WidgetTransition extends React.Component {
let WidgetTransition = React.createClass({
propTypes: {
static propTypes = {
sideToShow: React.PropTypes.string
},
};
getDefaultProps() {
return {
sideToShow: 'front'
};
},
static defaultProps = {
sideToShow: 'front'
};
getDefaultAnimation() {
return {
rotateY: -90
};
},
}
render() {
return (
<Motion defaultStyle={this.getDefaultAnimation()} style={this.getAnimation()}>
{this.renderChildren}
{this.renderChildren.bind(this)}
</Motion>
);
},
}
renderChildren: function (animation) {
renderChildren(animation) {
return (
<div className={this.getClass()}>
{React.Children.map(this.props.children, function (child, index) {
@ -57,7 +53,7 @@ let WidgetTransition = React.createClass({
})}
</div>
)
},
}
getClass() {
let classes = {
@ -66,13 +62,13 @@ let WidgetTransition = React.createClass({
};
return classNames(classes);
},
}
getAnimation() {
return {
rotateY: (this.props.sideToShow === 'front') ? spring(0, [100, 20]) : spring(180, [100, 20])
};
}
});
}
export default WidgetTransition;

View File

@ -1,17 +1,15 @@
import React from 'react';
import classNames from 'classnames';
let Widget = React.createClass({
propTypes: {
class Widget extends React.Component {
static propTypes = {
title: React.PropTypes.string,
children: React.PropTypes.node.isRequired
},
};
getDefaultProps() {
return {
title: ''
};
},
static defaultProps = {
title: ''
};
render() {
return (
@ -20,7 +18,7 @@ let Widget = React.createClass({
{this.props.children}
</div>
);
},
}
renderTitle() {
let titleNode = null;
@ -30,7 +28,7 @@ let Widget = React.createClass({
}
return titleNode;
},
}
getClass() {
let classes = {
@ -41,6 +39,6 @@ let Widget = React.createClass({
return classNames(classes);
}
});
}
export default Widget;