diff --git a/package.json b/package.json index 686d8992..78c1f8bf 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "redux": "^1.0.0 || 1.0.0-rc" }, "dependencies": { + "react-mixin": "^1.7.0", "react-redux": "^0.5.0", "redux": "^1.0.0-rc" } diff --git a/src/react/DebugPanel.js b/src/react/DebugPanel.js index bf888590..3932a8e3 100644 --- a/src/react/DebugPanel.js +++ b/src/react/DebugPanel.js @@ -13,9 +13,8 @@ export function getDefaultStyle(props) { position: 'fixed', zIndex: 10000, fontSize: 17, - overflow: 'auto', - opacity: 0.92, - background: 'black', + overflow: 'hidden', + opacity: 1, color: 'white', left: left ? 0 : undefined, right: right ? 0 : undefined, @@ -23,7 +22,10 @@ export function getDefaultStyle(props) { bottom: bottom ? 0 : undefined, maxHeight: (bottom && top) ? '100%' : '20%', maxWidth: (left && right) ? '100%' : '20%', - wordWrap: 'break-word' + minWidth: 300, + wordWrap: 'break-word', + boxSizing: 'border-box', + boxShadow: '-2px 0 7px 0 rgba(0, 0, 0, 0.5)' }; } diff --git a/src/react/JSONTree/JSONArrayNode.js b/src/react/JSONTree/JSONArrayNode.js new file mode 100644 index 00000000..f4e2f328 --- /dev/null +++ b/src/react/JSONTree/JSONArrayNode.js @@ -0,0 +1,125 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { ExpandedStateHandlerMixin } from './mixins'; +import JSONArrow from './JSONArrow'; +import grabNode from './grab-node'; + +const styles = { + base: { + position: 'relative', + paddingTop: 3, + paddingBottom: 3, + paddingRight: 0, + marginLeft: 14 + }, + label: { + margin: 0, + padding: 0, + display: 'inline-block' + }, + span: { + cursor: 'default' + }, + spanType: { + marginLeft: 5, + marginRight: 5 + } +}; + +@reactMixin.decorate(ExpandedStateHandlerMixin) +export default class JSONArrayNode extends React.Component { + defaultProps = { + data: [], + initialExpanded: false + }; + + // flag to see if we still need to render our child nodes + needsChildNodes = true; + + // cache store for our child nodes + renderedChildren = []; + + // cache store for the number of items string we display + itemString = false; + + constructor(props) { + super(props); + this.state = { + expanded: this.props.initialExpanded, + createdChildNodes: false + }; + } + + // Returns the child nodes for each element in the array. If we have + // generated them previously, we return from cache, otherwise we create + // them. + getChildNodes() { + if (this.state.expanded && this.needsChildNodes) { + let childNodes = []; + this.props.data.forEach((element, idx) => { + let prevData; + if (typeof this.props.previousData !== 'undefined') { + prevData = this.props.previousData[idx]; + } + const node = grabNode(idx, element, prevData, this.props.theme); + if (node !== false) { + childNodes.push(node); + } + }); + this.needsChildNodes = false; + this.renderedChildren = childNodes; + } + return this.renderedChildren; + } + + // Returns the "n Items" string for this node, generating and + // caching it if it hasn't been created yet. + getItemString() { + if (!this.itemString) { + this.itemString = this.props.data.length + ' item' + (this.props.data.length !== 0 ? 's' : ''); + } + return this.itemString; + } + + render() { + const childNodes = this.getChildNodes(); + const childListStyle = { + padding: 0, + margin: 0, + listStyle: 'none', + display: (this.state.expanded) ? 'block' : 'none' + }; + let containerStyle; + let spanStyle = { + ...styles.span, + color: this.props.theme.base0E + }; + containerStyle = { + ...styles.base + }; + if (this.state.expanded) { + spanStyle = { + ...spanStyle, + color: this.props.theme.base03 + }; + } + return ( +
  • + + + + [] + {this.getItemString()} + +
      + {childNodes} +
    +
  • + ); + } +} diff --git a/src/react/JSONTree/JSONArrow.js b/src/react/JSONTree/JSONArrow.js new file mode 100644 index 00000000..4e94a8a8 --- /dev/null +++ b/src/react/JSONTree/JSONArrow.js @@ -0,0 +1,42 @@ +import React from 'react'; + +const styles = { + base: { + display: 'inline-block', + marginLeft: 0, + marginTop: 8, + marginRight: 5, + 'float': 'left', + transition: '150ms', + WebkitTransition: '150ms', + MozTransition: '150ms', + borderLeft: '5px solid transparent', + borderRight: '5px solid transparent', + borderTopWidth: 5, + borderTopStyle: 'solid', + WebkitTransform: 'rotateZ(-90deg)', + MozTransform: 'rotateZ(-90deg)', + transform: 'rotateZ(-90deg)' + }, + open: { + WebkitTransform: 'rotateZ(0deg)', + MozTransform: 'rotateZ(0deg)', + transform: 'rotateZ(0deg)' + } +}; + +export default class JSONArrow extends React.Component { + render() { + let style = { + ...styles.base, + borderTopColor: this.props.theme.base0D + }; + if (this.props.open) { + style = { + ...style, + ...styles.open + }; + } + return
    ; + } +} diff --git a/src/react/JSONTree/JSONBooleanNode.js b/src/react/JSONTree/JSONBooleanNode.js new file mode 100644 index 00000000..73b2ce9f --- /dev/null +++ b/src/react/JSONTree/JSONBooleanNode.js @@ -0,0 +1,40 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { SquashClickEventMixin } from './mixins'; +import hexToRgb from '../../utils/hexToRgb'; + +const styles = { + base: { + paddingTop: 3, + paddingBottom: 3, + paddingRight: 0, + marginLeft: 14 + }, + label: { + display: 'inline-block', + marginRight: 5 + } +}; + +@reactMixin.decorate(SquashClickEventMixin) +export default class JSONBooleanNode extends React.Component { + render() { + const truthString = (this.props.value) ? 'true' : 'false'; + let backgroundColor = 'transparent'; + if (this.props.previousValue !== this.props.value) { + const bgColor = hexToRgb(this.props.theme.base06); + backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; + } + return ( +
  • + + {truthString} +
  • + ); + } +} diff --git a/src/react/JSONTree/JSONNullNode.js b/src/react/JSONTree/JSONNullNode.js new file mode 100644 index 00000000..6e11298a --- /dev/null +++ b/src/react/JSONTree/JSONNullNode.js @@ -0,0 +1,39 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { SquashClickEventMixin } from './mixins'; +import hexToRgb from '../../utils/hexToRgb'; + +const styles = { + base: { + paddingTop: 3, + paddingBottom: 3, + paddingRight: 0, + marginLeft: 14 + }, + label: { + display: 'inline-block', + marginRight: 5 + } +}; + +@reactMixin.decorate(SquashClickEventMixin) +export default class JSONNullNode extends React.Component { + render() { + let backgroundColor = 'transparent'; + if (this.props.previousValue !== this.props.value) { + const bgColor = hexToRgb(this.props.theme.base06); + backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; + } + return ( +
  • + + null +
  • + ); + } +} diff --git a/src/react/JSONTree/JSONNumberNode.js b/src/react/JSONTree/JSONNumberNode.js new file mode 100644 index 00000000..d8b2b9d5 --- /dev/null +++ b/src/react/JSONTree/JSONNumberNode.js @@ -0,0 +1,39 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { SquashClickEventMixin } from './mixins'; +import hexToRgb from '../../utils/hexToRgb'; + +const styles = { + base: { + paddingTop: 3, + paddingBottom: 3, + paddingRight: 0, + marginLeft: 14 + }, + label: { + display: 'inline-block', + marginRight: 5 + } +}; + +@reactMixin.decorate(SquashClickEventMixin) +export default class JSONNumberNode extends React.Component { + render() { + let backgroundColor = 'transparent'; + if (this.props.previousValue !== this.props.value) { + const bgColor = hexToRgb(this.props.theme.base06); + backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; + } + return ( +
  • + + {this.props.value} +
  • + ); + } +} diff --git a/src/react/JSONTree/JSONObjectNode.js b/src/react/JSONTree/JSONObjectNode.js new file mode 100644 index 00000000..a1b55338 --- /dev/null +++ b/src/react/JSONTree/JSONObjectNode.js @@ -0,0 +1,126 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { ExpandedStateHandlerMixin } from './mixins'; +import JSONArrow from './JSONArrow'; +import grabNode from './grab-node'; + +const styles = { + base: { + position: 'relative', + paddingTop: 3, + paddingBottom: 3, + marginLeft: 14 + }, + label: { + margin: 0, + padding: 0, + display: 'inline-block' + }, + span: { + cursor: 'default' + }, + spanType: { + marginLeft: 5, + marginRight: 5 + } +}; + +@reactMixin.decorate(ExpandedStateHandlerMixin) +export default class JSONObjectNode extends React.Component { + defaultProps = { + data: [], + initialExpanded: false + }; + // cache store for the number of items string we display + itemString = false; + + // flag to see if we still need to render our child nodes + needsChildNodes = true; + + // cache store for our child nodes + renderedChildren = []; + + constructor(props) { + super(props); + this.state = { + expanded: this.props.initialExpanded, + createdChildNodes: false + }; + } + + // Returns the child nodes for each element in the object. If we have + // generated them previously, we return from cache, otherwise we create + // them. + getChildNodes() { + if (this.state.expanded && this.needsChildNodes) { + const obj = this.props.data; + let childNodes = []; + for (let k in obj) { + if (obj.hasOwnProperty(k)) { + let prevData; + if (typeof this.props.previousData !== 'undefined') { + prevData = this.props.previousData[k]; + } + const node = grabNode(k, obj[k], prevData, this.props.theme); + if (node !== false) { + childNodes.push(node); + } + } + } + this.needsChildNodes = false; + this.renderedChildren = childNodes; + } + return this.renderedChildren; + } + + // Returns the "n Items" string for this node, generating and + // caching it if it hasn't been created yet. + getItemString() { + if (!this.itemString) { + const len = Object.keys(this.props.data).length; + this.itemString = len + ' key' + (len !== 0 ? 's' : ''); + } + return this.itemString; + } + + render() { + let childListStyle = { + padding: 0, + margin: 0, + listStyle: 'none', + display: (this.state.expanded) ? 'block' : 'none' + }; + let containerStyle; + let spanStyle = { + ...styles.span, + color: this.props.theme.base0B + }; + containerStyle = { + ...styles.base + }; + if (this.state.expanded) { + spanStyle = { + ...spanStyle, + color: this.props.theme.base03 + }; + } + return ( +
  • + + + + {} + {this.getItemString()} + +
      + {this.getChildNodes()} +
    +
  • + ); + } +} diff --git a/src/react/JSONTree/JSONStringNode.js b/src/react/JSONTree/JSONStringNode.js new file mode 100644 index 00000000..d687be37 --- /dev/null +++ b/src/react/JSONTree/JSONStringNode.js @@ -0,0 +1,39 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { SquashClickEventMixin } from './mixins'; +import hexToRgb from '../../utils/hexToRgb'; + +const styles = { + base: { + paddingTop: 3, + paddingBottom: 3, + paddingRight: 0, + marginLeft: 14 + }, + label: { + display: 'inline-block', + marginRight: 5 + } +}; + +@reactMixin.decorate(SquashClickEventMixin) +export default class JSONStringNode extends React.Component { + render() { + let backgroundColor = 'transparent'; + if (this.props.previousValue !== this.props.value) { + const bgColor = hexToRgb(this.props.theme.base06); + backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; + } + return ( +
  • + + "{this.props.value}" +
  • + ); + } +} diff --git a/src/react/JSONTree/grab-node.js b/src/react/JSONTree/grab-node.js new file mode 100644 index 00000000..de69cdb7 --- /dev/null +++ b/src/react/JSONTree/grab-node.js @@ -0,0 +1,27 @@ +import React from 'react'; +import objType from './obj-type'; +import JSONObjectNode from './JSONObjectNode'; +import JSONArrayNode from './JSONArrayNode'; +import JSONStringNode from './JSONStringNode'; +import JSONNumberNode from './JSONNumberNode'; +import JSONBooleanNode from './JSONBooleanNode'; +import JSONNullNode from './JSONNullNode'; + +export default function(key, value, prevValue, theme) { + const nodeType = objType(value); + const aKey = key + Date.now(); + if (nodeType === 'Object') { + return ; + } else if (nodeType === 'Array') { + return ; + } else if (nodeType === 'String') { + return ; + } else if (nodeType === 'Number') { + return ; + } else if (nodeType === 'Boolean') { + return ; + } else if (nodeType === 'Null') { + return ; + } + return false; +} diff --git a/src/react/JSONTree/index.js b/src/react/JSONTree/index.js new file mode 100644 index 00000000..bbac9580 --- /dev/null +++ b/src/react/JSONTree/index.js @@ -0,0 +1,56 @@ +// ES6 + inline style port of JSONViewer https://bitbucket.org/davevedder/react-json-viewer/ +// all credits and original code to the author +// Dave Vedder http://www.eskimospy.com/ +// port by Daniele Zannotti http://www.github.com/dzannotti + +import React from 'react'; +import objectType from './obj-type'; +import JSONObjectNode from './JSONObjectNode'; +import JSONArrayNode from './JSONArrayNode'; + +const styles = { + tree: { + border: 0, + padding: 0, + marginTop: 8, + marginBottom: 8, + marginLeft: 2, + marginRight: 0, + fontSize: '0.90em', + listStyle: 'none', + MozUserSelect: 'none', + WebkitUserSelect: 'none' + } +}; + +export default class JSONTree extends React.Component { + static propTypes = { + data: React.PropTypes.oneOfType([ + React.PropTypes.array, + React.PropTypes.object + ]).isRequired + }; + + constructor(props) { + super(props); + } + + render() { + const nodeType = objectType(this.props.data); + let rootNode = false; + const keyName = this.props.keyName || 'root'; + if (nodeType === 'Object') { + rootNode = ; + } else if (nodeType === 'Array') { + rootNode = ; + } + return ( +
      + {rootNode} +
    + ); + } +} diff --git a/src/react/JSONTree/mixins/expanded-state-handler.js b/src/react/JSONTree/mixins/expanded-state-handler.js new file mode 100644 index 00000000..4cf30c2a --- /dev/null +++ b/src/react/JSONTree/mixins/expanded-state-handler.js @@ -0,0 +1,21 @@ +import deepEqual from '../../../utils/deepEqual'; + +export default { + handleClick(e) { + e.stopPropagation(); + this.setState({ + expanded: !this.state.expanded + }); + }, + + componentWillReceiveProps() { + // resets our caches and flags we need to build child nodes again + this.renderedChildren = []; + this.itemString = false; + this.needsChildNodes = true; + }, + + shouldComponentUpdate(nextProps, nextState) { + return !deepEqual(this.state, nextState) || !deepEqual(this.props, nextProps); + } +}; diff --git a/src/react/JSONTree/mixins/index.js b/src/react/JSONTree/mixins/index.js new file mode 100644 index 00000000..6ee2b386 --- /dev/null +++ b/src/react/JSONTree/mixins/index.js @@ -0,0 +1,2 @@ +export { default as SquashClickEventMixin } from './squash-click-event'; +export { default as ExpandedStateHandlerMixin } from './expanded-state-handler'; diff --git a/src/react/JSONTree/mixins/squash-click-event.js b/src/react/JSONTree/mixins/squash-click-event.js new file mode 100644 index 00000000..233a9864 --- /dev/null +++ b/src/react/JSONTree/mixins/squash-click-event.js @@ -0,0 +1,5 @@ +export default { + handleClick(e) { + e.stopPropagation(); + } +}; diff --git a/src/react/JSONTree/obj-type.js b/src/react/JSONTree/obj-type.js new file mode 100644 index 00000000..e0b964c1 --- /dev/null +++ b/src/react/JSONTree/obj-type.js @@ -0,0 +1,3 @@ +export default function(obj) { + return Object.prototype.toString.call(obj).slice(8, -1); +} diff --git a/src/react/LogMonitor.js b/src/react/LogMonitor.js index d710dcc4..f4c26084 100644 --- a/src/react/LogMonitor.js +++ b/src/react/LogMonitor.js @@ -1,5 +1,35 @@ import React, { PropTypes, findDOMNode } from 'react'; import LogMonitorEntry from './LogMonitorEntry'; +import LogMonitorButton from './LogMonitorButton'; +import * as themes from './themes'; + +const styles = { + container: { + fontFamily: 'monaco, Consolas, Lucida Console, monospace', + position: 'relative', + overflowY: 'hidden', + width: '100%', + height: '100%', + fontSize: '0.95em' + }, + buttonBar: { + textAlign: 'center', + borderBottomWidth: 1, + borderBottomStyle: 'solid', + borderColor: 'transparent', + zIndex: 1, + display: 'flex' + }, + elements: { + position: 'absolute', + left: 0, + right: 0, + top: 38, + bottom: 0, + overflowX: 'hidden', + overflowY: 'auto' + } +}; export default class LogMonitor { constructor() { @@ -26,18 +56,18 @@ export default class LogMonitor { static defaultProps = { select: (state) => state, - monitorState: { isVisible: true } + monitorState: { isVisible: true }, + theme: 'nicinabox' }; componentWillReceiveProps(nextProps) { - const node = findDOMNode(this); + const node = findDOMNode(this.refs.elements); if (!node) { this.scrollDown = true; } else if ( this.props.stagedActions.length < nextProps.stagedActions.length ) { - const scrollableNode = node.parentElement; - const { scrollTop, offsetHeight, scrollHeight } = scrollableNode; + const { scrollTop, offsetHeight, scrollHeight } = node; this.scrollDown = Math.abs( scrollHeight - (scrollTop + offsetHeight) @@ -48,16 +78,13 @@ export default class LogMonitor { } componentDidUpdate() { - const node = findDOMNode(this); + const node = findDOMNode(this.refs.elements); if (!node) { return; } - if (this.scrollDown) { - const scrollableNode = node.parentElement; - const { offsetHeight, scrollHeight } = scrollableNode; - - scrollableNode.scrollTop = scrollHeight - offsetHeight; + const { offsetHeight, scrollHeight } = node; + node.scrollTop = scrollHeight - offsetHeight; this.scrollDown = false; } } @@ -97,7 +124,17 @@ export default class LogMonitor { render() { const elements = []; 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 nicinabox'); + theme = themes.nicinabox; + } + } else { + theme = this.props.theme; + } if (!monitorState.isVisible) { return null; } @@ -105,13 +142,18 @@ export default class LogMonitor { for (let i = 0; i < stagedActions.length; i++) { const action = stagedActions[i]; const { state, error } = computedStates[i]; - + let previousState; + if (i > 0) { + previousState = computedStates[i - 1].state; + } elements.push( @@ -119,52 +161,15 @@ export default class LogMonitor { } return ( -
    -
    -
    - Press Ctrl+H to hide. -
    - +
    +
    + Reset + Revert + skippedActions[key])}>Sweep + 1}>Commit
    - {elements} -
    - {computedStates.length > 1 && - - Rollback - - } - {Object.keys(skippedActions).some(key => skippedActions[key]) && - - {' • '} - - Sweep - - - } - {computedStates.length > 1 && - - - {' • '} - - - Commit - - - } +
    + {elements}
    ); diff --git a/src/react/LogMonitorButton.js b/src/react/LogMonitorButton.js new file mode 100644 index 00000000..545ebc34 --- /dev/null +++ b/src/react/LogMonitorButton.js @@ -0,0 +1,83 @@ +import React from 'react'; +import brighten from '../utils/brighten'; + +const styles = { + base: { + cursor: 'pointer', + fontWeight: 'bold', + borderRadius: 3, + padding: 4, + marginLeft: 3, + marginRight: 3, + marginTop: 5, + marginBottom: 5, + flexGrow: 1, + display: 'inline-block', + fontSize: '0.8em' + } +}; + +export default class LogMonitorButton extends React.Component { + constructor(props) { + super(props); + this.state = { + hovered: false, + active: false + }; + } + + handleMouseEnter() { + this.setState({ hovered: true }); + } + + handleMouseLeave() { + this.setState({ hovered: false }); + } + + handleMouseDown() { + this.setState({ active: true }); + } + + handleMouseUp() { + this.setState({ active: false }); + } + + onClick() { + if (!this.props.enabled) { + return; + } + if (this.props.onClick) { + this.props.onClick(); + } + } + + render() { + let style = { + ...styles.base, + backgroundColor: this.props.theme.base02 + }; + if (this.props.enabled && this.state.hovered) { + style = { + ...style, + backgroundColor: brighten(this.props.theme.base02, 0.2) + }; + } + if (!this.props.enabled) { + style = { + ...style, + opacity: 0.2, + cursor: 'text', + backgroundColor: 'transparent' + } + } + return ( + + {this.props.children} + + ); + } +} diff --git a/src/react/LogMonitorEntry.js b/src/react/LogMonitorEntry.js index 25b4cc83..8934940b 100644 --- a/src/react/LogMonitorEntry.js +++ b/src/react/LogMonitorEntry.js @@ -1,38 +1,16 @@ import React, { PropTypes } from 'react'; +import JSONTree from './JSONTree'; +import LogMonitorEntryAction from './LogMonitorEntryAction'; -function hsvToRgb(h, s, v) { - 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 finalToken = splitToken.concat(splitToken.reverse()); - - const number = finalToken.reduce( - (sum, char) => sum + char.charCodeAt(0), - 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 = { + entry: { + display: 'block', + WebkitUserSelect: 'none' + }, + tree: { + paddingLeft: 0 + } +}; export default class LogMonitorEntry { static propTypes = { @@ -49,15 +27,23 @@ export default class LogMonitorEntry { let errorText = error; if (!errorText) { try { - return JSON.stringify(this.props.select(state)); + return ; } catch (err) { errorText = 'Error selecting state.'; } } - return ( ({errorText}) @@ -73,48 +59,23 @@ export default class LogMonitorEntry { render() { const { index, error, action, state, collapsed } = this.props; - const { r, g, b } = colorFromString(action.type); - + const styleEntry = { + opacity: collapsed ? 0.5 : 1, + cursor: (index > 0) ? 'pointer' : 'default' + }; return ( -
    - 0) ? 'pointer' : 'default', - WebkitUserSelect: 'none' - }}> - {JSON.stringify(action)} - - +
    + {!collapsed && -

    - ⇧ -

    - } - - {!collapsed && -
    +
    {this.printState(state, error)}
    } - -
    ); } diff --git a/src/react/LogMonitorEntryAction.js b/src/react/LogMonitorEntryAction.js new file mode 100644 index 00000000..b459da2a --- /dev/null +++ b/src/react/LogMonitorEntryAction.js @@ -0,0 +1,45 @@ +import React from 'react'; +import JSONTree from './JSONTree'; + +const styles = { + actionBar: { + paddingTop: 8, + paddingBottom: 7, + paddingLeft: 16 + }, + payload: { + margin: 0, + overflow: 'auto' + } +}; + +export default class LogMonitorAction extends React.Component { + + renderPayload(payload) { + return ( +
    + { Object.keys(payload).length > 0 ? : '' } +
    + ); + } + + render() { + const { type, ...payload } = this.props.action; + return ( +
    +
    + {type} +
    + {!this.props.collapsed ? this.renderPayload(payload) : ''} +
    + ); + } +} diff --git a/src/react/theme.js b/src/react/theme.js new file mode 100644 index 00000000..de78238c --- /dev/null +++ b/src/react/theme.js @@ -0,0 +1,5 @@ +export default { + ocean: { + + } +}; diff --git a/src/react/themes/apathy.js b/src/react/themes/apathy.js new file mode 100644 index 00000000..e020afdd --- /dev/null +++ b/src/react/themes/apathy.js @@ -0,0 +1,20 @@ +export default { + scheme: 'apathy', + author: 'jannik siebert (https://github.com/janniks)', + base00: '#031A16', + base01: '#0B342D', + base02: '#184E45', + base03: '#2B685E', + base04: '#5F9C92', + base05: '#81B5AC', + base06: '#A7CEC8', + base07: '#D2E7E4', + base08: '#3E9688', + base09: '#3E7996', + base0A: '#3E4C96', + base0B: '#883E96', + base0C: '#963E4C', + base0D: '#96883E', + base0E: '#4C963E', + base0F: '#3E965B' +}; diff --git a/src/react/themes/ashes.js b/src/react/themes/ashes.js new file mode 100644 index 00000000..e297377c --- /dev/null +++ b/src/react/themes/ashes.js @@ -0,0 +1,20 @@ +export default { + scheme: 'ashes', + author: 'jannik siebert (https://github.com/janniks)', + base00: '#1C2023', + base01: '#393F45', + base02: '#565E65', + base03: '#747C84', + base04: '#ADB3BA', + base05: '#C7CCD1', + base06: '#DFE2E5', + base07: '#F3F4F5', + base08: '#C7AE95', + base09: '#C7C795', + base0A: '#AEC795', + base0B: '#95C7AE', + base0C: '#95AEC7', + base0D: '#AE95C7', + base0E: '#C795AE', + base0F: '#C79595' +}; diff --git a/src/react/themes/atelier-dune.js b/src/react/themes/atelier-dune.js new file mode 100644 index 00000000..0ab20e7e --- /dev/null +++ b/src/react/themes/atelier-dune.js @@ -0,0 +1,20 @@ +export default { + scheme: 'atelier dune', + author: 'bram de haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)', + base00: '#20201d', + base01: '#292824', + base02: '#6e6b5e', + base03: '#7d7a68', + base04: '#999580', + base05: '#a6a28c', + base06: '#e8e4cf', + base07: '#fefbec', + base08: '#d73737', + base09: '#b65611', + base0A: '#cfb017', + base0B: '#60ac39', + base0C: '#1fad83', + base0D: '#6684e1', + base0E: '#b854d4', + base0F: '#d43552' +}; diff --git a/src/react/themes/atelier-forest.js b/src/react/themes/atelier-forest.js new file mode 100644 index 00000000..50ea1369 --- /dev/null +++ b/src/react/themes/atelier-forest.js @@ -0,0 +1,20 @@ +export default { + scheme: 'atelier forest', + author: 'bram de haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest)', + base00: '#1b1918', + base01: '#2c2421', + base02: '#68615e', + base03: '#766e6b', + base04: '#9c9491', + base05: '#a8a19f', + base06: '#e6e2e0', + base07: '#f1efee', + base08: '#f22c40', + base09: '#df5320', + base0A: '#d5911a', + base0B: '#5ab738', + base0C: '#00ad9c', + base0D: '#407ee7', + base0E: '#6666ea', + base0F: '#c33ff3' +}; diff --git a/src/react/themes/atelier-heath.js b/src/react/themes/atelier-heath.js new file mode 100644 index 00000000..1faabf7f --- /dev/null +++ b/src/react/themes/atelier-heath.js @@ -0,0 +1,20 @@ +export default { + scheme: 'atelier heath', + author: 'bram de haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath)', + base00: '#1b181b', + base01: '#292329', + base02: '#695d69', + base03: '#776977', + base04: '#9e8f9e', + base05: '#ab9bab', + base06: '#d8cad8', + base07: '#f7f3f7', + base08: '#ca402b', + base09: '#a65926', + base0A: '#bb8a35', + base0B: '#379a37', + base0C: '#159393', + base0D: '#516aec', + base0E: '#7b59c0', + base0F: '#cc33cc' +}; diff --git a/src/react/themes/atelier-lakeside.js b/src/react/themes/atelier-lakeside.js new file mode 100644 index 00000000..66185731 --- /dev/null +++ b/src/react/themes/atelier-lakeside.js @@ -0,0 +1,20 @@ +export default { + scheme: 'atelier lakeside', + author: 'bram de haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside/)', + base00: '#161b1d', + base01: '#1f292e', + base02: '#516d7b', + base03: '#5a7b8c', + base04: '#7195a8', + base05: '#7ea2b4', + base06: '#c1e4f6', + base07: '#ebf8ff', + base08: '#d22d72', + base09: '#935c25', + base0A: '#8a8a0f', + base0B: '#568c3b', + base0C: '#2d8f6f', + base0D: '#257fad', + base0E: '#5d5db1', + base0F: '#b72dd2' +}; diff --git a/src/react/themes/atelier-seaside.js b/src/react/themes/atelier-seaside.js new file mode 100644 index 00000000..b789a499 --- /dev/null +++ b/src/react/themes/atelier-seaside.js @@ -0,0 +1,20 @@ +export default { + scheme: 'atelier seaside', + author: 'bram de haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside/)', + base00: '#131513', + base01: '#242924', + base02: '#5e6e5e', + base03: '#687d68', + base04: '#809980', + base05: '#8ca68c', + base06: '#cfe8cf', + base07: '#f0fff0', + base08: '#e6193c', + base09: '#87711d', + base0A: '#c3c322', + base0B: '#29a329', + base0C: '#1999b3', + base0D: '#3d62f5', + base0E: '#ad2bee', + base0F: '#e619c3' +}; diff --git a/src/react/themes/bespin.js b/src/react/themes/bespin.js new file mode 100644 index 00000000..bfb7a6bc --- /dev/null +++ b/src/react/themes/bespin.js @@ -0,0 +1,20 @@ +export default { + scheme: 'bespin', + author: 'jan t. sott', + base00: '#28211c', + base01: '#36312e', + base02: '#5e5d5c', + base03: '#666666', + base04: '#797977', + base05: '#8a8986', + base06: '#9d9b97', + base07: '#baae9e', + base08: '#cf6a4c', + base09: '#cf7d34', + base0A: '#f9ee98', + base0B: '#54be0d', + base0C: '#afc4db', + base0D: '#5ea6ea', + base0E: '#9b859d', + base0F: '#937121' +}; diff --git a/src/react/themes/brewer.js b/src/react/themes/brewer.js new file mode 100644 index 00000000..53c17391 --- /dev/null +++ b/src/react/themes/brewer.js @@ -0,0 +1,20 @@ +export default { + scheme: 'brewer', + author: 'timothée poisot (http://github.com/tpoisot)', + base00: '#0c0d0e', + base01: '#2e2f30', + base02: '#515253', + base03: '#737475', + base04: '#959697', + base05: '#b7b8b9', + base06: '#dadbdc', + base07: '#fcfdfe', + base08: '#e31a1c', + base09: '#e6550d', + base0A: '#dca060', + base0B: '#31a354', + base0C: '#80b1d3', + base0D: '#3182bd', + base0E: '#756bb1', + base0F: '#b15928' +}; diff --git a/src/react/themes/bright.js b/src/react/themes/bright.js new file mode 100644 index 00000000..2b76fabd --- /dev/null +++ b/src/react/themes/bright.js @@ -0,0 +1,20 @@ +export default { + scheme: 'bright', + author: 'chris kempson (http://chriskempson.com)', + base00: '#000000', + base01: '#303030', + base02: '#505050', + base03: '#b0b0b0', + base04: '#d0d0d0', + base05: '#e0e0e0', + base06: '#f5f5f5', + base07: '#ffffff', + base08: '#fb0120', + base09: '#fc6d24', + base0A: '#fda331', + base0B: '#a1c659', + base0C: '#76c7b7', + base0D: '#6fb3d2', + base0E: '#d381c3', + base0F: '#be643c' +}; diff --git a/src/react/themes/chalk.js b/src/react/themes/chalk.js new file mode 100644 index 00000000..3d4359bb --- /dev/null +++ b/src/react/themes/chalk.js @@ -0,0 +1,20 @@ +export default { + scheme: 'chalk', + author: 'chris kempson (http://chriskempson.com)', + base00: '#151515', + base01: '#202020', + base02: '#303030', + base03: '#505050', + base04: '#b0b0b0', + base05: '#d0d0d0', + base06: '#e0e0e0', + base07: '#f5f5f5', + base08: '#fb9fb1', + base09: '#eda987', + base0A: '#ddb26f', + base0B: '#acc267', + base0C: '#12cfc0', + base0D: '#6fc2ef', + base0E: '#e1a3ee', + base0F: '#deaf8f' +}; diff --git a/src/react/themes/codeschool.js b/src/react/themes/codeschool.js new file mode 100644 index 00000000..4911e9e8 --- /dev/null +++ b/src/react/themes/codeschool.js @@ -0,0 +1,20 @@ +export default { + scheme: 'codeschool', + author: 'brettof86', + base00: '#232c31', + base01: '#1c3657', + base02: '#2a343a', + base03: '#3f4944', + base04: '#84898c', + base05: '#9ea7a6', + base06: '#a7cfa3', + base07: '#b5d8f6', + base08: '#2a5491', + base09: '#43820d', + base0A: '#a03b1e', + base0B: '#237986', + base0C: '#b02f30', + base0D: '#484d79', + base0E: '#c59820', + base0F: '#c98344' +}; diff --git a/src/react/themes/colors.js b/src/react/themes/colors.js new file mode 100644 index 00000000..17e96fee --- /dev/null +++ b/src/react/themes/colors.js @@ -0,0 +1,20 @@ +export default { + scheme: 'colors', + author: 'mrmrs (http://clrs.cc)', + base00: '#111111', + base01: '#333333', + base02: '#555555', + base03: '#777777', + base04: '#999999', + base05: '#bbbbbb', + base06: '#dddddd', + base07: '#ffffff', + base08: '#ff4136', + base09: '#ff851b', + base0A: '#ffdc00', + base0B: '#2ecc40', + base0C: '#7fdbff', + base0D: '#0074d9', + base0E: '#b10dc9', + base0F: '#85144b' +}; diff --git a/src/react/themes/default.js b/src/react/themes/default.js new file mode 100644 index 00000000..c8831510 --- /dev/null +++ b/src/react/themes/default.js @@ -0,0 +1,20 @@ +export default { + scheme: 'default', + author: 'chris kempson (http://chriskempson.com)', + base00: '#181818', + base01: '#282828', + base02: '#383838', + base03: '#585858', + base04: '#b8b8b8', + base05: '#d8d8d8', + base06: '#e8e8e8', + base07: '#f8f8f8', + base08: '#ab4642', + base09: '#dc9656', + base0A: '#f7ca88', + base0B: '#a1b56c', + base0C: '#86c1b9', + base0D: '#7cafc2', + base0E: '#ba8baf', + base0F: '#a16946' +}; diff --git a/src/react/themes/eighties.js b/src/react/themes/eighties.js new file mode 100644 index 00000000..0dfc3a7d --- /dev/null +++ b/src/react/themes/eighties.js @@ -0,0 +1,20 @@ +export default { + scheme: 'eighties', + author: 'chris kempson (http://chriskempson.com)', + base00: '#2d2d2d', + base01: '#393939', + base02: '#515151', + base03: '#747369', + base04: '#a09f93', + base05: '#d3d0c8', + base06: '#e8e6df', + base07: '#f2f0ec', + base08: '#f2777a', + base09: '#f99157', + base0A: '#ffcc66', + base0B: '#99cc99', + base0C: '#66cccc', + base0D: '#6699cc', + base0E: '#cc99cc', + base0F: '#d27b53' +}; diff --git a/src/react/themes/embers.js b/src/react/themes/embers.js new file mode 100644 index 00000000..14398a09 --- /dev/null +++ b/src/react/themes/embers.js @@ -0,0 +1,20 @@ +export default { + scheme: 'embers', + author: 'jannik siebert (https://github.com/janniks)', + base00: '#16130F', + base01: '#2C2620', + base02: '#433B32', + base03: '#5A5047', + base04: '#8A8075', + base05: '#A39A90', + base06: '#BEB6AE', + base07: '#DBD6D1', + base08: '#826D57', + base09: '#828257', + base0A: '#6D8257', + base0B: '#57826D', + base0C: '#576D82', + base0D: '#6D5782', + base0E: '#82576D', + base0F: '#825757' +}; diff --git a/src/react/themes/flat.js b/src/react/themes/flat.js new file mode 100644 index 00000000..333e8a48 --- /dev/null +++ b/src/react/themes/flat.js @@ -0,0 +1,20 @@ +export default { + scheme: 'flat', + author: 'chris kempson (http://chriskempson.com)', + base00: '#2C3E50', + base01: '#34495E', + base02: '#7F8C8D', + base03: '#95A5A6', + base04: '#BDC3C7', + base05: '#e0e0e0', + base06: '#f5f5f5', + base07: '#ECF0F1', + base08: '#E74C3C', + base09: '#E67E22', + base0A: '#F1C40F', + base0B: '#2ECC71', + base0C: '#1ABC9C', + base0D: '#3498DB', + base0E: '#9B59B6', + base0F: '#be643c' +}; diff --git a/src/react/themes/google.js b/src/react/themes/google.js new file mode 100644 index 00000000..c2f1d57a --- /dev/null +++ b/src/react/themes/google.js @@ -0,0 +1,20 @@ +export default { + scheme: 'google', + author: 'seth wright (http://sethawright.com)', + base00: '#1d1f21', + base01: '#282a2e', + base02: '#373b41', + base03: '#969896', + base04: '#b4b7b4', + base05: '#c5c8c6', + base06: '#e0e0e0', + base07: '#ffffff', + base08: '#CC342B', + base09: '#F96A38', + base0A: '#FBA922', + base0B: '#198844', + base0C: '#3971ED', + base0D: '#3971ED', + base0E: '#A36AC7', + base0F: '#3971ED' +}; diff --git a/src/react/themes/grayscale.js b/src/react/themes/grayscale.js new file mode 100644 index 00000000..2aeec11d --- /dev/null +++ b/src/react/themes/grayscale.js @@ -0,0 +1,20 @@ +export default { + scheme: 'grayscale', + author: 'alexandre gavioli (https://github.com/alexx2/)', + base00: '#101010', + base01: '#252525', + base02: '#464646', + base03: '#525252', + base04: '#ababab', + base05: '#b9b9b9', + base06: '#e3e3e3', + base07: '#f7f7f7', + base08: '#7c7c7c', + base09: '#999999', + base0A: '#a0a0a0', + base0B: '#8e8e8e', + base0C: '#868686', + base0D: '#686868', + base0E: '#747474', + base0F: '#5e5e5e' +}; diff --git a/src/react/themes/greenscreen.js b/src/react/themes/greenscreen.js new file mode 100644 index 00000000..75e2430e --- /dev/null +++ b/src/react/themes/greenscreen.js @@ -0,0 +1,20 @@ +export default { + scheme: 'green screen', + author: 'chris kempson (http://chriskempson.com)', + base00: '#001100', + base01: '#003300', + base02: '#005500', + base03: '#007700', + base04: '#009900', + base05: '#00bb00', + base06: '#00dd00', + base07: '#00ff00', + base08: '#007700', + base09: '#009900', + base0A: '#007700', + base0B: '#00bb00', + base0C: '#005500', + base0D: '#009900', + base0E: '#00bb00', + base0F: '#005500' +}; diff --git a/src/react/themes/harmonic.js b/src/react/themes/harmonic.js new file mode 100644 index 00000000..665d0476 --- /dev/null +++ b/src/react/themes/harmonic.js @@ -0,0 +1,20 @@ +export default { + scheme: 'harmonic16', + author: 'jannik siebert (https://github.com/janniks)', + base00: '#0b1c2c', + base01: '#223b54', + base02: '#405c79', + base03: '#627e99', + base04: '#aabcce', + base05: '#cbd6e2', + base06: '#e5ebf1', + base07: '#f7f9fb', + base08: '#bf8b56', + base09: '#bfbf56', + base0A: '#8bbf56', + base0B: '#56bf8b', + base0C: '#568bbf', + base0D: '#8b56bf', + base0E: '#bf568b', + base0F: '#bf5656' +}; diff --git a/src/react/themes/hopscotch.js b/src/react/themes/hopscotch.js new file mode 100644 index 00000000..4eca7b8c --- /dev/null +++ b/src/react/themes/hopscotch.js @@ -0,0 +1,20 @@ +export default { + scheme: 'hopscotch', + author: 'jan t. sott', + base00: '#322931', + base01: '#433b42', + base02: '#5c545b', + base03: '#797379', + base04: '#989498', + base05: '#b9b5b8', + base06: '#d5d3d5', + base07: '#ffffff', + base08: '#dd464c', + base09: '#fd8b19', + base0A: '#fdcc59', + base0B: '#8fc13e', + base0C: '#149b93', + base0D: '#1290bf', + base0E: '#c85e7c', + base0F: '#b33508' +}; diff --git a/src/react/themes/index.js b/src/react/themes/index.js new file mode 100644 index 00000000..ca0660f9 --- /dev/null +++ b/src/react/themes/index.js @@ -0,0 +1,38 @@ +export { default as threezerotwofour } from './threezerotwofour'; +export { default as apathy } from './apathy'; +export { default as ashes } from './ashes'; +export { default as atelierDune } from './atelier-dune'; +export { default as atelierForest } from './atelier-forest'; +export { default as atelierHeath } from './atelier-heath'; +export { default as atelierLakeside } from './atelier-lakeside'; +export { default as atelierSeaside } from './atelier-seaside'; +export { default as bespin } from './bespin'; +export { default as brewer } from './brewer'; +export { default as bright } from './bright'; +export { default as chalk } from './chalk'; +export { default as codeschool } from './codeschool'; +export { default as colors } from './colors'; +export { default as default } from './default'; +export { default as eighties } from './eighties'; +export { default as embers } from './embers'; +export { default as flat } from './flat'; +export { default as google } from './google'; +export { default as grayscale } from './grayscale'; +export { default as greenscreen } from './greenscreen'; +export { default as harmonic } from './harmonic'; +export { default as hopscotch } from './hopscotch'; +export { default as isotope } from './isotope'; +export { default as marrakesh } from './marrakesh'; +export { default as mocha } from './mocha'; +export { default as monokai } from './monokai'; +export { default as ocean } from './ocean'; +export { default as paraiso } from './paraiso'; +export { default as pop } from './pop'; +export { default as railscasts } from './railscasts'; +export { default as shapeshifter } from './shapeshifter'; +export { default as solarized } from './solarized'; +export { default as summerfruit } from './summerfruit'; +export { default as tomorrow } from './tomorrow'; +export { default as tube } from './tube'; +export { default as twilight } from './twilight'; +export { default as nicinabox } from './nicinabox'; diff --git a/src/react/themes/isotope.js b/src/react/themes/isotope.js new file mode 100644 index 00000000..484524f0 --- /dev/null +++ b/src/react/themes/isotope.js @@ -0,0 +1,20 @@ +export default { + scheme: 'isotope', + author: 'jan t. sott', + base00: '#000000', + base01: '#404040', + base02: '#606060', + base03: '#808080', + base04: '#c0c0c0', + base05: '#d0d0d0', + base06: '#e0e0e0', + base07: '#ffffff', + base08: '#ff0000', + base09: '#ff9900', + base0A: '#ff0099', + base0B: '#33ff00', + base0C: '#00ffff', + base0D: '#0066ff', + base0E: '#cc00ff', + base0F: '#3300ff' +}; diff --git a/src/react/themes/marrakesh.js b/src/react/themes/marrakesh.js new file mode 100644 index 00000000..ca2ef0df --- /dev/null +++ b/src/react/themes/marrakesh.js @@ -0,0 +1,20 @@ +export default { + scheme: 'marrakesh', + author: 'alexandre gavioli (http://github.com/alexx2/)', + base00: '#201602', + base01: '#302e00', + base02: '#5f5b17', + base03: '#6c6823', + base04: '#86813b', + base05: '#948e48', + base06: '#ccc37a', + base07: '#faf0a5', + base08: '#c35359', + base09: '#b36144', + base0A: '#a88339', + base0B: '#18974e', + base0C: '#75a738', + base0D: '#477ca1', + base0E: '#8868b3', + base0F: '#b3588e' +}; diff --git a/src/react/themes/mocha.js b/src/react/themes/mocha.js new file mode 100644 index 00000000..9c86e910 --- /dev/null +++ b/src/react/themes/mocha.js @@ -0,0 +1,20 @@ +export default { + scheme: 'mocha', + author: 'chris kempson (http://chriskempson.com)', + base00: '#3B3228', + base01: '#534636', + base02: '#645240', + base03: '#7e705a', + base04: '#b8afad', + base05: '#d0c8c6', + base06: '#e9e1dd', + base07: '#f5eeeb', + base08: '#cb6077', + base09: '#d28b71', + base0A: '#f4bc87', + base0B: '#beb55b', + base0C: '#7bbda4', + base0D: '#8ab3b5', + base0E: '#a89bb9', + base0F: '#bb9584' +}; diff --git a/src/react/themes/monokai.js b/src/react/themes/monokai.js new file mode 100644 index 00000000..298fc861 --- /dev/null +++ b/src/react/themes/monokai.js @@ -0,0 +1,20 @@ +export default { + scheme: 'monokai', + author: 'wimer hazenberg (http://www.monokai.nl)', + base00: '#272822', + base01: '#383830', + base02: '#49483e', + base03: '#75715e', + base04: '#a59f85', + base05: '#f8f8f2', + base06: '#f5f4f1', + base07: '#f9f8f5', + base08: '#f92672', + base09: '#fd971f', + base0A: '#f4bf75', + base0B: '#a6e22e', + base0C: '#a1efe4', + base0D: '#66d9ef', + base0E: '#ae81ff', + base0F: '#cc6633' +}; diff --git a/src/react/themes/nicinabox.js b/src/react/themes/nicinabox.js new file mode 100644 index 00000000..0b1cdd36 --- /dev/null +++ b/src/react/themes/nicinabox.js @@ -0,0 +1,20 @@ +export default { + scheme: 'nicinabox', + author: 'nicinabox (http://github.com/nicinabox)', + base00: '#2A2F3A', + base01: '#3C444F', + base02: '#4F5A65', + base03: '#BEBEBE', + base04: '#b0b0b0', // unmodified + base05: '#d0d0d0', // unmodified + base06: '#FFFFFF', + base07: '#f5f5f5', // unmodified + base08: '#fb9fb1', // unmodified + base09: '#FC6D24', + base0A: '#ddb26f', // unmodified + base0B: '#A1C659', + base0C: '#12cfc0', // unmodified + base0D: '#6FB3D2', + base0E: '#D381C3', + base0F: '#deaf8f' // unmodified +}; diff --git a/src/react/themes/ocean.js b/src/react/themes/ocean.js new file mode 100644 index 00000000..d3143b29 --- /dev/null +++ b/src/react/themes/ocean.js @@ -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' +}; diff --git a/src/react/themes/paraiso.js b/src/react/themes/paraiso.js new file mode 100644 index 00000000..4d89e01a --- /dev/null +++ b/src/react/themes/paraiso.js @@ -0,0 +1,20 @@ +export default { + scheme: 'paraiso', + author: 'jan t. sott', + base00: '#2f1e2e', + base01: '#41323f', + base02: '#4f424c', + base03: '#776e71', + base04: '#8d8687', + base05: '#a39e9b', + base06: '#b9b6b0', + base07: '#e7e9db', + base08: '#ef6155', + base09: '#f99b15', + base0A: '#fec418', + base0B: '#48b685', + base0C: '#5bc4bf', + base0D: '#06b6ef', + base0E: '#815ba4', + base0F: '#e96ba8' +}; diff --git a/src/react/themes/pop.js b/src/react/themes/pop.js new file mode 100644 index 00000000..29daefeb --- /dev/null +++ b/src/react/themes/pop.js @@ -0,0 +1,20 @@ +export default { + scheme: 'pop', + author: 'chris kempson (http://chriskempson.com)', + base00: '#000000', + base01: '#202020', + base02: '#303030', + base03: '#505050', + base04: '#b0b0b0', + base05: '#d0d0d0', + base06: '#e0e0e0', + base07: '#ffffff', + base08: '#eb008a', + base09: '#f29333', + base0A: '#f8ca12', + base0B: '#37b349', + base0C: '#00aabb', + base0D: '#0e5a94', + base0E: '#b31e8d', + base0F: '#7a2d00' +}; diff --git a/src/react/themes/railscasts.js b/src/react/themes/railscasts.js new file mode 100644 index 00000000..2f914042 --- /dev/null +++ b/src/react/themes/railscasts.js @@ -0,0 +1,20 @@ +export default { + scheme: 'railscasts', + author: 'ryan bates (http://railscasts.com)', + base00: '#2b2b2b', + base01: '#272935', + base02: '#3a4055', + base03: '#5a647e', + base04: '#d4cfc9', + base05: '#e6e1dc', + base06: '#f4f1ed', + base07: '#f9f7f3', + base08: '#da4939', + base09: '#cc7833', + base0A: '#ffc66d', + base0B: '#a5c261', + base0C: '#519f50', + base0D: '#6d9cbe', + base0E: '#b6b3eb', + base0F: '#bc9458' +}; diff --git a/src/react/themes/shapeshifter.js b/src/react/themes/shapeshifter.js new file mode 100644 index 00000000..f6d99e02 --- /dev/null +++ b/src/react/themes/shapeshifter.js @@ -0,0 +1,20 @@ +export default { + scheme: 'shapeshifter', + author: 'tyler benziger (http://tybenz.com)', + base00: '#000000', + base01: '#040404', + base02: '#102015', + base03: '#343434', + base04: '#555555', + base05: '#ababab', + base06: '#e0e0e0', + base07: '#f9f9f9', + base08: '#e92f2f', + base09: '#e09448', + base0A: '#dddd13', + base0B: '#0ed839', + base0C: '#23edda', + base0D: '#3b48e3', + base0E: '#f996e2', + base0F: '#69542d' +}; diff --git a/src/react/themes/solarized.js b/src/react/themes/solarized.js new file mode 100644 index 00000000..b601e859 --- /dev/null +++ b/src/react/themes/solarized.js @@ -0,0 +1,20 @@ +export default { + scheme: 'solarized', + author: 'ethan schoonover (http://ethanschoonover.com/solarized)', + base00: '#002b36', + base01: '#073642', + base02: '#586e75', + base03: '#657b83', + base04: '#839496', + base05: '#93a1a1', + base06: '#eee8d5', + base07: '#fdf6e3', + base08: '#dc322f', + base09: '#cb4b16', + base0A: '#b58900', + base0B: '#859900', + base0C: '#2aa198', + base0D: '#268bd2', + base0E: '#6c71c4', + base0F: '#d33682' +}; diff --git a/src/react/themes/summerfruit.js b/src/react/themes/summerfruit.js new file mode 100644 index 00000000..ff9fe944 --- /dev/null +++ b/src/react/themes/summerfruit.js @@ -0,0 +1,20 @@ +export default { + scheme: 'summerfruit', + author: 'christopher corley (http://cscorley.github.io/)', + base00: '#151515', + base01: '#202020', + base02: '#303030', + base03: '#505050', + base04: '#B0B0B0', + base05: '#D0D0D0', + base06: '#E0E0E0', + base07: '#FFFFFF', + base08: '#FF0086', + base09: '#FD8900', + base0A: '#ABA800', + base0B: '#00C918', + base0C: '#1faaaa', + base0D: '#3777E6', + base0E: '#AD00A1', + base0F: '#cc6633' +}; diff --git a/src/react/themes/threezerotwofour.js b/src/react/themes/threezerotwofour.js new file mode 100644 index 00000000..f0c7de32 --- /dev/null +++ b/src/react/themes/threezerotwofour.js @@ -0,0 +1,20 @@ +export default { + scheme: 'threezerotwofour', + author: 'jan t. sott (http://github.com/idleberg)', + base00: '#090300', + base01: '#3a3432', + base02: '#4a4543', + base03: '#5c5855', + base04: '#807d7c', + base05: '#a5a2a2', + base06: '#d6d5d4', + base07: '#f7f7f7', + base08: '#db2d20', + base09: '#e8bbd0', + base0A: '#fded02', + base0B: '#01a252', + base0C: '#b5e4f4', + base0D: '#01a0e4', + base0E: '#a16a94', + base0F: '#cdab53' +}; diff --git a/src/react/themes/tomorrow.js b/src/react/themes/tomorrow.js new file mode 100644 index 00000000..9dd69015 --- /dev/null +++ b/src/react/themes/tomorrow.js @@ -0,0 +1,20 @@ +export default { + scheme: 'tomorrow', + author: 'chris kempson (http://chriskempson.com)', + base00: '#1d1f21', + base01: '#282a2e', + base02: '#373b41', + base03: '#969896', + base04: '#b4b7b4', + base05: '#c5c8c6', + base06: '#e0e0e0', + base07: '#ffffff', + base08: '#cc6666', + base09: '#de935f', + base0A: '#f0c674', + base0B: '#b5bd68', + base0C: '#8abeb7', + base0D: '#81a2be', + base0E: '#b294bb', + base0F: '#a3685a' +}; diff --git a/src/react/themes/tube.js b/src/react/themes/tube.js new file mode 100644 index 00000000..d0bfe87c --- /dev/null +++ b/src/react/themes/tube.js @@ -0,0 +1,20 @@ +export default { + scheme: 'london tube', + author: 'jan t. sott', + base00: '#231f20', + base01: '#1c3f95', + base02: '#5a5758', + base03: '#737171', + base04: '#959ca1', + base05: '#d9d8d8', + base06: '#e7e7e8', + base07: '#ffffff', + base08: '#ee2e24', + base09: '#f386a1', + base0A: '#ffd204', + base0B: '#00853e', + base0C: '#85cebc', + base0D: '#009ddc', + base0E: '#98005d', + base0F: '#b06110' +}; diff --git a/src/react/themes/twilight.js b/src/react/themes/twilight.js new file mode 100644 index 00000000..d0423a2c --- /dev/null +++ b/src/react/themes/twilight.js @@ -0,0 +1,20 @@ +export default { + scheme: 'twilight', + author: 'david hart (http://hart-dev.com)', + base00: '#1e1e1e', + base01: '#323537', + base02: '#464b50', + base03: '#5f5a60', + base04: '#838184', + base05: '#a7a7a7', + base06: '#c3c3c3', + base07: '#ffffff', + base08: '#cf6a4c', + base09: '#cda869', + base0A: '#f9ee98', + base0B: '#8f9d6a', + base0C: '#afc4db', + base0D: '#7587a6', + base0E: '#9b859d', + base0F: '#9b703f' +}; diff --git a/src/utils/brighten.js b/src/utils/brighten.js new file mode 100644 index 00000000..c6aa01ee --- /dev/null +++ b/src/utils/brighten.js @@ -0,0 +1,16 @@ +export default function(hex, lum) { + hex = String(hex).replace(/[^0-9a-f]/gi, ""); + if (hex.length < 6) { + hex = hex.replace(/(.)/g, '$1$1'); + } + lum = lum || 0; + + var rgb = "#", + c; + for (var i = 0; i < 3; ++i) { + c = parseInt(hex.substr(i * 2, 2), 16); + c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16); + rgb += ("00" + c).substr(c.length); + } + return rgb; +}; diff --git a/src/utils/deepEqual.js b/src/utils/deepEqual.js new file mode 100644 index 00000000..847c4472 --- /dev/null +++ b/src/utils/deepEqual.js @@ -0,0 +1,22 @@ +function deepEqual(x, y) { + if ((typeof x === 'object' && x !== null) && (typeof y === 'object' && y !== null)) { + if (Object.keys(x).length !== Object.keys(y).length) { + return false; + } + for (let prop in x) { + if (y.hasOwnProperty(prop)) { + if (!deepEqual(x[prop], y[prop])) { + return false; + } + } else { + return false; + } + } + return true; + } else if (x !== y) { + return false; + } + return true; +} + +export default deepEqual; diff --git a/src/utils/hexToRgb.js b/src/utils/hexToRgb.js new file mode 100644 index 00000000..af007856 --- /dev/null +++ b/src/utils/hexToRgb.js @@ -0,0 +1,8 @@ +export default function(hex) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; +}