diff --git a/README.md b/README.md index 9f33ed9..5518d93 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Demo: http://rubaxa.github.io/Sortable/ * Supports * [Meteor](https://github.com/SortableJS/meteor) * [AngularJS](#ng) - * [React](#react) + * [React](https://github.com/SortableJS/react-mixin-sortablejs) * [Knockout](https://github.com/SortableJS/knockout-sortablejs) * [Polymer](https://github.com/SortableJS/polymer-sortablejs) * Supports any CSS library, e.g. [Bootstrap](#bs) @@ -366,148 +366,6 @@ angular.module('myApp', ['ng-sortable']) --- - -### Support React -Include [react-sortable-mixin.js](react-sortable-mixin.js). -See [more options](react-sortable-mixin.js#L26). - - -```jsx -var SortableList = React.createClass({ - mixins: [SortableMixin], - - getInitialState: function() { - return { - items: ['Mixin', 'Sortable'] - }; - }, - - handleSort: function (/** Event */evt) { /*..*/ }, - - render: function() { - return - } -}); - -React.render(, document.body); - - -// -// Groups -// -var AllUsers = React.createClass({ - mixins: [SortableMixin], - - sortableOptions: { - ref: "user", - group: "shared", - model: "users" - }, - - getInitialState: function() { - return { users: ['Abbi', 'Adela', 'Bud', 'Cate', 'Davis', 'Eric']; }; - }, - - render: function() { - return ( -

Users

- - ); - } -}); - -var ApprovedUsers = React.createClass({ - mixins: [SortableMixin], - sortableOptions: { group: "shared" }, - - getInitialState: function() { - return { items: ['Hal', 'Judy']; }; - }, - - render: function() { - return - } -}); - -React.render(
- -
- -
, document.body); -``` - -### Support React ES2015 / TypeScript syntax -As mixins are not supported in ES2015 / TypeScript syntax here is example of ES2015 ref based implementation. -Using refs is the preferred (by facebook) "escape hatch" to underlaying DOM nodes: [React: The ref Callback Attribute](https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute) - -```js -import * as React from "react"; -import Sortable from 'sortablejs'; - -export class SortableExampleEsnext extends React.Component { - - sortableContainersDecorator = (componentBackingInstance) => { - // check if backing instance not null - if (componentBackingInstance) { - let options = { - handle: ".group-title" // Restricts sort start click/touch to the specified element - }; - Sortable.create(componentBackingInstance, options); - } - }; - - sortableGroupDecorator = (componentBackingInstance) => { - // check if backing instance not null - if (componentBackingInstance) { - let options = { - draggable: "div", // Specifies which items inside the element should be sortable - group: "shared" - }; - Sortable.create(componentBackingInstance, options); - } - }; - - render() { - return ( -
-
-

Group 1

-
-
Swap them around
-
Swap us around
-
Swap things around
-
Swap everything around
-
-
-
-

Group 2

-
-
Swap them around
-
Swap us around
-
Swap things around
-
Swap everything around
-
-
-
- ); - } -} -``` - ---- - ### Method diff --git a/bower.json b/bower.json index a21c6ec..deabf8a 100644 --- a/bower.json +++ b/bower.json @@ -2,8 +2,7 @@ "name": "Sortable", "main": [ "Sortable.js", - "ng-sortable.js", - "react-sortable-mixin.js" + "ng-sortable.js" ], "homepage": "http://rubaxa.github.io/Sortable/", "authors": [ diff --git a/react-sortable-mixin.js b/react-sortable-mixin.js deleted file mode 100644 index e8c865f..0000000 --- a/react-sortable-mixin.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @author RubaXa - * @licence MIT - */ - -(function (factory) { - 'use strict'; - - if (typeof module != 'undefined' && typeof module.exports != 'undefined') { - module.exports = factory(require('./Sortable')); - } - else if (typeof define === 'function' && define.amd) { - define(['./Sortable'], factory); - } - else { - /* jshint sub:true */ - window['SortableMixin'] = factory(Sortable); - } -})(function (/** Sortable */Sortable) { - 'use strict'; - - var _nextSibling; - - var _activeComponent; - - var _defaultOptions = { - ref: 'list', - model: 'items', - - animation: 100, - onStart: 'handleStart', - onEnd: 'handleEnd', - onAdd: 'handleAdd', - onUpdate: 'handleUpdate', - onRemove: 'handleRemove', - onSort: 'handleSort', - onFilter: 'handleFilter', - onMove: 'handleMove' - }; - - - function _getModelName(component) { - return component.sortableOptions && component.sortableOptions.model || _defaultOptions.model; - } - - - function _getModelItems(component) { - var name = _getModelName(component), - items = component.state && component.state[name] || component.props[name]; - - return items.slice(); - } - - - function _extend(dst, src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - - return dst; - } - - - /** - * Simple and easy mixin-wrapper for rubaxa/Sortable library, in order to - * make reorderable drag-and-drop lists on modern browsers and touch devices. - * - * @mixin - */ - var SortableMixin = { - sortableMixinVersion: '0.1.1', - - - /** - * @type {Sortable} - * @private - */ - _sortableInstance: null, - - - componentDidMount: function () { - var DOMNode, options = _extend(_extend({}, _defaultOptions), this.sortableOptions || {}), - copyOptions = _extend({}, options), - - emitEvent = function (/** string */type, /** Event */evt) { - var method = this[options[type]]; - method && method.call(this, evt, this._sortableInstance); - }.bind(this); - - - // Bind callbacks so that "this" refers to the component - 'onStart onEnd onAdd onSort onUpdate onRemove onFilter onMove'.split(' ').forEach(function (/** string */name) { - copyOptions[name] = function (evt) { - if (name === 'onStart') { - _nextSibling = evt.item.nextElementSibling; - _activeComponent = this; - } - else if (name === 'onAdd' || name === 'onUpdate') { - evt.from.insertBefore(evt.item, _nextSibling); - - var newState = {}, - remoteState = {}, - oldIndex = evt.oldIndex, - newIndex = evt.newIndex, - items = _getModelItems(this), - remoteItems, - item; - - if (name === 'onAdd') { - remoteItems = _getModelItems(_activeComponent); - item = remoteItems.splice(oldIndex, 1)[0]; - items.splice(newIndex, 0, item); - - remoteState[_getModelName(_activeComponent)] = remoteItems; - } - else { - items.splice(newIndex, 0, items.splice(oldIndex, 1)[0]); - } - - newState[_getModelName(this)] = items; - - if (copyOptions.stateHandler) { - this[copyOptions.stateHandler](newState); - } else { - this.setState(newState); - } - - (this !== _activeComponent) && _activeComponent.setState(remoteState); - } - - setTimeout(function () { - emitEvent(name, evt); - }, 0); - }.bind(this); - }, this); - - DOMNode = this.getDOMNode() ? (this.refs[options.ref] || this).getDOMNode() : this.refs[options.ref] || this; - - /** @namespace this.refs — http://facebook.github.io/react/docs/more-about-refs.html */ - this._sortableInstance = Sortable.create(DOMNode, copyOptions); - }, - - componentWillReceiveProps: function (nextProps) { - var newState = {}, - modelName = _getModelName(this), - items = nextProps[modelName]; - - if (items) { - newState[modelName] = items; - this.setState(newState); - } - }, - - componentWillUnmount: function () { - this._sortableInstance.destroy(); - this._sortableInstance = null; - } - }; - - - // Export - return SortableMixin; -});