mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-22 09:36:43 +03:00
added theming
This commit is contained in:
parent
50212f88a0
commit
42d4c3f890
|
@ -15,7 +15,6 @@ export function getDefaultStyle(props) {
|
||||||
fontSize: 17,
|
fontSize: 17,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
opacity: 0.92,
|
opacity: 0.92,
|
||||||
background: '#181d20',
|
|
||||||
color: 'white',
|
color: 'white',
|
||||||
left: left ? 0 : undefined,
|
left: left ? 0 : undefined,
|
||||||
right: right ? 0 : undefined,
|
right: right ? 0 : undefined,
|
||||||
|
|
|
@ -15,17 +15,12 @@ const styles = {
|
||||||
label: {
|
label: {
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
display: 'inline-block',
|
display: 'inline-block'
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
},
|
||||||
span: {
|
span: {
|
||||||
color: '#C042DF',
|
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
cursor: 'default'
|
cursor: 'default'
|
||||||
},
|
},
|
||||||
spanExpanded: {
|
|
||||||
color: '#D7D5D8'
|
|
||||||
},
|
|
||||||
spanType: {
|
spanType: {
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
|
@ -64,7 +59,7 @@ export default class JSONArrayNode extends React.Component {
|
||||||
let childNodes = [];
|
let childNodes = [];
|
||||||
if (this.state.expanded && this.needsChildNodes) {
|
if (this.state.expanded && this.needsChildNodes) {
|
||||||
this.props.data.forEach((element, idx) => {
|
this.props.data.forEach((element, idx) => {
|
||||||
childNodes.push(grabNode(idx, element));
|
childNodes.push(grabNode(idx, element, this.props.theme));
|
||||||
});
|
});
|
||||||
this.needsChildNodes = false;
|
this.needsChildNodes = false;
|
||||||
this.renderedChildren = childNodes;
|
this.renderedChildren = childNodes;
|
||||||
|
@ -89,18 +84,26 @@ export default class JSONArrayNode extends React.Component {
|
||||||
listStyle: 'none',
|
listStyle: 'none',
|
||||||
display: (this.state.expanded) ? 'block' : 'none'
|
display: (this.state.expanded) ? 'block' : 'none'
|
||||||
};
|
};
|
||||||
let containerStyle = {...styles.base, ...styles.parentNode};
|
let containerStyle = { ...styles.base, ...styles.parentNode };
|
||||||
let spanStyle = { ...styles.span };
|
let spanStyle = {
|
||||||
|
...styles.span,
|
||||||
|
color: this.props.theme.base0E
|
||||||
|
};
|
||||||
if (this.state.expanded) {
|
if (this.state.expanded) {
|
||||||
spanStyle = {
|
spanStyle = {
|
||||||
...spanStyle,
|
...spanStyle,
|
||||||
...styles.spanExpanded
|
color: this.props.theme.base05
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<li style={containerStyle} onClick={::this.handleClick}>
|
<li style={containerStyle} onClick={::this.handleClick}>
|
||||||
<JSONArrow open={this.state.expanded}/>
|
<JSONArrow theme={this.props.theme} open={this.state.expanded}/>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
<span style={spanStyle}>
|
<span style={spanStyle}>
|
||||||
<span style={styles.spanType}>[]</span>
|
<span style={styles.spanType}>[]</span>
|
||||||
{this.getItemString()}
|
{this.getItemString()}
|
||||||
|
|
|
@ -11,7 +11,8 @@ const styles = {
|
||||||
MozTransition: '150ms',
|
MozTransition: '150ms',
|
||||||
borderLeft: '5px solid transparent',
|
borderLeft: '5px solid transparent',
|
||||||
borderRight: '5px solid transparent',
|
borderRight: '5px solid transparent',
|
||||||
borderTop: '5px solid #39ace6',
|
borderTopWidth: 5,
|
||||||
|
borderTopStyle: 'solid',
|
||||||
WebkitTransform: 'rotateZ(-90deg)',
|
WebkitTransform: 'rotateZ(-90deg)',
|
||||||
MozTransform: 'rotateZ(-90deg)',
|
MozTransform: 'rotateZ(-90deg)',
|
||||||
transform: 'rotateZ(-90deg)'
|
transform: 'rotateZ(-90deg)'
|
||||||
|
@ -25,7 +26,10 @@ const styles = {
|
||||||
|
|
||||||
export default class JSONArrow extends React.Component {
|
export default class JSONArrow extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let style = { ...styles.base };
|
let style = {
|
||||||
|
...styles.base,
|
||||||
|
borderTopColor: this.props.theme.base0C
|
||||||
|
};
|
||||||
if (this.props.open) {
|
if (this.props.open) {
|
||||||
style = {
|
style = {
|
||||||
...style,
|
...style,
|
||||||
|
|
|
@ -12,11 +12,7 @@ const styles = {
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
marginRight: 5,
|
marginRight: 5
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
color: '#08c6eE'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,8 +22,13 @@ export default class JSONBooleanNode extends React.Component {
|
||||||
const truthString = (this.props.value) ? 'true' : 'false';
|
const truthString = (this.props.value) ? 'true' : 'false';
|
||||||
return (
|
return (
|
||||||
<li style={styles.base} onClick={::this.handleClick}>
|
<li style={styles.base} onClick={::this.handleClick}>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
<span style={styles.value}>{truthString}</span>
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
|
<span style={{ color: this.props.theme.base0F }}>{truthString}</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,7 @@ const styles = {
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
marginRight: 5,
|
marginRight: 5
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
color: '#DF113A'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,8 +21,13 @@ export default class JSONNullNode extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<li style={styles.base} onClick={::this.handleClick}>
|
<li style={styles.base} onClick={::this.handleClick}>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
<span style={styles.value}>null</span>
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
|
<span style={{ color: this.props.theme.base08 }}>null</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,7 @@ const styles = {
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
marginRight: 5,
|
marginRight: 5
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
color: '#0B75F5'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,8 +21,13 @@ export default class JSONNumberNode extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<li style={styles.base} onClick={::this.handleClick}>
|
<li style={styles.base} onClick={::this.handleClick}>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
<span style={styles.value}>{this.props.value}</span>
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
|
<span style={{ color: this.props.theme.base09 }}>{this.props.value}</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,12 @@ const styles = {
|
||||||
label: {
|
label: {
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
display: 'inline-block',
|
display: 'inline-block'
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
},
|
||||||
span: {
|
span: {
|
||||||
color: '#049977',
|
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
cursor: 'default'
|
cursor: 'default'
|
||||||
},
|
},
|
||||||
spanExpanded: {
|
|
||||||
color: '#D7D5D8'
|
|
||||||
},
|
|
||||||
spanType: {
|
spanType: {
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
|
@ -65,7 +60,7 @@ export default class JSONObjectNode extends React.Component {
|
||||||
let childNodes = [];
|
let childNodes = [];
|
||||||
for (let k in obj) {
|
for (let k in obj) {
|
||||||
if (obj.hasOwnProperty(k)) {
|
if (obj.hasOwnProperty(k)) {
|
||||||
childNodes.push(grabNode(k, obj[k]));
|
childNodes.push(grabNode(k, obj[k], this.props.theme));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.needsChildNodes = false;
|
this.needsChildNodes = false;
|
||||||
|
@ -91,18 +86,26 @@ export default class JSONObjectNode extends React.Component {
|
||||||
listStyle: 'none',
|
listStyle: 'none',
|
||||||
display: (this.state.expanded) ? 'block' : 'none'
|
display: (this.state.expanded) ? 'block' : 'none'
|
||||||
};
|
};
|
||||||
let containerStyle = {...styles.base, ...styles.parentNode};
|
let containerStyle = { ...styles.base, ...styles.parentNode };
|
||||||
let spanStyle = { ...styles.span };
|
let spanStyle = {
|
||||||
|
...styles.span,
|
||||||
|
color: this.props.theme.base0B
|
||||||
|
};
|
||||||
if (this.state.expanded) {
|
if (this.state.expanded) {
|
||||||
spanStyle = {
|
spanStyle = {
|
||||||
...spanStyle,
|
...spanStyle,
|
||||||
...styles.spanExpanded
|
color: this.props.theme.base05
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<li style={containerStyle} onClick={::this.handleClick}>
|
<li style={containerStyle} onClick={::this.handleClick}>
|
||||||
<JSONArrow open={this.state.expanded}/>
|
<JSONArrow theme={this.props.theme} open={this.state.expanded}/>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
<span style={spanStyle}>
|
<span style={spanStyle}>
|
||||||
<span style={styles.spanType}>{}</span>
|
<span style={styles.spanType}>{}</span>
|
||||||
{this.getItemString()}
|
{this.getItemString()}
|
||||||
|
|
|
@ -12,11 +12,7 @@ const styles = {
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
marginRight: 5,
|
marginRight: 5
|
||||||
color: '#8fa1b2'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
color: '#717c93'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,8 +21,13 @@ export default class JSONStringNode extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<li style={styles.base} onClick={::this.handleClick}>
|
<li style={styles.base} onClick={::this.handleClick}>
|
||||||
<label style={styles.label}>{this.props.keyName}:</label>
|
<label style={{
|
||||||
<span style={styles.value}>{this.props.value}</span>
|
...styles.label,
|
||||||
|
color: this.props.theme.base0D
|
||||||
|
}}>
|
||||||
|
{this.props.keyName}:
|
||||||
|
</label>
|
||||||
|
<span style={{ color: this.props.theme.base0B }}>{this.props.value}</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,21 @@ import JSONNumberNode from './JSONNumberNode';
|
||||||
import JSONBooleanNode from './JSONBooleanNode';
|
import JSONBooleanNode from './JSONBooleanNode';
|
||||||
import JSONNullNode from './JSONNullNode';
|
import JSONNullNode from './JSONNullNode';
|
||||||
|
|
||||||
export default function(key, value) {
|
export default function(key, value, theme) {
|
||||||
const nodeType = objType(value);
|
const nodeType = objType(value);
|
||||||
const aKey = key + Date.now();
|
const aKey = key + Date.now();
|
||||||
if (nodeType === 'Object') {
|
if (nodeType === 'Object') {
|
||||||
return <JSONObjectNode data={value} keyName={key} key={aKey} />;
|
return <JSONObjectNode data={value} theme={theme} keyName={key} key={aKey} />;
|
||||||
} else if (nodeType === 'Array') {
|
} else if (nodeType === 'Array') {
|
||||||
return <JSONArrayNode data={value} keyName={key} key={aKey} />;
|
return <JSONArrayNode data={value} theme={theme} keyName={key} key={aKey} />;
|
||||||
} else if (nodeType === 'String') {
|
} else if (nodeType === 'String') {
|
||||||
return <JSONStringNode keyName={key} value={value} key={aKey} />;
|
return <JSONStringNode keyName={key} theme={theme} value={value} key={aKey} />;
|
||||||
} else if (nodeType === 'Number') {
|
} else if (nodeType === 'Number') {
|
||||||
return <JSONNumberNode keyName={key} value={value} key={aKey} />;
|
return <JSONNumberNode keyName={key} theme={theme} value={value} key={aKey} />;
|
||||||
} else if (nodeType === 'Boolean') {
|
} else if (nodeType === 'Boolean') {
|
||||||
return <JSONBooleanNode keyName={key} value={value} key={aKey} />;
|
return <JSONBooleanNode keyName={key} theme={theme} value={value} key={aKey} />;
|
||||||
} else if (nodeType === 'Null') {
|
} else if (nodeType === 'Null') {
|
||||||
return <JSONNullNode keyName={key} value={value} key={aKey} />;
|
return <JSONNullNode keyName={key} theme={theme} value={value} key={aKey} />;
|
||||||
}
|
}
|
||||||
console.error('Unknown node type:', nodeType);
|
console.error('Unknown node type:', nodeType);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -38,9 +38,9 @@ export default class JSONTree extends React.Component {
|
||||||
let rootNode = false;
|
let rootNode = false;
|
||||||
const keyName = this.props.keyName || 'root';
|
const keyName = this.props.keyName || 'root';
|
||||||
if (nodeType === 'Object') {
|
if (nodeType === 'Object') {
|
||||||
rootNode = <JSONObjectNode data={this.props.data} keyName={keyName} initialExpanded={true} />;
|
rootNode = <JSONObjectNode theme={this.props.theme} data={this.props.data} keyName={keyName} initialExpanded={true} />;
|
||||||
} else if (nodeType === 'Array') {
|
} else if (nodeType === 'Array') {
|
||||||
rootNode = <JSONArrayNode data={this.props.data} initialExpanded={true} keyName={keyName} />;
|
rootNode = <JSONArrayNode theme={this.props.theme} data={this.props.data} initialExpanded={true} keyName={keyName} />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ul style={styles.tree}>
|
<ul style={styles.tree}>
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
import React, { PropTypes, findDOMNode } from 'react';
|
import React, { PropTypes, findDOMNode } from 'react';
|
||||||
import LogMonitorEntry from './LogMonitorEntry';
|
import LogMonitorEntry from './LogMonitorEntry';
|
||||||
import LogMonitorButton from './LogMonitorButton';
|
import LogMonitorButton from './LogMonitorButton';
|
||||||
|
import themes from "./themes";
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
container: {
|
container: {
|
||||||
fontFamily: 'monospace',
|
fontFamily: 'monospace',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflowY: 'hidden'
|
overflowY: 'hidden',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
},
|
},
|
||||||
buttonBarWrapper: {
|
buttonBarWrapper: {
|
||||||
backgroundColor: '#343c45',
|
|
||||||
borderBottom: '1px solid #3f464d',
|
|
||||||
marginBottom: 1
|
marginBottom: 1
|
||||||
},
|
},
|
||||||
buttonBar: {
|
buttonBar: {
|
||||||
paddingLeft: 2
|
paddingLeft: 2
|
||||||
},
|
|
||||||
bordering: {
|
|
||||||
'float': 'left',
|
|
||||||
height: 1,
|
|
||||||
border: '1px solid #20262c',
|
|
||||||
width: '100%'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +43,7 @@ export default class LogMonitor {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
select: (state) => state,
|
select: (state) => state,
|
||||||
monitorState: { isVisible: true },
|
monitorState: { isVisible: true },
|
||||||
|
theme: 'ocean'
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
@ -77,7 +73,6 @@ export default class LogMonitor {
|
||||||
if (this.scrollDown) {
|
if (this.scrollDown) {
|
||||||
const scrollableNode = node.parentElement;
|
const scrollableNode = node.parentElement;
|
||||||
const { offsetHeight, scrollHeight } = scrollableNode;
|
const { offsetHeight, scrollHeight } = scrollableNode;
|
||||||
|
|
||||||
scrollableNode.scrollTop = scrollHeight - offsetHeight;
|
scrollableNode.scrollTop = scrollHeight - offsetHeight;
|
||||||
this.scrollDown = false;
|
this.scrollDown = false;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +113,17 @@ export default class LogMonitor {
|
||||||
render() {
|
render() {
|
||||||
const elements = [];
|
const elements = [];
|
||||||
const { monitorState, skippedActions, stagedActions, computedStates, select } = this.props;
|
const { monitorState, skippedActions, stagedActions, computedStates, select } = this.props;
|
||||||
|
let theme;
|
||||||
|
if (typeof this.props.theme === 'string') {
|
||||||
|
if (typeof themes[this.props.theme] !== 'undefined') {
|
||||||
|
theme = themes[this.props.theme]
|
||||||
|
} else {
|
||||||
|
console.warn('DevTools theme ' + this.props.theme + ' not found, defaulting to ocean');
|
||||||
|
theme = themes.ocean
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theme = this.props.theme;
|
||||||
|
}
|
||||||
if (!monitorState.isVisible) {
|
if (!monitorState.isVisible) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +135,7 @@ export default class LogMonitor {
|
||||||
elements.push(
|
elements.push(
|
||||||
<LogMonitorEntry key={i}
|
<LogMonitorEntry key={i}
|
||||||
index={i}
|
index={i}
|
||||||
|
theme={theme}
|
||||||
select={select}
|
select={select}
|
||||||
action={action}
|
action={action}
|
||||||
state={state}
|
state={state}
|
||||||
|
@ -139,20 +146,22 @@ export default class LogMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={styles.container}>
|
<div style={{...styles.container, backgroundColor: theme.base00}}>
|
||||||
<div style={styles.buttonBarWrapper}>
|
<div style={{
|
||||||
<div style={styles.buttonBar}>
|
...styles.buttonBar,
|
||||||
<LogMonitorButton onClick={::this.handleReset}>Reset</LogMonitorButton>
|
backgroundColor: theme.base01,
|
||||||
{computedStates.length > 1 &&
|
borderBottom: theme.base00
|
||||||
<LogMonitorButton onClick={::this.handleRollback}>Revert</LogMonitorButton>
|
}}>
|
||||||
}
|
<LogMonitorButton theme={theme} onClick={::this.handleReset}>Reset</LogMonitorButton>
|
||||||
{Object.keys(skippedActions).some(key => skippedActions[key]) &&
|
{computedStates.length > 1 &&
|
||||||
<LogMonitorButton onClick={::this.handleSweep}>Sweep</LogMonitorButton>
|
<LogMonitorButton theme={theme} onClick={::this.handleRollback}>Revert</LogMonitorButton>
|
||||||
}
|
}
|
||||||
{computedStates.length > 1 &&
|
{Object.keys(skippedActions).some(key => skippedActions[key]) &&
|
||||||
<LogMonitorButton onClick={::this.handleCommit}>Commit</LogMonitorButton>
|
<LogMonitorButton theme={theme} onClick={::this.handleSweep}>Sweep</LogMonitorButton>
|
||||||
}
|
}
|
||||||
</div>
|
{computedStates.length > 1 &&
|
||||||
|
<LogMonitorButton theme={theme} onClick={::this.handleCommit}>Commit</LogMonitorButton>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div styles={{
|
<div styles={{
|
||||||
overflowX: 'hidden',
|
overflowX: 'hidden',
|
||||||
|
|
|
@ -9,9 +9,6 @@ const styles = {
|
||||||
marginTop: 2,
|
marginTop: 2,
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
fontSize: "0.8em"
|
fontSize: "0.8em"
|
||||||
},
|
|
||||||
active: {
|
|
||||||
backgroundColor: "#252c33"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +44,7 @@ export default class LogMonitorButton extends React.Component {
|
||||||
if (this.state.hovered) {
|
if (this.state.hovered) {
|
||||||
style = {
|
style = {
|
||||||
...style,
|
...style,
|
||||||
...styles.active
|
backgroundColor: this.props.theme.base00
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,38 +2,12 @@ import React, { PropTypes } from 'react';
|
||||||
import JSONTree from './JSONTree';
|
import JSONTree from './JSONTree';
|
||||||
import LogMonitorEntryAction from "./LogMonitorEntryAction";
|
import LogMonitorEntryAction from "./LogMonitorEntryAction";
|
||||||
|
|
||||||
function hsvToRgb(h, s, v) {
|
function colorFromString(theme, token) {
|
||||||
const i = Math.floor(h);
|
|
||||||
const f = h - i;
|
|
||||||
const p = v * (1 - s);
|
|
||||||
const q = v * (1 - f * s);
|
|
||||||
const t = v * (1 - (1 - f) * s);
|
|
||||||
const mod = i % 6;
|
|
||||||
const r = [v, q, p, p, t, v][mod];
|
|
||||||
const g = [t, v, v, q, p, p][mod];
|
|
||||||
const b = [p, p, t, v, v, q][mod];
|
|
||||||
|
|
||||||
return {
|
|
||||||
r: Math.round(r * 255),
|
|
||||||
g: Math.round(g * 255),
|
|
||||||
b: Math.round(b * 255)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function colorFromString(token) {
|
|
||||||
const splitToken = token.split('');
|
const splitToken = token.split('');
|
||||||
const finalToken = splitToken.concat(splitToken.reverse());
|
const finalToken = splitToken.concat(splitToken.reverse());
|
||||||
|
const number = (parseInt(finalToken, 36) + finalToken.length) % 8;
|
||||||
const number = finalToken.reduce(
|
const themeNumber = 'base0' + (number + 8).toString(16).toUpperCase();
|
||||||
(sum, char) => sum + char.charCodeAt(0),
|
return theme[themeNumber];
|
||||||
0
|
|
||||||
) * Math.abs(Math.sin(token.length));
|
|
||||||
|
|
||||||
const h = Math.round((number * (180 / Math.PI) * token.length) % 360);
|
|
||||||
const s = number % 100 / 100;
|
|
||||||
const v = 1;
|
|
||||||
|
|
||||||
return hsvToRgb(h, s, v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
|
@ -58,7 +32,7 @@ export default class LogMonitorEntry {
|
||||||
let errorText = error;
|
let errorText = error;
|
||||||
if (!errorText) {
|
if (!errorText) {
|
||||||
try {
|
try {
|
||||||
return <JSONTree keyName={'state'} data={this.props.select(state)} />
|
return <JSONTree theme={this.props.theme} keyName={'state'} data={this.props.select(state)} />
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorText = 'Error selecting state.';
|
errorText = 'Error selecting state.';
|
||||||
}
|
}
|
||||||
|
@ -82,15 +56,19 @@ export default class LogMonitorEntry {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { index, error, action, state, collapsed } = this.props;
|
const { index, error, action, state, collapsed } = this.props;
|
||||||
const { r, g, b } = colorFromString(action.type);
|
|
||||||
const styleEntry = {
|
const styleEntry = {
|
||||||
opacity: collapsed ? 0.5 : 1,
|
opacity: collapsed ? 0.5 : 1,
|
||||||
color: `rgb(${r}, ${g}, ${b})`,
|
color: colorFromString(this.props.theme, action.type),
|
||||||
cursor: (index > 0) ? 'pointer' : 'default'
|
cursor: (index > 0) ? 'pointer' : 'default'
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{textDecoration: collapsed ? 'line-through' : 'none'}}>
|
<div style={{textDecoration: collapsed ? 'line-through' : 'none'}}>
|
||||||
<LogMonitorEntryAction collapsed={collapsed} action={action} onClick={::this.handleActionClick} style={{...styles.entry, ...styleEntry}}/>
|
<LogMonitorEntryAction
|
||||||
|
theme={this.props.theme}
|
||||||
|
collapsed={collapsed}
|
||||||
|
action={action}
|
||||||
|
onClick={::this.handleActionClick}
|
||||||
|
style={{...styles.entry, ...styleEntry}}/>
|
||||||
{!collapsed &&
|
{!collapsed &&
|
||||||
<div style={{
|
<div style={{
|
||||||
borderBottom: '1px solid #20262c',
|
borderBottom: '1px solid #20262c',
|
||||||
|
|
|
@ -3,9 +3,10 @@ import JSONTree from './JSONTree';
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
backgroundColor: '#343c45',
|
borderTopWidth: 1,
|
||||||
borderTop: '1px solid #3f464d',
|
borderBottomWidth: 1,
|
||||||
borderBottom: '1px solid #3f464d'
|
borderTopStyle: 'solid',
|
||||||
|
borderBottomStyle: 'solid',
|
||||||
},
|
},
|
||||||
actionBar: {
|
actionBar: {
|
||||||
paddingTop: 4,
|
paddingTop: 4,
|
||||||
|
@ -22,14 +23,20 @@ export default class LogMonitorAction extends React.Component {
|
||||||
renderPayload(payload) {
|
renderPayload(payload) {
|
||||||
return (
|
return (
|
||||||
<div style={styles.payload}>
|
<div style={styles.payload}>
|
||||||
{ Object.keys(payload).length > 0 ? <JSONTree keyName={'payload'} data={payload}/> : "" }
|
{ Object.keys(payload).length > 0 ? <JSONTree theme={this.props.theme} keyName={'payload'} data={payload}/> : "" }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { type, ...payload } = this.props.action;
|
const { type, ...payload } = this.props.action;
|
||||||
return (
|
return (
|
||||||
<div style={{...styles.wrapper, ...this.props.style}} onClick={this.props.onClick}>
|
<div style={{
|
||||||
|
...styles.wrapper,
|
||||||
|
backgroundColor: this.props.theme.base01,
|
||||||
|
borderTopColor: this.props.theme.base00,
|
||||||
|
borderBottomColor: this.props.theme.base02,
|
||||||
|
...this.props.style
|
||||||
|
}} onClick={this.props.onClick}>
|
||||||
<div style={styles.actionBar}>{type}</div>
|
<div style={styles.actionBar}>{type}</div>
|
||||||
{!this.props.collapsed ? '' : ''}
|
{!this.props.collapsed ? '' : ''}
|
||||||
</div>
|
</div>
|
||||||
|
|
5
src/react/theme.js
Normal file
5
src/react/theme.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export default {
|
||||||
|
ocean: {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
5
src/react/themes/index.js
Normal file
5
src/react/themes/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import ocean from "./ocean";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
ocean,
|
||||||
|
};
|
20
src/react/themes/ocean.js
Normal file
20
src/react/themes/ocean.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
export default {
|
||||||
|
scheme: 'Ocean',
|
||||||
|
author: 'Chris Kempson (http://chriskempson.com)',
|
||||||
|
base00: '#2b303b',
|
||||||
|
base01: '#343d46',
|
||||||
|
base02: '#4f5b66',
|
||||||
|
base03: '#65737e',
|
||||||
|
base04: '#a7adba',
|
||||||
|
base05: '#c0c5ce',
|
||||||
|
base06: '#dfe1e8',
|
||||||
|
base07: '#eff1f5',
|
||||||
|
base08: '#bf616a',
|
||||||
|
base09: '#d08770',
|
||||||
|
base0A: '#ebcb8b',
|
||||||
|
base0B: '#a3be8c',
|
||||||
|
base0C: '#96b5b4',
|
||||||
|
base0D: '#8fa1b3',
|
||||||
|
base0E: '#b48ead',
|
||||||
|
base0F: '#ab7967'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user