Skip to content

Commit

Permalink
Autoinject styles for Lists
Browse files Browse the repository at this point in the history
  • Loading branch information
javivelasco committed May 29, 2016
1 parent 731153d commit 592024f
Show file tree
Hide file tree
Showing 15 changed files with 368 additions and 289 deletions.
1 change: 1 addition & 0 deletions components/identifiers.js
Expand Up @@ -10,6 +10,7 @@ export const DROPDOWN = 'RTDropdown';
export const INPUT = 'RTInput';
export const LAYOUT = 'RTLayout';
export const LINK = 'RTLink';
export const LIST = 'RTList';
export const OVERLAY = 'RTOverlay';
export const PROGRESS_BAR = 'RTProgressBar';
export const RIPPLE = 'RTRipple';
82 changes: 45 additions & 37 deletions components/list/List.js
@@ -1,45 +1,53 @@
import React from 'react';
import React, { Component, PropTypes } from 'react';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import ListItem from './ListItem';
import { LIST } from '../identifiers.js';
import InjectListItem from './ListItem.js';

class List extends React.Component {
static propTypes = {
children: React.PropTypes.node,
className: React.PropTypes.string,
ripple: React.PropTypes.bool,
selectable: React.PropTypes.bool,
theme: React.PropTypes.shape({
list: React.PropTypes.string.isRequired
})
};
const factory = (ListItem) => {
class List extends Component {
static propTypes = {
children: PropTypes.node,
className: PropTypes.string,
ripple: PropTypes.bool,
selectable: PropTypes.bool,
theme: PropTypes.shape({
list: PropTypes.string.isRequired
})
};

static defaultProps = {
className: '',
ripple: false,
selectable: false
};
static defaultProps = {
className: '',
ripple: false,
selectable: false
};

renderItems () {
return React.Children.map(this.props.children, (item) => {
if (item.type === ListItem) {
return React.cloneElement(item, {
ripple: this.props.ripple,
selectable: this.props.selectable
});
} else {
return React.cloneElement(item);
}
});
}
renderItems () {
return React.Children.map(this.props.children, (item) => {
if (item.type === ListItem) {
return React.cloneElement(item, {
ripple: this.props.ripple,
selectable: this.props.selectable
});
} else {
return React.cloneElement(item);
}
});
}

render () {
return (
<ul data-react-toolbox='list' className={classnames(this.props.theme.list, this.props.className)}>
{this.renderItems()}
</ul>
);
render () {
return (
<ul data-react-toolbox='list' className={classnames(this.props.theme.list, this.props.className)}>
{this.renderItems()}
</ul>
);
}
}
}

export default themr('ToolboxList')(List);
return List;
};

const List = factory(InjectListItem);
export default themr(LIST)(List);
export { factory as listFactory };
export { List };
95 changes: 52 additions & 43 deletions components/list/ListCheckbox.js
@@ -1,51 +1,60 @@
import React from 'react';
import React, { PropTypes } from 'react';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import Checkbox from '../checkbox';
import ListItemContent from './ListItemContent';
import { LIST } from '../identifiers.js';
import InjectCheckbox from '../checkbox/Checkbox.js';
import InjectListItemContent from './ListItemContent.js';

const ListCheckbox = ({ caption, checked, className, disabled, legend, name, onBlur, onChange, onFocus, theme }) => {
const _className = classnames(theme.item, theme.checkboxItem, {
[theme.disabled]: disabled
}, className);
const factory = (Checkbox, ListItemContent) => {
const ListCheckbox = ({ caption, checked, className, disabled, legend, name, onBlur, onChange, onFocus, theme }) => {
const _className = classnames(theme.item, theme.checkboxItem, {
[theme.disabled]: disabled
}, className);

return (
<li className={_className}>
<Checkbox
checked={checked}
className={theme.checkbox}
disabled={disabled}
label={<ListItemContent caption={caption} legend={legend} />}
name={name}
onBlur={onBlur}
onChange={onChange}
onFocus={onFocus}
/>
</li>
);
};
return (
<li className={_className}>
<Checkbox
checked={checked}
className={theme.checkbox}
disabled={disabled}
label={<ListItemContent caption={caption} legend={legend} />}
name={name}
onBlur={onBlur}
onChange={onChange}
onFocus={onFocus}
/>
</li>
);
};

ListCheckbox.propTypes = {
caption: React.PropTypes.string.isRequired,
checked: React.PropTypes.bool,
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
legend: React.PropTypes.string,
name: React.PropTypes.string,
onBlur: React.PropTypes.func,
onChange: React.PropTypes.func,
onFocus: React.PropTypes.func,
theme: React.PropTypes.shape({
checkbox: React.PropTypes.string.isRequired,
checkboxItem: React.PropTypes.string.isRequired,
disabled: React.PropTypes.string.isRequired,
item: React.PropTypes.string.isRequired
})
};
ListCheckbox.propTypes = {
caption: PropTypes.string.isRequired,
checked: PropTypes.bool,
className: PropTypes.string,
disabled: PropTypes.bool,
legend: PropTypes.string,
name: PropTypes.string,
onBlur: PropTypes.func,
onChange: PropTypes.func,
onFocus: PropTypes.func,
theme: PropTypes.shape({
checkbox: PropTypes.string.isRequired,
checkboxItem: PropTypes.string.isRequired,
disabled: PropTypes.string.isRequired,
item: PropTypes.string.isRequired
})
};

ListCheckbox.defaultProps = {
checked: false,
disabled: false
ListCheckbox.defaultProps = {
checked: false,
disabled: false
};

return ListCheckbox;
};

export default themr('ToolboxList')(ListCheckbox);
const ListCheckbox = factory(InjectCheckbox, InjectListItemContent);

export default themr(LIST)(ListCheckbox);
export { factory as listCheckboxFactory };
export { ListCheckbox };
4 changes: 3 additions & 1 deletion components/list/ListDivider.js
@@ -1,5 +1,6 @@
import React from 'react';
import { themr } from 'react-css-themr';
import { LIST } from '../identifiers.js';

const ListDivider = ({inset, theme}) => (
<hr className={inset ? `${theme.divider} ${theme.inset}` : theme.divider} />
Expand All @@ -17,4 +18,5 @@ ListDivider.defaultProps = {
inset: false
};

export default themr('ToolboxList')(ListDivider);
export default themr(LIST)(ListDivider);
export { ListDivider };
134 changes: 69 additions & 65 deletions components/list/ListItem.js
@@ -1,77 +1,81 @@
import React from 'react';
import { themr } from 'react-css-themr';
import ListItemContent from './ListItemContent';
import ListItemLayout from './ListItemLayout';
import Ripple from '../ripple';
import { LIST } from '../identifiers.js';
import InjectListItemContent from './ListItemContent.js';
import InjectListItemLayout from './ListItemLayout.js';
import rippleFactory from '../ripple/Ripple.js';

class ListItem extends React.Component {
static propTypes = {
children: React.PropTypes.any,
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
onClick: React.PropTypes.func,
ripple: React.PropTypes.bool,
theme: React.PropTypes.shape({
listItem: React.PropTypes.string.isRequired
}),
to: React.PropTypes.string
};

static defaultProps = {
className: '',
disabled: false,
ripple: false
};

handleClick = (event) => {
if (this.props.onClick && !this.props.disabled) {
this.props.onClick(event);
}
};
const factory = (ripple, ListItemLayout, ListItemContent) => {
class ListItem extends React.Component {
static propTypes = {
children: React.PropTypes.any,
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
onClick: React.PropTypes.func,
ripple: React.PropTypes.bool,
theme: React.PropTypes.shape({
listItem: React.PropTypes.string.isRequired
}),
to: React.PropTypes.string
};

groupChildren () {
const children = {
leftActions: [],
rightActions: [],
ignored: []
static defaultProps = {
className: '',
disabled: false,
ripple: false
};

React.Children.forEach(this.props.children, (child, i) => {
if (!React.isValidElement(child)) {
return;
handleClick = (event) => {
if (this.props.onClick && !this.props.disabled) {
this.props.onClick(event);
}
if (child.props.listItemIgnore) {
children.ignored.push(child);
return;
}
if (child.type === ListItemContent) {
children.itemContent = child;
return;
}
const bucket = children.itemContent ? 'rightActions' : 'leftActions';
children[bucket].push({...child, key: i});
});
};

return children;
}
groupChildren () {
const children = {
leftActions: [],
rightActions: [],
ignored: []
};

React.Children.forEach(this.props.children, (child, i) => {
if (!React.isValidElement(child)) {
return;
}
if (child.props.listItemIgnore) {
children.ignored.push(child);
return;
}
if (child.type === ListItemContent) {
children.itemContent = child;
return;
}
const bucket = children.itemContent ? 'rightActions' : 'leftActions';
children[bucket].push({...child, key: i});
});

return children;
}

render () {
const {className, onMouseDown, to, onClick, ripple, theme, ...other} = this.props; //eslint-disable-line no-unused-vars
const children = this.groupChildren();
const content = <ListItemLayout {...children} {...other}/>;
return (
<li className={`${theme.listItem} ${className}`} onClick={this.handleClick} onMouseDown={onMouseDown}>
{to ? <a href={this.props.to}>{content}</a> : content}
{children.ignored}
</li>
);
render () {
const {className, onMouseDown, to, onClick, ripple: hasRipple, theme, ...other} = this.props; //eslint-disable-line no-unused-vars
const children = this.groupChildren();
const content = <ListItemLayout {...children} {...other}/>;
return (
<li className={`${theme.listItem} ${className}`} onClick={this.handleClick} onMouseDown={onMouseDown}>
{to ? <a href={this.props.to}>{content}</a> : content}
{children.ignored}
</li>
);
}
}
}

const RawListItem = themr('ToolboxList')(ListItem);
export default themr('ToolboxList')(Ripple({
centered: false,
listItemIgnore: true
})(ListItem));
return ripple(ListItem);
};

const ripple = rippleFactory({ centered: false, listItemIgnore: true });
const ListItem = factory(ripple, InjectListItemLayout, InjectListItemContent);

export {RawListItem as RawListItem};
export default themr(LIST)(ListItem);
export { factory as listItemFactory };
export { ListItem };
7 changes: 3 additions & 4 deletions components/list/ListItemAction.js
@@ -1,5 +1,6 @@
import React, { PropTypes } from 'react';
import { themr } from 'react-css-themr';
import { LIST } from '../identifiers.js';

const ListItemAction = ({action, theme}) => {
const {onClick, onMouseDown} = action.props;
Expand All @@ -19,7 +20,5 @@ ListItemAction.propTypes = {
})
};

ListItemAction.defaultProps = {
};

export default themr('ToolboxList')(ListItemAction);
export default themr(LIST)(ListItemAction);
export { ListItemAction };

0 comments on commit 592024f

Please sign in to comment.