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

Feature/draggable #179

Merged
merged 9 commits into from
Jan 30, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,13 @@ module.exports = {
"!packages/dataparcels-docs/**"
],
testMatch: ["**/__test__/**/*-test.js?(x)"],
testURL: 'http://localhost'
testURL: 'http://localhost',
coverageThreshold: {
global: {
branches: 90,
functions: 90,
lines: 90,
statements: 90
}
}
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ParcelHoc from 'react-dataparcels/ParcelHoc';
import ParcelBoundary from 'react-dataparcels/ParcelBoundary';
import {SortableContainer, SortableElement} from 'react-sortable-hoc';
import ParcelDrag from 'react-dataparcels-drag';
import ExampleHoc from 'component/ExampleHoc';

const FruitListParcelHoc = ParcelHoc({
Expand All @@ -13,35 +13,20 @@ const FruitListParcelHoc = ParcelHoc({
]
});

const SortableFruitItem = SortableElement(({fruitParcel}) => {
return <ParcelBoundary parcel={fruitParcel}>
const SortableFruitList = ParcelDrag({
element: (fruitParcel) => <ParcelBoundary parcel={fruitParcel}>
{(parcel) => <div className="Box-draggable Typography">
<input type="text" {...parcel.spreadDOM()} />
<button onClick={() => parcel.insertAfter(`${parcel.value} copy`)}>+</button>
<button onClick={() => parcel.delete()}>x</button>
</div>}
</ParcelBoundary>;
});

const SortableFruitList = SortableContainer(({fruitListParcel}) => {
return <div>
{fruitListParcel.toArray((fruitParcel, index) => {
return <SortableFruitItem
key={fruitParcel.key}
index={index}
fruitParcel={fruitParcel}
/>;
})}
</div>;
</ParcelBoundary>
});

const FruitListEditor = (props) => {
let {fruitListParcel} = props;
return <div>
<SortableFruitList
fruitListParcel={fruitListParcel}
onSortEnd={({oldIndex, newIndex}) => fruitListParcel.move(oldIndex, newIndex)}
/>
<SortableFruitList parcel={fruitListParcel} />
<button onClick={() => fruitListParcel.push("New fruit")}>Add new fruit</button>
</div>;
};
Expand Down
40 changes: 13 additions & 27 deletions packages/dataparcels-docs/src/pages/examples/editing-arrays.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Link from 'gatsby-link';
import EditingArrays from 'examples/EditingArrays';
import EditingArraysFlipMove from 'examples/EditingArraysFlipMove';
import EditingArraysSortableHoc from 'examples/EditingArraysSortableHoc';
import EditingArraysDrag from 'examples/EditingArraysDrag';

Dataparcels has a powerful set of methods for manipulating indexed data types, such as arrays. This example demonstrates an editor that allows the user to edit, append to and sort the elements in an array of strings.

Expand Down Expand Up @@ -52,17 +52,19 @@ export default FruitListParcelHoc(FruitListEditor);

For the full list of methods you can use on indexed data types, see <Link to="/api/Parcel#indexed_change_methods">Indexed Change Methods</Link> and <Link to="/api/Parcel#element_change_methods">Element Change Methods</Link> in the Parcel API reference.

## Drag and drop with react-sortable-hoc
## Drag and drop with react-dataparcels-drag

Dataparcels' plays nicely with [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc). Drag items up and fown to change their order.
Drag and drop is easy using [react-dataparcels-drag](https://www.npmjs.com/package/react-dataparcels-drag), which is a slim wrapper around [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc). Drag items up and fown to change their order.

<EditingArraysSortableHoc />
THe `react-dataparcels-drag` HOC attempts to keep a very similar API to `react-sortable-hoc`, and therefore its usage is a little different compared to the other HOCs in `react-dataparcels`.

<EditingArraysDrag />

```js
import React from 'react';
import ParcelHoc from 'react-dataparcels/ParcelHoc';
import ParcelBoundary from 'react-dataparcels/ParcelBoundary';
import {SortableContainer, SortableElement} from 'react-sortable-hoc';
import ParcelDrag from 'react-dataparcels-drag';

const FruitListParcelHoc = ParcelHoc({
name: "fruitListParcel",
Expand All @@ -73,35 +75,20 @@ const FruitListParcelHoc = ParcelHoc({
]
});

const SortableFruitItem = SortableElement(({fruitParcel}) => {
return <ParcelBoundary parcel={fruitParcel}>
{(parcel) => <div>
const SortableFruitList = ParcelDrag({
element: (fruitParcel) => <ParcelBoundary parcel={fruitParcel}>
{(parcel) => <div className="Box-draggable Typography">
<input type="text" {...parcel.spreadDOM()} />
<button onClick={() => parcel.insertAfter(`${parcel.value} copy`)}>+</button>
<button onClick={() => parcel.delete()}>x</button>
</div>}
</ParcelBoundary>;
});

const SortableFruitList = SortableContainer(({fruitListParcel}) => {
return <div>
{fruitListParcel.toArray((fruitParcel, index) => {
return <SortableFruitItem
key={fruitParcel.key}
index={index}
fruitParcel={fruitParcel}
/>;
})}
</div>;
</ParcelBoundary>
});

const FruitListEditor = (props) => {
let {fruitListParcel} = props;
return <div>
<SortableFruitList
fruitListParcel={fruitListParcel}
onSortEnd={({oldIndex, newIndex}) => fruitListParcel.move(oldIndex, newIndex)}
/>
<SortableFruitList parcel={fruitListParcel} />
<button onClick={() => fruitListParcel.push("New fruit")}>Add new fruit</button>
</div>;
};
Expand All @@ -120,7 +107,6 @@ import React from 'react';
import FlipMove from 'react-flip-move';
import ParcelHoc from 'react-dataparcels/ParcelHoc';
import ParcelBoundary from 'react-dataparcels/ParcelBoundary';
import ExampleHoc from 'component/ExampleHoc';

const FruitListEditor = (props) => {
let {fruitListParcel} = props;
Expand Down Expand Up @@ -149,6 +135,6 @@ const FruitListParcelHoc = ParcelHoc({
name: "fruitListParcel"
});

export default FruitListParcelHoc(ExampleHoc(FruitListEditor));
export default FruitListParcelHoc(FruitListEditor);

```
14 changes: 14 additions & 0 deletions packages/react-dataparcels-drag/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
![dataparcels](https://user-images.githubusercontent.com/345320/48319791-4eece200-e666-11e8-8b19-252cd1135ae2.png)

<a href="https://www.npmjs.com/package/react-dataparcels-drag"><img src="https://img.shields.io/npm/v/react-dataparcels-drag.svg?style=flat-square"></a>
[![CircleCI](https://circleci.com/gh/blueflag/dataparcels/tree/master.svg?style=shield)](https://circleci.com/gh/blueflag/dataparcels/tree/master)

A plugin for [`react-dataparcels`](https://www.npmjs.com/package/react-dataparcels) that adds drag and drop re-ordering of elements, using the wonderful [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc).

## Example

**[See the example](https://dataparcels.blueflag.codes/examples/editing-arrays)**

## Packages

Get [`react-dataparcels-drag`](https://www.npmjs.com/package/react-dataparcels-drag).
9 changes: 9 additions & 0 deletions packages/react-dataparcels-drag/__test__/Exports-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @flow

// dataparcels exports
import Drag from '../src/index';
import InternalDrag from '../src/Drag';

test('index should export Drag', () => {
expect(Drag).toBe(InternalDrag);
});
32 changes: 32 additions & 0 deletions packages/react-dataparcels-drag/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "react-dataparcels-drag",
"version": "0.18.0-2",
"description": "A plugin for react-dataparcels that adds drag and drop re-ordering of elements.",
"main": "lib/index.js",
"license": "UNLICENSED",
"author": "Damien Clarke",
"repository": {
"type": "git",
"url": "git+https://github.com/blueflag/dataparcels.git"
},
"files": [
"lib"
],
"bugs": {
"url": "https://github.com/blueflag/dataparcels/issues"
},
"private": false,
"scripts": {
"build": "rm -rf lib && NODE_ENV=production babel src --out-dir lib --ignore '**/__test__/*.js'",
"build-all": "yarn build",
"watch": "yarn run build -w"
},
"dependencies": {
"babel-runtime": "6.23.0",
"react-sortable-hoc": "1.4.0"
},
"peerDependencies": {
"react": "16.4.2",
"react-dataparcels": "^0.18.0-2"
}
}
47 changes: 47 additions & 0 deletions packages/react-dataparcels-drag/src/Drag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// @flow

import type {ComponentType} from 'react';
import type {Node} from 'react';
import type Parcel from 'react-dataparcels';

import React from 'react';
import {SortableContainer} from 'react-sortable-hoc';
import {SortableElement} from 'react-sortable-hoc';

type Config = {
element: (parcel: Parcel, rest: *) => Node,
container?: ComponentType<*>
};

type Props = {
parcel: Parcel,
onSortEnd?: ({oldIndex: number, newIndex: number}) => void
};

export default ({element, container, ...configRest}: Config) => {
let Container = container || 'div';
let ConfiguredElement = SortableElement(({parcel, ...rest}) => element(parcel, rest));
let ConfiguredContainer = SortableContainer(({parcel}) => <Container>
{parcel.toArray((elementParcel, index) => <ConfiguredElement
key={elementParcel.key}
index={index}
parcel={elementParcel}
/>)}
</Container>);

return ({parcel, onSortEnd, ...rest}: Props): Node => {
if(!parcel.isIndexed()) {
throw new Error(`react-dataparcels-drag's parcel prop must be of type indexed`);
}
return <ConfiguredContainer
parcel={parcel}
onSortEnd={(param) => {
let {oldIndex, newIndex} = param;
parcel.move(oldIndex, newIndex);
onSortEnd && onSortEnd(param);
}}
{...configRest}
{...rest}
/>;
};
};