Skip to content

Commit

Permalink
Merge pull request #339 from toggle-corp/feature-select-hoc
Browse files Browse the repository at this point in the history
Feature select hoc
  • Loading branch information
thenav56 authored Sep 26, 2018
2 parents d6054ac + e5f06ea commit 64f439c
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 75 deletions.
8 changes: 6 additions & 2 deletions components/General/FaramList/FaramListApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ export default class FaramListApi extends FaramGroupApi {
return this.onClickMemory[faramElementName];
}

const newOnClick = () => {
const newValue = faramAction(this.props.value || emptyArray, faramElementName);
const newOnClick = (clickParams) => {
const newValue = faramAction(
this.props.value || emptyArray,
faramElementName,
clickParams,
);
// Button doesn't have children, so no need to propagate faramInfo
this.props.onChange(newValue);
};
Expand Down
79 changes: 79 additions & 0 deletions components/Input/TreeSelection/ExtraRoot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import PropTypes from 'prop-types';
import React from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';


const propTypes = {
withRoot: PropTypes.bool,
rootKey: PropTypes.string,
rootTitle: PropTypes.string,
rootSelectedInitial: PropTypes.bool,
value: PropTypes.arrayOf(PropTypes.object),
onChange: PropTypes.func.isRequired,
};

const defaultProps = {
withRoot: false,
rootKey: undefined,
rootTitle: undefined,
rootSelectedInitial: undefined,
value: [],
};


export default (WrappedComponent) => {
class ComponentWithExtraRoot extends React.PureComponent {
static propTypes = propTypes;
static defaultProps = defaultProps;

constructor(props) {
super(props);
this.lastRootSelectionValue = props.rootSelectedInitial;
}

handleChange = (value) => {
const { onChange } = this.props;
this.lastRootSelectionValue = value[0].selected;
onChange(value[0].nodes);
}

calcProps = () => {
const {
withRoot,
rootKey,
rootTitle,
value,
...otherProps
} = this.props;

if (!withRoot) {
return this.props;
}

return {
...otherProps,
initialExpandState: { [rootKey]: true },
value: [{
key: rootKey,
title: rootTitle,
selected: this.lastRootSelectionValue || false,
nodes: value,
draggable: false,
}],
onChange: this.handleChange,
};
}

render() {
const props = this.calcProps();
return (
<WrappedComponent {...props} />
);
}
}

return hoistNonReactStatics(
ComponentWithExtraRoot,
WrappedComponent,
);
};
52 changes: 52 additions & 0 deletions components/Input/TreeSelection/Select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';


const selectors = {
labelSelector: 'title',
keySelector: 'key',
nodesSelector: 'nodes',
};

export default (WrappedComponent) => {
class SelectedComponent extends React.PureComponent {
static calcNewData = (data, props) => {
const newData = Object.keys(selectors)
.filter(s => props[s])
.reduce((acc, selector) => ({
...acc,
[selectors[selector]]: props[selector](data),
}), { ...data });

if (newData.nodes) {
newData.nodes =
newData.nodes.map(d => SelectedComponent.calcNewData(d, props));
}

return newData;
}

calcProps = () => {
const { data } = this.props;
const newData = data &&
data.map(datum => SelectedComponent.calcNewData(datum, this.props));

return {
...this.props,
data: newData,
};
}

render() {
const props = this.calcProps();
return (
<WrappedComponent {...props} />
);
}
}

return hoistNonReactStatics(
SelectedComponent,
WrappedComponent,
);
};
91 changes: 91 additions & 0 deletions components/Input/TreeSelection/SeparateDataValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import PropTypes from 'prop-types';
import React from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
import { pick } from '../../../utils/common';

const emptyObject = {};

const propTypes = {
data: PropTypes.arrayOf(PropTypes.object).isRequired,
value: PropTypes.objectOf(PropTypes.shape({
selected: PropTypes.oneOf([true, false, 'fuzzy']),
nodes: PropTypes.objectOf(PropTypes.object),
})),
onChange: PropTypes.func.isRequired,
};

const defaultProps = {
data: [],
value: {},
};

const mergeDataValue = (data = {}, value = {}) => {
const newValue = {
...data,
selected: value.selected || false,
};

if (newValue.nodes) {
newValue.nodes = newValue.nodes.map(datum => mergeDataValue(
datum,
(value.nodes || emptyObject)[datum.key],
));
}

return newValue;
};


const pickRecursive = (obj, keys) => {
const pickedData = pick(obj, keys);
if (pickedData.nodes) {
pickedData.nodes = pickedData.nodes.reduce((acc, d) => ({
...acc,
[d.key]: pickRecursive(d, keys),
}), {});
}
return pickedData;
};

export default (WrappedComponent) => {
class SeparatedComponent extends React.PureComponent {
static propTypes = propTypes;
static defaultProps = defaultProps;

handleChange = (value) => {
const { onChange } = this.props;
const newValue = value.reduce((acc, d) => ({
...acc,
[d.key]: pickRecursive(d, ['selected', 'nodes']),
}), {});
onChange(newValue);
}

calcProps = () => {
const { value, data, ...otherProps } = this.props;

const newValue = data.map(datum => mergeDataValue(
datum,
(value || emptyObject)[datum.key],
));

return {
...otherProps,
value: newValue,
onChange: this.handleChange,
};
}

render() {
const props = this.calcProps();
return (
<WrappedComponent {...props} />
);
}
}

return hoistNonReactStatics(
SeparatedComponent,
WrappedComponent,
);
};
Loading

0 comments on commit 64f439c

Please sign in to comment.