Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic onClick functionality for rendered structuredLang #8

Merged
merged 11 commits into from
Apr 17, 2017
3 changes: 2 additions & 1 deletion src/actions/creators.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as types from './types.js';

export const traceActivated = (trace) => {
export const traceActivated = (lang, trace) => {
return {
type: types.TRACE_ACTIVATED,
lang,
trace,
};
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/structuredlang/StructuredExpWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import PropTypes from 'prop-types';

import StructuredExp from './recursive/StructuredExp.js';

const StructuredExpWrapper = ({ lang, sExp }) => (
const StructuredExpWrapper = ({ lang, sExp, createOnClick }) => (
<pre>
<span>{lang}</span><br />
<StructuredExp sExp={sExp} />
<StructuredExp sExp={sExp} createOnClick={createOnClick} />
</pre>
)

StructuredExpWrapper.propTypes = {
lang: PropTypes.string.isRequired,
sExp: PropTypes.object.isRequired,
createOnClick: PropTypes.func.isRequired,
};

export default StructuredExpWrapper;
6 changes: 4 additions & 2 deletions src/components/structuredlang/StructuredLangTrees.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';

import StructuredExpWrapper from './StructuredExpWrapper.js';

const StructuredLangTrees = ({ trees }) => {
const StructuredLangTrees = ({ trees, createOnClick }) => {
if (!trees) {
return null;
}
Expand All @@ -13,6 +13,7 @@ const StructuredLangTrees = ({ trees }) => {
key={tree.lang}
lang={tree.lang}
sExp={tree.prog}
createOnClick={createOnClick(tree.lang)}
/>
));

Expand All @@ -24,6 +25,7 @@ StructuredLangTrees.propTypes = {
lang: PropTypes.string.isRequired,
prog: PropTypes.object.isRequired,
})),
}
createOnClick: PropTypes.func.isRequired,
};

export default StructuredLangTrees;
20 changes: 14 additions & 6 deletions src/components/structuredlang/recursive/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ const shouldSurround = (item) => item.args && item.args.length > 0;

// This function is intended to be used as the `callback` argument in a call to
// `Array.prototype.map`, hence the index argument.
const renderAndMaybeSurround = (sExp, index) => {
const rendered = <StructuredExp sExp={sExp} key={index} />;
const renderAndMaybeSurround = (props) => {
const rendered = <StructuredExp {...props} />;

let arr = [];
if (shouldSurround(sExp)) {
if (shouldSurround(props.sExp)) {
arr = ['(', rendered, ')'];
} else {
arr = [rendered];
Expand All @@ -23,19 +23,27 @@ const renderAndMaybeSurround = (sExp, index) => {
return arr;
}

const Item = ({ name, args, trace }) => {
const nestedRenderedArgs = args.map(renderAndMaybeSurround);
const Item = ({ name, args, trace, createOnClick }) => {
const decorated = args.map((arg, index) => ({
sExp: arg,
key: index,
createOnClick,
}));
const nestedRenderedArgs = decorated.map(renderAndMaybeSurround);
const nestedNameAndArgs = [name].concat(nestedRenderedArgs);
const nestedWithSpaces = intersperse(' ', nestedNameAndArgs);
const withSpaces = _.flatten(nestedWithSpaces);

return <span>{withSpaces}</span>;
const onClick = createOnClick(trace);

return <span onClick={onClick}>{withSpaces}</span>;
}

Item.propTypes = {
name: PropTypes.string.isRequired,
args: PropTypes.array.isRequired,
trace: PropTypes.object,
createOnClick: PropTypes.func.isRequired,
};

export default Item;
4 changes: 3 additions & 1 deletion src/components/structuredlang/recursive/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import PropTypes from 'prop-types';

import SurroundAndSeparate from './SurroundAndSeparate.js';

const List = ({ elements }) =>
const List = ({ elements, createOnClick }) =>
<SurroundAndSeparate
left={'['}
right={']'}
separator='; '
elements={elements}
createOnClick={createOnClick}
/>;

List.propTypes = {
elements: PropTypes.array.isRequired,
createOnClick: PropTypes.func.isRequired,
};

export default List;
9 changes: 5 additions & 4 deletions src/components/structuredlang/recursive/StructuredExp.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import Item from './Item.js';
import List from './List.js';
import Tuple from './Tuple.js';

const StructuredExp = ({ sExp }) => {
const StructuredExp = ({ sExp, createOnClick }) => {
let rendered;
if (Array.isArray(sExp)) {
rendered = <List elements={sExp} />;
rendered = <List elements={sExp} createOnClick={createOnClick} />;
} else if (sExp.isTuple) {
rendered = <Tuple elements={sExp.elements} />;
rendered = <Tuple elements={sExp.elements} createOnClick={createOnClick} />;
} else {
rendered = <Item {...sExp} />;
rendered = <Item {...sExp} createOnClick={createOnClick} />;
}

return rendered;
Expand All @@ -24,6 +24,7 @@ StructuredExp.propTypes = {
PropTypes.object,
PropTypes.array,
]).isRequired,
createOnClick: PropTypes.func.isRequired,
};

export default StructuredExp;
11 changes: 9 additions & 2 deletions src/components/structuredlang/recursive/SurroundAndSeparate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ import { intersperse } from '../../../utils/ArrayUtils.js';

import StructuredExp from './StructuredExp.js';

const SurroundAndSeparate = ({ left, right, separator, elements }) => {
const renderedElements = elements.map((element, index) => <StructuredExp sExp={element} key={index} />);
const SurroundAndSeparate = ({ left, right, separator, elements, createOnClick }) => {
const renderedElements = elements.map((element, index) => (
<StructuredExp
sExp={element}
key={index}
createOnClick={createOnClick}
/>
));
const withSeparator = intersperse(separator, renderedElements);
return <span>{left}{withSeparator}{right}</span>;
}
Expand All @@ -16,6 +22,7 @@ SurroundAndSeparate.propTypes = {
right: PropTypes.string.isRequired,
separator: PropTypes.string.isRequired,
elements: PropTypes.array.isRequired,
createOnClick: PropTypes.func.isRequired,
};

export default SurroundAndSeparate;
4 changes: 3 additions & 1 deletion src/components/structuredlang/recursive/Tuple.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import PropTypes from 'prop-types';

import SurroundAndSeparate from './SurroundAndSeparate.js';

const Tuple = ({ elements }) =>
const Tuple = ({ elements, createOnClick }) =>
<SurroundAndSeparate
left={'('}
right={')'}
separator=', '
elements={elements}
createOnClick={createOnClick}
/>;

Tuple.propTypes = {
elements: PropTypes.array.isRequired,
createOnClick: PropTypes.func.isRequired,
};

export default Tuple;
13 changes: 12 additions & 1 deletion src/containers/LangTreesContainer.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { connect } from 'react-redux';

import { traceActivated, traceDeactivated } from '../actions/creators.js';

import StructuredLangTrees from '../components/structuredlang/StructuredLangTrees.js';

const mapStateToProps = (state) => ({
trees: state.trees.trees,
})

const mapDispatchToProps = (dispatch) => ({})
const mapDispatchToProps = (dispatch) => ({
createOnClick: (lang) => (trace) => (event) => {
event.stopPropagation();
if (trace) {
dispatch(traceActivated(lang, trace));
} else {
dispatch(traceDeactivated());
}
},
})

const LangTreesContainer = connect(
mapStateToProps,
Expand Down
5 changes: 4 additions & 1 deletion src/reducers/highlightedTrace.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { TRACE_ACTIVATED, TRACE_DEACTIVATED } from '../actions/types.js';
const highlightedTrace = (state = null, action) => {
switch (action.type) {
case TRACE_ACTIVATED:
return action.trace;
return {
lang: action.lang,
trace: action.trace,
};
case TRACE_DEACTIVATED:
return null;
default:
Expand Down