Skip to content

Commit

Permalink
Make repeatable widget HOC use react-sortable-hoc
Browse files Browse the repository at this point in the history
  • Loading branch information
Benaiah committed Jul 5, 2017
1 parent e515b39 commit f204440
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 60 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
"react-sidebar": "^2.2.1",
"react-simple-dnd": "^0.1.2",
"react-sortable": "^1.2.0",
"react-sortable-hoc": "^0.6.5",
"react-split-pane": "^0.1.57",
"react-textarea-autosize": "^4.3.2",
"react-toolbox": "^1.2.1",
Expand Down
15 changes: 2 additions & 13 deletions src/components/Widgets/WidgetHOCs/repeatable.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,11 @@
border-top-left-radius: 0;
}

.expanded {
}

.collapsed {
& .objectLabel {
display: block;
}
& .objectControl {
display: none;
}
}

.dragIcon {
position: absolute;
/* position: absolute; */
top: 2px;
display: block;
width: 100%;
text-align: center;
cursor: grab;
}
94 changes: 49 additions & 45 deletions src/components/Widgets/WidgetHOCs/repeatable.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import React, { Component, PropTypes } from 'react';
import { fromJS, List, Map } from 'immutable';
import { fromJS, List } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { sortable } from 'react-sortable';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import FontIcon from 'react-toolbox/lib/font_icon';
import styles from './repeatable.css';

const RepeatableItem = sortable(
props => <div {...props}>{props.children}</div>
const RepeatableContainer = SortableContainer(
({ items, renderItem }) => <div>{items.map(renderItem)}</div>
);

const repeatable = WrappedComponent =>
class extends Component {
const DragHandle = SortableHandle(
() => <FontIcon value="drag_handle" className={styles.dragIcon} />
);

const repeatable = (WrappedComponent) => {
const RepeatableItem = SortableElement(
props => (<div {...props}>
<DragHandle />
{props.children}
</div>)
);

return class extends Component {
static propTypes = {
field: ImmutablePropTypes.map.isRequired,
value: PropTypes.oneOfType([
Expand All @@ -26,81 +37,74 @@ const repeatable = WrappedComponent =>

constructor(props) {
super(props);
this.state = {};
}

handleChangeFor = (index) => {
return (newValueForIndex, newMetadata) => {
const { value, onChange } = this.props;
const newValue = value.set(index, newValueForIndex);
onChange(fromJS(newValue));
};
handleChangeFor = index => (newValueForIndex, newMetadata) => {
const { value, onChange } = this.props;
const newValue = value.set(index, newValueForIndex);
onChange(fromJS(newValue));
};

handleRemoveFor = (index) => {
return (e) => {
e.preventDefault();
const { value, metadata, onChange, forID } = this.props;
const parsedMetadata = metadata && {
[forID]: metadata.removeIn(value.get(index).valueSeq()),
};
onChange(value.remove(index), parsedMetadata);
handleRemoveFor = index => (e) => {
e.preventDefault();
const { value, metadata, onChange, forID } = this.props;
const parsedMetadata = metadata && {
[forID]: metadata.removeIn(value.get(index).valueSeq()),
};
onChange(value.remove(index), parsedMetadata);
};

handleAdd = (e) => {
e.preventDefault();
const { value, onChange } = this.props;
onChange((value || List()).push(null));
}

handleSort = (obj) => {
this.setState({ draggingIndex: obj.draggingIndex });
if (obj.items) {
this.props.onChange(fromJS(obj.items));
}
};

renderItem = (item, index) => {
return (<RepeatableItem
key={index}
sortId={index}
draggingIndex={this.state.draggingIndex}
outline="list"
updateState={this.handleSort}
items={this.props.value ? this.props.value.toJS() : []}
>
<FontIcon value="drag_handle" className={styles.dragIcon} />
<button className={styles.removeButton} onClick={this.handleRemoveFor(index)}>
renderItem = (item, i) =>
(<RepeatableItem key={`item-${ i }`} index={i}>
<button className={styles.removeButton} onClick={this.handleRemoveFor(i)}>
<FontIcon value="close" />
</button>
<WrappedComponent
{...this.props}
className={styles.repeatedComponent}
value={item}
onChange={this.handleChangeFor(index)}
onChange={this.handleChangeFor(i)}
/>
</RepeatableItem>);

onSortEnd = ({ oldIndex, newIndex }) => {
const oldItem = this.props.value.get(oldIndex);
const newValue = this.props.value.delete(oldIndex).insert(newIndex, oldItem);
this.props.onChange(newValue);
};

renderItems() {
const { value, forID } = this.props;
const { value, field, forID } = this.props;
return (<div id={forID}>
{value && value.map(this.renderItem).toJS()}
<button className={styles.addButton} onClick={this.handleAdd}>=
<RepeatableContainer
items={value || List()}
renderItem={this.renderItem}
onSortEnd={this.onSortEnd}
useDragHandle={true}
/>
<button className={styles.addButton} onClick={this.handleAdd}>
<FontIcon value="add" className={styles.addButtonText} />
<span className={styles.addButtonText}>new</span>
<span className={styles.addButtonText}>
new {field.get('label', '').toLowerCase()}
</span>
</button>
</div>);
}

render() {
if (this.props.field.get("repeat", false)) {
return <div id={this.props.forID}>{this.renderItems()}</div>;
return this.renderItems();
}

return <WrappedComponent {...this.props} />;
}
};
};

export default repeatable;
13 changes: 11 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ babel-register@^6.24.1:
mkdirp "^0.5.1"
source-map-support "^0.4.2"

babel-runtime@6.x.x, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.5.0, babel-runtime@^6.6.1, babel-runtime@^6.9.2:
babel-runtime@6.x.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.5.0, babel-runtime@^6.6.1, babel-runtime@^6.9.2:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
dependencies:
Expand Down Expand Up @@ -4763,7 +4763,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"

"lodash@4.6.1 || ^4.16.1", lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.2, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.7.0:
"lodash@4.6.1 || ^4.16.1", lodash@^4.0.0, lodash@^4.1.0, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.2, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.7.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"

Expand Down Expand Up @@ -6783,6 +6783,15 @@ react-simple-dnd@^0.1.2:
react-dnd "^2.1.4"
react-dnd-html5-backend "^2.1.2"

react-sortable-hoc@^0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/react-sortable-hoc/-/react-sortable-hoc-0.6.5.tgz#e6b5d414476d51a0b621931298855d4fd608c227"
dependencies:
babel-runtime "^6.11.6"
invariant "^2.2.1"
lodash "^4.12.0"
prop-types "^15.5.7"

react-sortable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/react-sortable/-/react-sortable-1.2.0.tgz#5acd7e1910df665408957035acb5f2354519d849"
Expand Down

0 comments on commit f204440

Please sign in to comment.