Add ability to add notebooks and refactor code
This commit is contained in:
parent
03238ad179
commit
d30477bd9d
12 changed files with 518 additions and 97 deletions
142
app/enhance/SelectableEnhance.jsx
Normal file
142
app/enhance/SelectableEnhance.jsx
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import React from 'react';
|
||||
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
|
||||
import StylePropable from 'material-ui/lib/mixins/style-propable';
|
||||
import ColorManipulator from 'material-ui/lib/utils/color-manipulator';
|
||||
|
||||
export const SelectableContainerEnhance = (Component) => {
|
||||
const composed = React.createClass({
|
||||
|
||||
displayName: `Selectable${Component.displayName}`,
|
||||
|
||||
propTypes: {
|
||||
children: React.PropTypes.node,
|
||||
selectedItemStyle: React.PropTypes.object,
|
||||
valueLink: React.PropTypes.shape({
|
||||
value: React.PropTypes.any,
|
||||
requestChange: React.PropTypes.func,
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
contextTypes: {
|
||||
muiTheme: React.PropTypes.object,
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
muiTheme: React.PropTypes.object,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
StylePropable,
|
||||
],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
muiTheme: this.context.muiTheme || getMuiTheme(),
|
||||
};
|
||||
},
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
muiTheme: this.state.muiTheme,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
|
||||
this.setState({muiTheme: newMuiTheme});
|
||||
},
|
||||
|
||||
getValueLink: function(props) {
|
||||
return props.valueLink || {
|
||||
value: props.value,
|
||||
requestChange: props.onChange,
|
||||
};
|
||||
},
|
||||
|
||||
extendChild(child, styles, selectedItemStyle) {
|
||||
if (child && child.type && child.type.displayName === 'ListItem') {
|
||||
let selected = this.isChildSelected(child, this.props);
|
||||
let selectedChildrenStyles = {};
|
||||
if (selected) {
|
||||
selectedChildrenStyles = this.mergeStyles(styles, selectedItemStyle);
|
||||
}
|
||||
|
||||
let mergedChildrenStyles = this.mergeStyles(child.props.style || {}, selectedChildrenStyles);
|
||||
|
||||
this.keyIndex += 1;
|
||||
|
||||
return React.cloneElement(child, {
|
||||
onTouchTap: (e) => {
|
||||
this.handleItemTouchTap(e, child);
|
||||
if (child.props.onTouchTap) {
|
||||
child.props.onTouchTap(e);
|
||||
}
|
||||
},
|
||||
key: this.keyIndex,
|
||||
style: mergedChildrenStyles,
|
||||
nestedItems: child.props.nestedItems.map((child) => this.extendChild(child, styles, selectedItemStyle)),
|
||||
initiallyOpen: this.isInitiallyOpen(child),
|
||||
});
|
||||
} else {
|
||||
var Type = child.type
|
||||
return <Type {...child.props} {...child.state}>{React.Children.map(child.props.children, (childx) => this.extendChild(childx, styles, selectedItemStyle))}</Type>;
|
||||
}
|
||||
},
|
||||
|
||||
isInitiallyOpen(child) {
|
||||
if (child.props.initiallyOpen) {
|
||||
return child.props.initiallyOpen;
|
||||
}
|
||||
return this.hasSelectedDescendant(false, child);
|
||||
},
|
||||
|
||||
hasSelectedDescendant(previousValue, child) {
|
||||
if (React.isValidElement(child) && child.props.nestedItems && child.props.nestedItems.length > 0) {
|
||||
return child.props.nestedItems.reduce(this.hasSelectedDescendant, previousValue);
|
||||
}
|
||||
return previousValue || this.isChildSelected(child, this.props);
|
||||
},
|
||||
|
||||
isChildSelected(child, props) {
|
||||
let itemValue = this.getValueLink(props).value;
|
||||
let childValue = child.props.value;
|
||||
|
||||
return (itemValue === childValue);
|
||||
},
|
||||
|
||||
handleItemTouchTap(e, item) {
|
||||
let valueLink = this.getValueLink(this.props);
|
||||
let itemValue = item.props.value;
|
||||
let menuValue = valueLink.value;
|
||||
if ( itemValue !== menuValue) {
|
||||
valueLink.requestChange(e, itemValue);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const {children, selectedItemStyle} = this.props;
|
||||
this.keyIndex = 0;
|
||||
let styles = {};
|
||||
|
||||
if (!selectedItemStyle) {
|
||||
let textColor = this.state.muiTheme.rawTheme.palette.textColor;
|
||||
let selectedColor = ColorManipulator.fade(textColor, 0.2);
|
||||
styles = {
|
||||
backgroundColor: selectedColor,
|
||||
};
|
||||
}
|
||||
|
||||
let newChildren = React.Children.map(children, (child) => this.extendChild(child, styles, selectedItemStyle));
|
||||
|
||||
return (
|
||||
<Component {...this.props} {...this.state}>
|
||||
{newChildren}
|
||||
</Component>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return composed;
|
||||
};
|
||||
|
||||
export default SelectableContainerEnhance;
|
||||
Loading…
Add table
Add a link
Reference in a new issue