...
 
Commits (29)
{
"presets": ["es2015", "react"],
"plugins": ["transform-react-jsx"]
}
<!doctype html>
<html lang="en">
<head>
<style type="text/css">
html, body {
height:100%;
margin: 0;
padding: 0;
}
div#viz{
width:400px;
height:200px;
border:1px solid black;
position:absolute;
left:0px;
bottom:0px;
}
#app-root {
width : 100%;
height : 100%;
}
</style>
<meta charset="utf-8">
<link rel="stylesheet" href="node_modules/@jbeard/schviz2/test-integration/styles.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Redux Drag and Drop State Machine Example</title>
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/babel-polyfill/dist/polyfill.js"></script>
</head>
<body>
<div id="app-root"></div>
<script src="dist/index.js"></script>
</body>
</html>
{
"name": "@scion-scxml/drag-and-drop-redux-with-devtools",
"version": "0.0.13",
"license": "Apache-2.0",
"author": "Jacob Beard <jake@jacobeanrnd.com>",
"devDependencies": {
"@scion-scxml/redux-devtools-scion-monitor": "^1.4.12",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babelify": "^8.0.0",
"browserify": "^14.5.0",
"enzyme": "^2.4.1",
"react-addons-test-utils": "^15.3.0",
"react-scripts": "^0.9.3",
"redux-devtools": "^3.4.1",
"redux-devtools-chart-monitor": "^1.7.0",
"redux-devtools-dock-monitor": "^1.1.3",
"redux-devtools-log-monitor": "^1.4.0",
"redux-slider-monitor": "^2.0.0-1",
"sorcery": "^0.10.0"
},
"dependencies": {
"@scion-scxml/cli": "^1.0.29",
"@scion-scxml/core": "^2.6.14",
"@scion-scxml/schviz": "^3.2.17",
"babel-preset-react": "^6.24.1",
"jquery": "^3.3.1",
"prop-types": "^15.5.8",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^4.4.8",
"redux": "^3.6.0",
"redux-thunk": "^2.3.0"
},
"main": "src/index.jsx",
"scripts": {
"compile-scxml": "scion compile ./src/reducers/drag-and-drop.scxml --format json -o dist/drag-and-drop.json && scion compile ./src/reducers/drag-and-drop.scxml --format module -o dist/drag-and-drop.js",
"bundle": "cd dist; browserify -d -t babelify ../src/index.js -o ./index.js; sorcery -i index.js",
"build": "npm run compile-scxml && npm run bundle",
"watch": "cd dist; watchify -d -t babelify ../src/index.js -o 'cat > index.js; sorcery -i index.js' -v"
},
"gitHead": "0838a38c74a63ce40c48168e03c4e783e37c1731"
}
export const mouseevent = (event) => ({
type: event.type,
data: {
screenX : event.screenX,
screenY : event.screenY
}
})
import React from 'react'
import PropTypes from 'prop-types'
const Rect = ({ x, y, onMouseDown, onMouseUp, onMouseMove }) => {
return (
<rect x={x} y={y}
fill="red" stroke="black"
onMouseDown={onMouseDown} onMouseUp={onMouseUp} onMouseMove={onMouseMove}
width="100" height="100"/>
)
}
Rect.propTypes = {
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
onMouseDown:PropTypes.func.isRequired,
onMouseUp:PropTypes.func.isRequired,
onMouseMove:PropTypes.func.isRequired
}
export default Rect
import React from 'react';
import { createDevTools } from 'redux-devtools';
import LogMonitor from 'redux-devtools-log-monitor';
import ScionMonitor from '@scion-scxml/redux-devtools-scion-monitor';
import DockMonitor from 'redux-devtools-dock-monitor';
import SliderMonitor from 'redux-slider-monitor';
import ChartMonitor from 'redux-devtools-chart-monitor';
import scjson from '../../dist/drag-and-drop.json'
export default createDevTools(
<DockMonitor
changeMonitorKey='ctrl-m'
toggleVisibilityKey='ctrl-h'
changePositionKey='ctrl-q'>
<ScionMonitor scjson={scjson}/>
<ChartMonitor />
<LogMonitor />
<SliderMonitor keyboardEnabled />
</DockMonitor>
);
import { connect } from 'react-redux'
import { mouseevent } from '../actions'
import Rect from '../components/Rect';
const mapStateToProps = ({ snapshot: [configuration, history, isInFinalState, datamodel] }, ownProps) => {
return {
x : datamodel.rectX,
y : datamodel.rectY
}
}
const mapDispatchToProps = (dispatch, ownProps) => ({
onMouseDown: (e) => {
dispatch(mouseevent(e))
},
onMouseUp: (e) => {
dispatch(mouseevent(e))
},
onMouseMove: (e) => {
dispatch(mouseevent(e))
}
})
let DraggableRect = connect(
mapStateToProps,
mapDispatchToProps
)(Rect)
export default DraggableRect
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import DevTools from './DevTools';
import DraggableRect from '../containers/DnD';
import InteractiveSCHVIZ from '../containers/SCHVIZ';
export default class Root extends Component {
render() {
const { store } = this.props;
return (
<Provider store={store}>
<div style={{width:'100%', height:'100%'}}>
<div style={{width:'100%', height:'100%'}}>
<svg width="100%" height="100%">
<DraggableRect/>
</svg>
</div>
<DevTools />
</div>
</Provider>
);
}
}
if (process.env.NODE_ENV === 'production') {
module.exports = require('./Root.prod');
} else {
module.exports = require('./Root.dev');
}
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import DraggableRect from '../containers/DnD';
export default class Root extends Component {
render() {
const { store } = this.props;
return (
<Provider store={store}>
<div style={{width:'100%', height:'100%'}}>
<div style={{width:'100%', height:'100%'}}>
<svg width="100%" height="100%">
<DraggableRect/>
</svg>
</div>
</div>
</Provider>
);
}
}
import { connect } from 'react-redux'
import SCHVIZ from '@scion-scxml/schviz';
import scjson from '../../dist/drag-and-drop.json'
const mapStateToProps = ({ snapshot: [configuration, history, isInFinalState, datamodel] }, ownProps) => {
return {
configuration,
scjson,
hideActions : true
}
}
let InteractiveSCHVIZ = connect(
mapStateToProps,
null
)(SCHVIZ)
export default InteractiveSCHVIZ
import React from 'react'
import { render } from 'react-dom'
import Root from './containers/Root';
import reducer from './reducers'
import configureStore from './store/configureStore';
const store = configureStore();
render(
<Root
store={ store }
/>,
document.getElementById('app-root')
);
<scxml
xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
profile="ecmascript">
<datamodel>
<data id="eventStampX"/>
<data id="eventStampY"/>
<data id="rectX" expr="0"/>
<data id="rectY" expr="0"/>
</datamodel>
<state id="idle">
<transition event="mousedown" target="dragging">
<assign location="eventStampX" expr="_event.data.screenX"/>
<assign location="eventStampY" expr="_event.data.screenY"/>
</transition>
</state>
<state id="dragging">
<transition event="mouseup" target="idle"/>
<transition event="mousemove" target="dragging">
<script>
var dx = eventStampX - _event.data.screenX;
var dy = eventStampY - _event.data.screenY;
rectX -= dx;
rectY -= dy;
</script>
<assign location="eventStampX" expr="_event.data.screenX"/>
<assign location="eventStampY" expr="_event.data.screenY"/>
</transition>
</state>
</scxml>
const scion = require('@scion-scxml/core');
import modelFactory from '../../dist/drag-and-drop'
const initialState = { snapshot: null };
const handleAction = ({ snapshot } = initialState, action) => {
if(action.type && !action.name){
action.name = action.type;
}
let interpreter
if(!snapshot){
//instantiate the interpreter
interpreter = new scion.Statechart(modelFactory);
//start the interpreter
interpreter.start();
}else{
//instantiate the interpreter
interpreter = new scion.Statechart(modelFactory, { snapshot });
}
interpreter.gen(action);
return { snapshot: interpreter.getSnapshot() };
}
export default handleAction
import { createStore, applyMiddleware, compose } from 'redux';
import { persistState } from 'redux-devtools';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
import DevTools from '../containers/DevTools';
const enhancer = compose(
applyMiddleware(thunk),
DevTools.instrument(),
persistState(
window.location.href.match(
/[?&]debug_session=([^&#]+)\b/
)
)
);
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, enhancer);
if (module.hot) {
module.hot.onUpdate(()=>{
store.replaceReducer(require('../reducers').default)
});
}
return store;
}
if (process.env.NODE_ENV === 'production') {
module.exports = require('./configureStore.prod');
} else {
module.exports = require('./configureStore.dev');
}
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
const enhancer = applyMiddleware(thunk);
export default function configureStore(initialState) {
return createStore(rootReducer, initialState, enhancer);
}
{
"presets": ["es2015"],
"plugins": ["transform-react-jsx"]
}
node_modules
dist
*.sw*
<!doctype html>
<html lang="en">
<head>
<style type="text/css">
html, body {
height:100%;
margin: 0;
padding: 0;
}
div#viz{
width:400px;
height:200px;
border:1px solid black;
position:absolute;
right:0px;
top:0px;
}
#app-root {
width : 100%;
height : 100%;
}
</style>
<meta charset="utf-8">
<link rel="stylesheet" href="node_modules/@jbeard/schviz2/test-integration/styles.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Redux Drag and Drop State Machine Example</title>
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/babel-polyfill/dist/polyfill.js"></script>
</head>
<body>
<div id="app-root"></div>
<script src="dist/index.js"></script>
</body>
</html>
This diff is collapsed.
{
"name": "@scion-scxml/drag-and-drop-redux",
"version": "0.0.13",
"license": "Apache-2.0",
"author": "Jacob Beard <jake@jacobeanrnd.com>",
"devDependencies": {
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babelify": "^8.0.0",
"browserify": "^14.5.0",
"enzyme": "^2.4.1",
"react-addons-test-utils": "^15.3.0",
"react-scripts": "^0.9.3",
"redux-devtools-chart-monitor": "^1.7.0",
"sorcery": "^0.10.0"
},
"dependencies": {
"@scion-scxml/cli": "^1.0.29",
"@scion-scxml/core": "^2.6.14",
"@scion-scxml/schviz": "^3.2.17",
"babel-preset-react": "^6.24.1",
"jquery": "^3.3.1",
"prop-types": "^15.5.8",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^4.4.8",
"redux": "^3.6.0"
},
"scripts": {
"compile-scxml": "scion compile ./src/reducers/drag-and-drop.scxml --format json -o dist/drag-and-drop.json && scion compile ./src/reducers/drag-and-drop.scxml --format module -o dist/drag-and-drop.js",
"bundle": "cd dist; browserify -d -t babelify ../src/index.js -o ./index.js; sorcery -i index.js",
"build": "npm run compile-scxml && npm run bundle",
"watch": "cd dist; watchify -d -t babelify ../src/index.js -o 'cat > index.js; sorcery -i index.js' -v"
},
"gitHead": "0838a38c74a63ce40c48168e03c4e783e37c1731"
}
export const mouseevent = (event) => ({
type: event.type,
data: event
})
import React from 'react'
import DraggableRect from '../containers/DnD'
import InteractiveSCHVIZ from '../containers/SCHVIZ'
const App = () => (
<div style={{width:'100%', height:'100%'}}>
<div style={{width:'100%', height:'100%'}}>
<svg width="100%" height="100%">
<DraggableRect/>
</svg>
</div>
<div id="viz">
<InteractiveSCHVIZ />
</div>
</div>
)
export default App
import React from 'react'
import PropTypes from 'prop-types'
const Rect = ({ x, y, onMouseDown, onMouseUp, onMouseMove }) => {
return (
<rect x={x} y={y}
fill="red" stroke="black"
onMouseDown={onMouseDown} onMouseUp={onMouseUp} onMouseMove={onMouseMove}
width="100" height="100"/>
)
}
Rect.propTypes = {
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
onMouseDown:PropTypes.func.isRequired,
onMouseUp:PropTypes.func.isRequired,
onMouseMove:PropTypes.func.isRequired
}
export default Rect
import { connect } from 'react-redux'
import { mouseevent } from '../actions'
import Rect from '../components/Rect';
const mapStateToProps = ([configuration, history, isInFinalState, datamodel], ownProps) => {
return {
x : datamodel.rectX,
y : datamodel.rectY
}
}
const mapDispatchToProps = (dispatch, ownProps) => ({
onMouseDown: (e) => {
dispatch(mouseevent(e))
},
onMouseUp: (e) => {
dispatch(mouseevent(e))
},
onMouseMove: (e) => {
dispatch(mouseevent(e))
}
})
let DraggableRect = connect(
mapStateToProps,
mapDispatchToProps
)(Rect)
export default DraggableRect
import { connect } from 'react-redux'
import SCHVIZ from '@scion-scxml/schviz';
import scjson from '../../dist/drag-and-drop.json'
const mapStateToProps = ([configuration, history, isInFinalState, datamodel], ownProps) => {
return {
configuration,
scjson,
hideActions : true
}
}
let InteractiveSCHVIZ = connect(
mapStateToProps,
null
)(SCHVIZ)
export default InteractiveSCHVIZ
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'
const store = createStore(reducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app-root')
)
<scxml
xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
profile="ecmascript">
<datamodel>
<data id="eventStampX"/>
<data id="eventStampY"/>
<data id="rectX" expr="0"/>
<data id="rectY" expr="0"/>
</datamodel>
<state id="idle">
<transition event="mousedown" target="dragging">
<assign location="eventStampX" expr="_event.data.screenX"/>
<assign location="eventStampY" expr="_event.data.screenY"/>
</transition>
</state>
<state id="dragging">
<transition event="mouseup" target="idle"/>
<transition event="mousemove" target="dragging">
<script>
var dx = eventStampX - _event.data.screenX;
var dy = eventStampY - _event.data.screenY;
rectX -= dx;
rectY -= dy;
</script>
<assign location="eventStampX" expr="_event.data.screenX"/>
<assign location="eventStampY" expr="_event.data.screenY"/>
</transition>
</state>
</scxml>
const scion = require('@scion-scxml/core');
import fnModel from '../../dist/drag-and-drop'
const handleAction = (state, action) => {
if(action.type && !action.name){
action.name = action.type;
}
let interpreter
if(!state){
//instantiate the interpreter
interpreter = new scion.Statechart(fnModel);
//start the interpreter
interpreter.start();
}else{
//instantiate the interpreter
interpreter = new scion.Statechart(fnModel, {snapshot : state});
}
interpreter.gen(action);
return interpreter.getSnapshot();
}
export default handleAction