mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-10-31 07:57:39 +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", | ||||
|     "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" | ||||
|   } | ||||
|  |  | |||
|  | @ -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() | ||||
|   ) | ||||
|   <DockMonitor defaultPosition='bottom'> | ||||
|     <LogMonitor theme='ocean' /> | ||||
|   </DockMonitor> | ||||
| ); | ||||
|  |  | |||
|  | @ -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 ( | ||||
|       <Dock position={position} | ||||
|             isVisible={isVisible} | ||||
|             dimMode='none'> | ||||
|         {children} | ||||
|         {cloneElement(Children.only(children), { | ||||
|           monitorState: monitorState.child, | ||||
|           monitorActions: monitorActions.child, | ||||
|           historyState, | ||||
|           historyActions | ||||
|         })} | ||||
|       </Dock> | ||||
|     ); | ||||
|   } | ||||
|  | @ -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 }) => ( | ||||
|     <DockMonitor monitorState={monitorState} | ||||
|                  monitorActions={monitorActions}> | ||||
|       <ChildMonitor {...rest} | ||||
|                     monitorState={monitorState.child} | ||||
|                     monitorActions={monitorActions.child} /> | ||||
|     </DockMonitor> | ||||
|   ); | ||||
|   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 | ||||
|     } | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -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": { | ||||
|  |  | |||
|  | @ -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 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 ( | ||||
|         <Monitor {...this.props} | ||||
|                  store={this.context.store.instrumentedStore} /> | ||||
|         <ConnectedMonitor {...child.props} | ||||
|                           store={this.instrumentedStore} /> | ||||
|       ); | ||||
|     } | ||||
|   }; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user