mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-11-01 00:17:48 +03:00 
			
		
		
		
	Component-centric API, horrors are encapsulated
This commit is contained in:
		
							parent
							
								
									34d599af77
								
							
						
					
					
						commit
						79b51a7c0f
					
				|  | @ -28,8 +28,8 @@ | ||||||
|     "node-libs-browser": "^0.5.2", |     "node-libs-browser": "^0.5.2", | ||||||
|     "react-dock": "^0.1.0", |     "react-dock": "^0.1.0", | ||||||
|     "react-hot-loader": "^1.3.0", |     "react-hot-loader": "^1.3.0", | ||||||
|     "redux-devtools": "^3.0.0-alpha-7", |     "redux-devtools": "^3.0.0-alpha-8", | ||||||
|     "redux-devtools-log-monitor": "^1.0.0-alpha-7", |     "redux-devtools-log-monitor": "^1.0.0-alpha-8", | ||||||
|     "webpack": "^1.9.11", |     "webpack": "^1.9.11", | ||||||
|     "webpack-dev-server": "^1.9.0" |     "webpack-dev-server": "^1.9.0" | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
|  | import React from 'react'; | ||||||
| import { createDevTools } from 'redux-devtools'; | import { createDevTools } from 'redux-devtools'; | ||||||
| import createLogMonitor from 'redux-devtools-log-monitor'; | import LogMonitor from 'redux-devtools-log-monitor'; | ||||||
| import createDockMonitor from '../dock/DockMonitor'; | import DockMonitor from '../dock/DockMonitor'; | ||||||
| 
 | 
 | ||||||
| export default createDevTools( | export default createDevTools( | ||||||
|   createDockMonitor( |   <DockMonitor defaultPosition='bottom'> | ||||||
|     createLogMonitor() |     <LogMonitor theme='ocean' /> | ||||||
|   ) |   </DockMonitor> | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | @ -2,24 +2,36 @@ | ||||||
| // TODO: extract to a separate project.
 | // 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 Dock from 'react-dock'; | ||||||
| import { combineReducers } from 'redux'; | import { combineReducers } from 'redux'; | ||||||
| 
 | 
 | ||||||
| const POSITIONS = ['left', 'top', 'right', 'bottom']; | const POSITIONS = ['left', 'top', 'right', 'bottom']; | ||||||
| 
 | 
 | ||||||
| class DockMonitor extends Component { | export default class DockMonitor extends Component { | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|  |     defaultPosition: PropTypes.oneOf(POSITIONS).isRequired, | ||||||
|  |     defaultIsVisible: PropTypes.bool.isRequired, | ||||||
|  |     toggleVisibilityShortcut: PropTypes.string.isRequired, | ||||||
|  |     changePositionShortcut: PropTypes.string.isRequired, | ||||||
|  | 
 | ||||||
|     monitorState: PropTypes.shape({ |     monitorState: PropTypes.shape({ | ||||||
|       position: PropTypes.oneOf(POSITIONS).isRequired, |       position: PropTypes.oneOf(POSITIONS).isRequired, | ||||||
|       isVisible: PropTypes.bool.isRequired, |       isVisible: PropTypes.bool.isRequired, | ||||||
|       child: PropTypes.any |       child: PropTypes.any | ||||||
|     }).isRequired, |     }), | ||||||
| 
 | 
 | ||||||
|     monitorActions: PropTypes.shape({ |     monitorActions: PropTypes.shape({ | ||||||
|       toggleVisibility: PropTypes.func.isRequired, |       toggleVisibility: PropTypes.func.isRequired, | ||||||
|       changePosition: PropTypes.func.isRequired |       changePosition: PropTypes.func.isRequired | ||||||
|     }).isRequired |     }) | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   static defaultProps = { | ||||||
|  |     defaultIsVisible: true, | ||||||
|  |     defaultPosition: 'right', | ||||||
|  |     toggleVisibilityShortcut: 'H', | ||||||
|  |     changePositionShortcut: 'Q' | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|  | @ -39,11 +51,11 @@ class DockMonitor extends Component { | ||||||
| 
 | 
 | ||||||
|     const key = event.keyCode || event.which; |     const key = event.keyCode || event.which; | ||||||
|     const char = String.fromCharCode(key); |     const char = String.fromCharCode(key); | ||||||
|     switch (char) { |     switch (char.toUpperCase()) { | ||||||
|     case 'H': |     case this.props.toggleVisibilityShortcut.toUpperCase(): | ||||||
|       this.props.monitorActions.toggleVisibility(); |       this.props.monitorActions.toggleVisibility(); | ||||||
|       break; |       break; | ||||||
|     case 'D': |     case this.props.changePositionShortcut.toUpperCase(): | ||||||
|       this.props.monitorActions.changePosition(); |       this.props.monitorActions.changePosition(); | ||||||
|       break; |       break; | ||||||
|     default: |     default: | ||||||
|  | @ -52,13 +64,29 @@ class DockMonitor extends Component { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     const { children, monitorState } = this.props; |     const { | ||||||
|     const { position, isVisible } = monitorState; |       monitorState, | ||||||
|  |       monitorActions, | ||||||
|  |       historyState, | ||||||
|  |       historyActions, | ||||||
|  |       children | ||||||
|  |     } = this.props; | ||||||
|  | 
 | ||||||
|  |     const { | ||||||
|  |       position, | ||||||
|  |       isVisible | ||||||
|  |     } = monitorState; | ||||||
|  | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Dock position={position} |       <Dock position={position} | ||||||
|             isVisible={isVisible} |             isVisible={isVisible} | ||||||
|             dimMode='none'> |             dimMode='none'> | ||||||
|         {children} |         {cloneElement(Children.only(children), { | ||||||
|  |           monitorState: monitorState.child, | ||||||
|  |           monitorActions: monitorActions.child, | ||||||
|  |           historyState, | ||||||
|  |           historyActions | ||||||
|  |         })} | ||||||
|       </Dock> |       </Dock> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | @ -74,43 +102,32 @@ function changePosition() { | ||||||
|   return { type: CHANGE_POSITION }; |   return { type: CHANGE_POSITION }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default function create(child, { | DockMonitor.setup = function setup(props) { | ||||||
|   defaultIsVisible = true, |   function position(state = props.defaultPosition, action) { | ||||||
|   defaultPosition = 'right' |  | ||||||
| } = {}) { |  | ||||||
|   function position(state = defaultPosition, action) { |  | ||||||
|     return (action.type === CHANGE_POSITION) ? |     return (action.type === CHANGE_POSITION) ? | ||||||
|       POSITIONS[(POSITIONS.indexOf(state) + 1) % POSITIONS.length] : |       POSITIONS[(POSITIONS.indexOf(state) + 1) % POSITIONS.length] : | ||||||
|       state; |       state; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function isVisible(state = defaultIsVisible, action) { |   function isVisible(state = props.defaultIsVisible, action) { | ||||||
|     return (action.type === TOGGLE_VISIBILITY) ? |     return (action.type === TOGGLE_VISIBILITY) ? | ||||||
|       !state : |       !state : | ||||||
|       state; |       state; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const ChildMonitor = child.component; |   const child = Children.only(props.children); | ||||||
|   const CompositeMonitor = ({ monitorState, monitorActions, ...rest }) => ( |   const childSetupResult = child.type.setup(child.props); | ||||||
|     <DockMonitor monitorState={monitorState} |  | ||||||
|                  monitorActions={monitorActions}> |  | ||||||
|       <ChildMonitor {...rest} |  | ||||||
|                     monitorState={monitorState.child} |  | ||||||
|                     monitorActions={monitorActions.child} /> |  | ||||||
|     </DockMonitor> |  | ||||||
|   ); |  | ||||||
| 
 | 
 | ||||||
|   return { |   return { | ||||||
|     component: CompositeMonitor, |  | ||||||
|     reducer: combineReducers({ |     reducer: combineReducers({ | ||||||
|       position, |       position, | ||||||
|       isVisible, |       isVisible, | ||||||
|       child: child.reducer |       child: childSetupResult.reducer | ||||||
|     }), |     }), | ||||||
|     actionCreators: { |     actionCreators: { | ||||||
|       toggleVisibility, |       toggleVisibility, | ||||||
|       changePosition, |       changePosition, | ||||||
|       child: child.actionCreators |       child: childSetupResult.actionCreators | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| { | { | ||||||
|   "name": "redux-devtools", |   "name": "redux-devtools", | ||||||
|   "version": "3.0.0-alpha-7", |   "version": "3.0.0-alpha-8", | ||||||
|   "description": "Redux DevTools with hot reloading and time travel", |   "description": "Redux DevTools with hot reloading and time travel", | ||||||
|   "main": "lib/index.js", |   "main": "lib/index.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|  |  | ||||||
|  | @ -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; |  | ||||||
| } |  | ||||||
|  | @ -1,21 +1,49 @@ | ||||||
| import React, { Component, PropTypes } from 'react'; | import React, { Children, Component, PropTypes } from 'react'; | ||||||
| import instrument from './instrument'; | import { connect } from 'react-redux'; | ||||||
| import connectMonitor from './connectMonitor'; | import { bindActionCreators } from 'redux'; | ||||||
|  | import bindActionCreatorsDeep from './bindActionCreatorsDeep'; | ||||||
|  | import instrument, { ActionCreators as historyActionCreators } from './instrument'; | ||||||
| 
 | 
 | ||||||
| export default function createDevTools(monitor) { | export default function createDevTools(children) { | ||||||
|   const Monitor = connectMonitor(monitor); |   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 { |   return class DevTools extends Component { | ||||||
|     static contextTypes = { |     static contextTypes = { | ||||||
|       store: PropTypes.object.isRequired |       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() { |     render() { | ||||||
|       return ( |       return ( | ||||||
|         <Monitor {...this.props} |         <ConnectedMonitor {...child.props} | ||||||
|                  store={this.context.store.instrumentedStore} /> |                           store={this.instrumentedStore} /> | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user