diff --git a/examples/counter/package.json b/examples/counter/package.json
index 029efc70..2e82f7a4 100644
--- a/examples/counter/package.json
+++ b/examples/counter/package.json
@@ -28,8 +28,8 @@
"node-libs-browser": "^0.5.2",
"react-dock": "^0.1.0",
"react-hot-loader": "^1.3.0",
- "redux-devtools": "^3.0.0-alpha-7",
- "redux-devtools-log-monitor": "^1.0.0-alpha-7",
+ "redux-devtools": "^3.0.0-alpha-8",
+ "redux-devtools-log-monitor": "^1.0.0-alpha-8",
"webpack": "^1.9.11",
"webpack-dev-server": "^1.9.0"
}
diff --git a/examples/counter/src/containers/DevTools.js b/examples/counter/src/containers/DevTools.js
index 4ef74abb..d1b15355 100644
--- a/examples/counter/src/containers/DevTools.js
+++ b/examples/counter/src/containers/DevTools.js
@@ -1,9 +1,10 @@
+import React from 'react';
import { createDevTools } from 'redux-devtools';
-import createLogMonitor from 'redux-devtools-log-monitor';
-import createDockMonitor from '../dock/DockMonitor';
+import LogMonitor from 'redux-devtools-log-monitor';
+import DockMonitor from '../dock/DockMonitor';
export default createDevTools(
- createDockMonitor(
- createLogMonitor()
- )
+
+
+
);
diff --git a/examples/counter/src/dock/DockMonitor.js b/examples/counter/src/dock/DockMonitor.js
index f9a308f8..147be38d 100644
--- a/examples/counter/src/dock/DockMonitor.js
+++ b/examples/counter/src/dock/DockMonitor.js
@@ -2,24 +2,36 @@
// TODO: extract to a separate project.
//
-import React, { Component, PropTypes } from 'react';
+import React, { cloneElement, Children, Component, PropTypes } from 'react';
import Dock from 'react-dock';
import { combineReducers } from 'redux';
const POSITIONS = ['left', 'top', 'right', 'bottom'];
-class DockMonitor extends Component {
+export default class DockMonitor extends Component {
static propTypes = {
+ defaultPosition: PropTypes.oneOf(POSITIONS).isRequired,
+ defaultIsVisible: PropTypes.bool.isRequired,
+ toggleVisibilityShortcut: PropTypes.string.isRequired,
+ changePositionShortcut: PropTypes.string.isRequired,
+
monitorState: PropTypes.shape({
position: PropTypes.oneOf(POSITIONS).isRequired,
isVisible: PropTypes.bool.isRequired,
child: PropTypes.any
- }).isRequired,
+ }),
monitorActions: PropTypes.shape({
toggleVisibility: PropTypes.func.isRequired,
changePosition: PropTypes.func.isRequired
- }).isRequired
+ })
+ };
+
+ static defaultProps = {
+ defaultIsVisible: true,
+ defaultPosition: 'right',
+ toggleVisibilityShortcut: 'H',
+ changePositionShortcut: 'Q'
};
componentDidMount() {
@@ -39,11 +51,11 @@ class DockMonitor extends Component {
const key = event.keyCode || event.which;
const char = String.fromCharCode(key);
- switch (char) {
- case 'H':
+ switch (char.toUpperCase()) {
+ case this.props.toggleVisibilityShortcut.toUpperCase():
this.props.monitorActions.toggleVisibility();
break;
- case 'D':
+ case this.props.changePositionShortcut.toUpperCase():
this.props.monitorActions.changePosition();
break;
default:
@@ -52,13 +64,29 @@ class DockMonitor extends Component {
}
render() {
- const { children, monitorState } = this.props;
- const { position, isVisible } = monitorState;
+ const {
+ monitorState,
+ monitorActions,
+ historyState,
+ historyActions,
+ children
+ } = this.props;
+
+ const {
+ position,
+ isVisible
+ } = monitorState;
+
return (
- {children}
+ {cloneElement(Children.only(children), {
+ monitorState: monitorState.child,
+ monitorActions: monitorActions.child,
+ historyState,
+ historyActions
+ })}
);
}
@@ -74,43 +102,32 @@ function changePosition() {
return { type: CHANGE_POSITION };
}
-export default function create(child, {
- defaultIsVisible = true,
- defaultPosition = 'right'
-} = {}) {
- function position(state = defaultPosition, action) {
+DockMonitor.setup = function setup(props) {
+ function position(state = props.defaultPosition, action) {
return (action.type === CHANGE_POSITION) ?
POSITIONS[(POSITIONS.indexOf(state) + 1) % POSITIONS.length] :
state;
}
- function isVisible(state = defaultIsVisible, action) {
+ function isVisible(state = props.defaultIsVisible, action) {
return (action.type === TOGGLE_VISIBILITY) ?
!state :
state;
}
- const ChildMonitor = child.component;
- const CompositeMonitor = ({ monitorState, monitorActions, ...rest }) => (
-
-
-
- );
+ const child = Children.only(props.children);
+ const childSetupResult = child.type.setup(child.props);
return {
- component: CompositeMonitor,
reducer: combineReducers({
position,
isVisible,
- child: child.reducer
+ child: childSetupResult.reducer
}),
actionCreators: {
toggleVisibility,
changePosition,
- child: child.actionCreators
+ child: childSetupResult.actionCreators
}
};
}
diff --git a/package.json b/package.json
index 4b5934b0..a73ffc2a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "redux-devtools",
- "version": "3.0.0-alpha-7",
+ "version": "3.0.0-alpha-8",
"description": "Redux DevTools with hot reloading and time travel",
"main": "lib/index.js",
"scripts": {
diff --git a/src/connectMonitor.js b/src/connectMonitor.js
deleted file mode 100644
index 517f9adf..00000000
--- a/src/connectMonitor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { bindActionCreators } from 'redux';
-import bindActionCreatorsDeep from './bindActionCreatorsDeep';
-import { connect } from 'react-redux';
-import { ActionCreators as historyActionCreators } from './instrument';
-
-export default function connectMonitor({
- component,
- reducer = () => null,
- actionCreators = {}
-}) {
- function mapStateToProps(state) {
- return {
- historyState: state.historyState,
- monitorState: state.monitorState
- };
- }
-
- function mapDispatchToProps(dispatch) {
- return {
- historyActions: bindActionCreators(historyActionCreators, dispatch),
- monitorActions: bindActionCreatorsDeep(actionCreators, dispatch)
- };
- }
-
- const Monitor = connect(mapStateToProps, mapDispatchToProps)(component);
- Monitor.reducer = reducer;
- return Monitor;
-}
diff --git a/src/createDevTools.js b/src/createDevTools.js
index f3281343..fb1245b5 100644
--- a/src/createDevTools.js
+++ b/src/createDevTools.js
@@ -1,21 +1,49 @@
-import React, { Component, PropTypes } from 'react';
-import instrument from './instrument';
-import connectMonitor from './connectMonitor';
+import React, { Children, Component, PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import bindActionCreatorsDeep from './bindActionCreatorsDeep';
+import instrument, { ActionCreators as historyActionCreators } from './instrument';
-export default function createDevTools(monitor) {
- const Monitor = connectMonitor(monitor);
+export default function createDevTools(children) {
+ const child = Children.only(children);
+ const { type: Monitor } = child;
+ const { reducer, actionCreators } = Monitor.setup(child.props);
+
+ function mapStateToProps(state) {
+ return {
+ historyState: state.historyState,
+ monitorState: state.monitorState
+ };
+ }
+
+ function mapDispatchToProps(dispatch) {
+ return {
+ historyActions: bindActionCreators(historyActionCreators, dispatch),
+ monitorActions: bindActionCreatorsDeep(actionCreators, dispatch)
+ };
+ }
+
+ const ConnectedMonitor = connect(
+ mapStateToProps,
+ mapDispatchToProps
+ )(Monitor);
return class DevTools extends Component {
static contextTypes = {
store: PropTypes.object.isRequired
};
- static instrument = () => instrument(Monitor.reducer);
+ static instrument = () => instrument(reducer);
+
+ constructor(props, context) {
+ super(props, context);
+ this.instrumentedStore = context.store.instrumentedStore;
+ }
render() {
return (
-
+
);
}
};