方正 7 жил өмнө
parent
commit
b6d59ebaf0

+ 5 - 0
README.md

@@ -4,6 +4,11 @@ Dragact is a react component, which allows you to build your own **dragable grid
 
 ![](https://github.com/215566435/React-dragger-layout/blob/master/example/image/NormalLayoutDemo.gif)
 
+### 快速安装
+```
+npm install --save dragact
+```
+
 
 # Demo
 [Live Demo](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html)

+ 26 - 0
dist/NormalLayout/index.js

@@ -0,0 +1,26 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var dragact_1 = require("../lib/dragact");
+require("./index.css");
+var Words = [
+    { content: 'You can do anything, but not everything.', img: 'http://pic.sc.chinaz.com/files/pic/pic9/201303/xpic10472.jpg' },
+    { content: 'Those who dare to fail miserably can achieve greatly.', img: 'https://img00.deviantart.net/1163/i/2013/059/d/7/irish_views_by_ssquared_photography-d5wjnsk.jpg' },
+    { content: 'You miss 100 percent of the shots you never take.', img: 'http://www.landsendhotel.co.uk/uploads/gallery/gallery/coastal_scenery_seascapes_6.jpg' },
+    { content: 'Those who believe in telekinetics, raise my hand.', img: 'https://tctechcrunch2011.files.wordpress.com/2017/10/26099344353_18cd6fabb8_k.jpg?w=738' },
+    { content: 'I’d rather live with a good question than a bad answer.', img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQVa26cLzh6PYUwY4LMpwbHyDHFmWi_w2JuqDzeOdm1IIEbBZO0Vg' }
+];
+var Card = function (props) {
+    var item = props.item;
+    return (React.createElement("div", { className: 'layout-Item' },
+        React.createElement("img", { src: item.img, style: { width: '100%', height: '60%' }, draggable: false, alt: 'card' }),
+        React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } }, item.content)));
+};
+exports.LayoutDemo = function () {
+    return (React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
+        React.createElement("div", null,
+            React.createElement("h1", { style: { textAlign: 'center' } }, "Normal Layout Demo"),
+            React.createElement(dragact_1.Dragact, { width: 800, col: 12, rowHeight: 800 / 12, margin: [5, 5], className: 'normal-layout' }, Words.map(function (el, index) {
+                return React.createElement(Card, { item: el, key: index, "data-set": { GridX: (index * 3) % 12, GridY: index * 2, w: 3, h: 3 } });
+            })))));
+};

+ 26 - 0
dist/SortedTable/index.js

@@ -0,0 +1,26 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var dragact_1 = require("../lib/dragact");
+require("./index.css");
+var Words = [
+    { content: 'You can do anything, but not everything.', img: 'http://pic.sc.chinaz.com/files/pic/pic9/201303/xpic10472.jpg' },
+    { content: 'Those who dare to fail miserably can achieve greatly.', img: 'https://img00.deviantart.net/1163/i/2013/059/d/7/irish_views_by_ssquared_photography-d5wjnsk.jpg' },
+    { content: 'You miss 100 percent of the shots you never take.', img: 'http://www.landsendhotel.co.uk/uploads/gallery/gallery/coastal_scenery_seascapes_6.jpg' },
+    { content: 'Those who believe in telekinetics, raise my hand.', img: 'https://tctechcrunch2011.files.wordpress.com/2017/10/26099344353_18cd6fabb8_k.jpg?w=738' },
+    { content: 'I’d rather live with a good question than a bad answer.', img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQVa26cLzh6PYUwY4LMpwbHyDHFmWi_w2JuqDzeOdm1IIEbBZO0Vg' }
+];
+var Cell = function (props) {
+    var item = props.item;
+    return (React.createElement("div", { className: 'layout-Cell' },
+        React.createElement("img", { src: item.img, style: { width: 45, height: 45 }, draggable: false, alt: 'card' }),
+        React.createElement("div", { style: { paddingLeft: 12, color: '#595959' } }, item.content)));
+};
+exports.SortedTable = function () {
+    return (React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
+        React.createElement("div", null,
+            React.createElement("h1", { style: { textAlign: 'center' } }, "Sorted Table Demo"),
+            React.createElement(dragact_1.Dragact, { width: 800, col: 1, rowHeight: 60, margin: [2, 2], className: 'normal-layout' }, Words.map(function (el, index) {
+                return React.createElement(Cell, { item: el, key: index, "data-set": { GridX: 0, GridY: 0, w: 1, h: 1 } });
+            })))));
+};

+ 26 - 0
dist/StaticHeader/index.js

@@ -0,0 +1,26 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var dragact_1 = require("../lib/dragact");
+require("./index.css");
+var Words = [
+    { content: 'Sorry I just can not move in any circumstances', img: 'http://pic.sc.chinaz.com/files/pic/pic9/201303/xpic10472.jpg', static: true },
+    { content: 'Those who dare to fail miserably can achieve greatly.', img: 'https://img00.deviantart.net/1163/i/2013/059/d/7/irish_views_by_ssquared_photography-d5wjnsk.jpg' },
+    { content: 'You miss 100 percent of the shots you never take.', img: 'http://www.landsendhotel.co.uk/uploads/gallery/gallery/coastal_scenery_seascapes_6.jpg' },
+    { content: 'Those who believe in telekinetics, raise my hand.', img: 'https://tctechcrunch2011.files.wordpress.com/2017/10/26099344353_18cd6fabb8_k.jpg?w=738' },
+    { content: 'I’d rather live with a good question than a bad answer.', img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQVa26cLzh6PYUwY4LMpwbHyDHFmWi_w2JuqDzeOdm1IIEbBZO0Vg' }
+];
+var Cell = function (props) {
+    var item = props.item;
+    return (React.createElement("div", { className: "layout-Cell " + (item.static ? "static" : ""), style: { background: item.static ? "#e8e8e8" : "" } },
+        React.createElement("img", { src: item.img, style: { width: 45, height: 45 }, draggable: false, alt: 'card' }),
+        React.createElement("div", { style: { paddingLeft: 12, color: '#595959' } }, item.content)));
+};
+exports.SortedTableWithStatic = function () {
+    return (React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
+        React.createElement("div", null,
+            React.createElement("h1", { style: { textAlign: 'center' } }, "Static Header Table Demo"),
+            React.createElement(dragact_1.Dragact, { width: 800, col: 1, rowHeight: 60, margin: [2, 2], className: 'normal-layout' }, Words.map(function (el, index) {
+                return React.createElement(Cell, { item: el, key: index, "data-set": { GridX: 0, GridY: index, w: 1, h: 1, static: el.static } });
+            })))));
+};

+ 50 - 0
dist/index.js

@@ -0,0 +1,50 @@
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var ReactDOM = require("react-dom");
+var index_1 = require("./NormalLayout/index");
+var SortedTable_1 = require("./SortedTable");
+var StaticHeader_1 = require("./StaticHeader");
+require("./index.css");
+var DemoMap = {
+    normalLayout: React.createElement(index_1.LayoutDemo, null),
+    SortedTable: React.createElement(SortedTable_1.SortedTable, null),
+    StaticHeader: React.createElement(StaticHeader_1.SortedTableWithStatic, null)
+};
+var DemoDispatcher = /** @class */ (function (_super) {
+    __extends(DemoDispatcher, _super);
+    function DemoDispatcher() {
+        var _this = _super !== null && _super.apply(this, arguments) || this;
+        _this.state = {
+            demo: React.createElement(index_1.LayoutDemo, null)
+        };
+        _this.handleLayoutChange = function (demoName) {
+            _this.setState({
+                demo: DemoMap[demoName]
+            });
+        };
+        return _this;
+    }
+    DemoDispatcher.prototype.render = function () {
+        var _this = this;
+        return (React.createElement("div", null,
+            React.createElement("div", { className: 'demo-button-layout' },
+                React.createElement("div", null, "Switch Demos"),
+                React.createElement("button", { onClick: function () { return _this.handleLayoutChange('normalLayout'); } }, "normalLayout"),
+                React.createElement("button", { onClick: function () { return _this.handleLayoutChange('SortedTable'); } }, "SortedTable"),
+                React.createElement("button", { onClick: function () { return _this.handleLayoutChange('StaticHeader'); } }, "StaticHeader")),
+            this.state.demo));
+    };
+    return DemoDispatcher;
+}(React.Component));
+ReactDOM.render(React.createElement(DemoDispatcher, null), document.getElementById('root'));

+ 118 - 0
dist/lib/GridItem.js

@@ -0,0 +1,118 @@
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var index_1 = require("./dragger/index");
+var correction_1 = require("./util/correction");
+var GridItem = /** @class */ (function (_super) {
+    __extends(GridItem, _super);
+    function GridItem(props) {
+        var _this = _super.call(this, props) || this;
+        _this.onDrag = _this.onDrag.bind(_this);
+        _this.onDragStart = _this.onDragStart.bind(_this);
+        _this.onDragEnd = _this.onDragEnd.bind(_this);
+        _this.calGridXY = _this.calGridXY.bind(_this);
+        _this.calColWidth = _this.calColWidth.bind(_this);
+        return _this;
+    }
+    /** 计算容器的每一个格子多大 */
+    GridItem.prototype.calColWidth = function () {
+        var _a = this.props, containerWidth = _a.containerWidth, col = _a.col, containerPadding = _a.containerPadding, margin = _a.margin;
+        if (margin) {
+            return (containerWidth - containerPadding[0] * 2 - margin[0] * (col + 1)) / col;
+        }
+        return (containerWidth - containerPadding[0] * 2 - 0 * (col + 1)) / col;
+    };
+    /**转化,计算网格的GridX,GridY值 */
+    GridItem.prototype.calGridXY = function (x, y) {
+        var _a = this.props, margin = _a.margin, containerWidth = _a.containerWidth, col = _a.col, w = _a.w, rowHeight = _a.rowHeight;
+        /**坐标转换成格子的时候,无须计算margin */
+        var GridX = Math.round(x / containerWidth * col);
+        var GridY = Math.round(y / (rowHeight + (margin ? margin[1] : 0)));
+        // /**防止元素出container */
+        return correction_1.checkInContainer(GridX, GridY, col, w);
+    };
+    /**给予一个grid的位置,算出元素具体的在容器中位置在哪里,单位是px */
+    GridItem.prototype.calGridItemPosition = function (GridX, GridY) {
+        var _a = this.props, margin = _a.margin, rowHeight = _a.rowHeight;
+        if (!margin)
+            margin = [0, 0];
+        var x = Math.round(GridX * this.calColWidth() + (GridX + 1) * margin[0]);
+        var y = Math.round(GridY * rowHeight + margin[1] * (GridY + 1));
+        return {
+            x: x,
+            y: y
+        };
+    };
+    GridItem.prototype.shouldComponentUpdate = function (props, state) {
+        return this.props.GridX !== props.GridX ||
+            this.props.GridY !== props.GridY ||
+            this.props.isUserMove !== props.isUserMove;
+    };
+    /**宽和高计算成为px */
+    GridItem.prototype.calWHtoPx = function (w, h) {
+        var margin = this.props.margin;
+        if (!margin)
+            margin = [0, 0];
+        var wPx = Math.round(w * this.calColWidth() + (w - 1) * margin[0]);
+        var hPx = Math.round(h * this.props.rowHeight + (h - 1) * margin[1]);
+        return { wPx: wPx, hPx: hPx };
+    };
+    GridItem.prototype.onDragStart = function (x, y) {
+        var _a = this.props, w = _a.w, h = _a.h, UniqueKey = _a.UniqueKey;
+        if (this.props.static)
+            return;
+        var _b = this.calGridXY(x, y), GridX = _b.GridX, GridY = _b.GridY;
+        this.props.onDragStart && this.props.onDragStart({
+            event: event, GridX: GridX, GridY: GridY, w: w, h: h, UniqueKey: UniqueKey + ''
+        });
+    };
+    GridItem.prototype.onDrag = function (event, x, y) {
+        if (this.props.static)
+            return;
+        var _a = this.calGridXY(x, y), GridX = _a.GridX, GridY = _a.GridY;
+        var _b = this.props, w = _b.w, h = _b.h, UniqueKey = _b.UniqueKey;
+        this.props.onDrag && this.props.onDrag({ GridX: GridX, GridY: GridY, w: w, h: h, UniqueKey: UniqueKey + '', event: event });
+    };
+    GridItem.prototype.onDragEnd = function () {
+        if (this.props.static)
+            return;
+        if (this.props.onDragEnd)
+            this.props.onDragEnd(this.props.UniqueKey + '');
+    };
+    GridItem.prototype.render = function () {
+        var _a = this.props, w = _a.w, h = _a.h, style = _a.style, bounds = _a.bounds, GridX = _a.GridX, GridY = _a.GridY;
+        var _b = this.calGridItemPosition(GridX, GridY), x = _b.x, y = _b.y;
+        var _c = this.calWHtoPx(w, h), wPx = _c.wPx, hPx = _c.hPx;
+        return (React.createElement(index_1.Dragger, { style: __assign({}, style, { width: wPx, height: hPx, position: 'absolute', transition: this.props.isUserMove ? '' : 'all .2s' }), onDragStart: this.onDragStart, onMove: this.onDrag, onDragEnd: this.onDragEnd, x: x, y: y, isUserMove: this.props.isUserMove, bounds: bounds },
+            React.createElement("div", { style: { width: wPx, height: hPx } }, React.Children.map(this.props.children, function (child) { return child; }))));
+    };
+    GridItem.defaultProps = {
+        col: 12,
+        containerWidth: 500,
+        containerPadding: [0, 0],
+        margin: [10, 10],
+        rowHeight: 30,
+        w: 1,
+        h: 1
+    };
+    return GridItem;
+}(React.Component));
+exports.default = GridItem;

+ 136 - 0
dist/lib/dragact.js

@@ -0,0 +1,136 @@
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var GridItem_1 = require("./GridItem");
+var compact_1 = require("./util/compact");
+var sort_1 = require("./util/sort");
+var collison_1 = require("./util/collison");
+var correction_1 = require("./util/correction");
+var utils_1 = require("./utils");
+var initiate_1 = require("./util/initiate");
+require("./style.css");
+var Dragact = /** @class */ (function (_super) {
+    __extends(Dragact, _super);
+    function Dragact(props) {
+        var _this = _super.call(this, props) || this;
+        _this.onDrag = _this.onDrag.bind(_this);
+        _this.onDragStart = _this.onDragStart.bind(_this);
+        _this.onDragEnd = _this.onDragEnd.bind(_this);
+        var layout = props.layout ?
+            initiate_1.MapLayoutTostate(props.layout, props.children)
+            :
+                utils_1.getDataSet(props.children);
+        _this.state = {
+            GridXMoving: 0,
+            GridYMoving: 0,
+            wMoving: 0,
+            hMoving: 0,
+            placeholderShow: false,
+            placeholderMoving: false,
+            layout: layout,
+            containerHeight: 500
+        };
+        return _this;
+    }
+    Dragact.prototype.onDragStart = function (bundles) {
+        var GridX = bundles.GridX, GridY = bundles.GridY, w = bundles.w, h = bundles.h, UniqueKey = bundles.UniqueKey;
+        var newlayout = initiate_1.syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
+        this.setState({
+            GridXMoving: GridX,
+            GridYMoving: GridY,
+            wMoving: w,
+            hMoving: h,
+            placeholderShow: true,
+            placeholderMoving: true,
+            layout: newlayout,
+        });
+        this.props.onDragStart && this.props.onDragStart(bundles);
+    };
+    Dragact.prototype.onDrag = function (layoutItem) {
+        var GridY = layoutItem.GridY, UniqueKey = layoutItem.UniqueKey;
+        var moving = GridY - this.state.GridYMoving;
+        var newLayout = collison_1.layoutCheck(this.state.layout, layoutItem, UniqueKey, UniqueKey /*用户移动方块的key */, moving);
+        var compactedLayout = compact_1.compactLayout(newLayout);
+        for (var i = 0; i < compactedLayout.length; i++) {
+            var compactedItem = compactedLayout[i];
+            if (UniqueKey === compactedItem.key) {
+                /**
+                 * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
+                 * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
+                 * 但是实际layout中的位置还是会改变
+                 * (isUserMove=true用于解除placeholder和元素的绑定)
+                 */
+                compactedItem.isUserMove = true;
+                layoutItem.GridX = compactedItem.GridX;
+                layoutItem.GridY = compactedItem.GridY;
+                break;
+            }
+        }
+        this.setState({
+            GridXMoving: layoutItem.GridX,
+            GridYMoving: layoutItem.GridY,
+            layout: compactedLayout,
+            containerHeight: sort_1.getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
+        });
+        this.props.onDrag && this.props.onDrag(layoutItem);
+    };
+    Dragact.prototype.onDragEnd = function (key) {
+        var compactedLayout = compact_1.compactLayout(this.state.layout);
+        this.setState({
+            placeholderShow: false,
+            layout: compactedLayout,
+            containerHeight: sort_1.getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
+        });
+        this.props.onDragEnd && this.props.onDragEnd(key);
+    };
+    Dragact.prototype.renderPlaceholder = function () {
+        if (!this.state.placeholderShow)
+            return null;
+        var _a = this.props, col = _a.col, width = _a.width, padding = _a.padding, rowHeight = _a.rowHeight, margin = _a.margin;
+        var _b = this.state, GridXMoving = _b.GridXMoving, GridYMoving = _b.GridYMoving, wMoving = _b.wMoving, hMoving = _b.hMoving, placeholderMoving = _b.placeholderMoving;
+        if (!padding)
+            padding = 0;
+        return (React.createElement(GridItem_1.default, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: GridXMoving, GridY: GridYMoving, w: wMoving, h: hMoving, style: { background: '#d6e4ff', zIndex: 1, transition: ' all .15s' }, isUserMove: !placeholderMoving }));
+    };
+    Dragact.prototype.componentDidMount = function () {
+        var _this = this;
+        setTimeout(function () {
+            var layout = correction_1.correctLayout(_this.state.layout, _this.props.col);
+            var compacted = compact_1.compactLayout(layout);
+            _this.setState({
+                layout: compacted,
+                containerHeight: sort_1.getMaxContainerHeight(compacted, _this.props.rowHeight, _this.props.margin[1])
+            });
+        }, 1);
+    };
+    Dragact.prototype.getGridItem = function (child, index) {
+        var layout = this.state.layout;
+        var _a = this.props, col = _a.col, width = _a.width, padding = _a.padding, rowHeight = _a.rowHeight, margin = _a.margin;
+        var renderItem = initiate_1.layoutItemForkey(layout, child.key); //TODO:可以优化速度,这一步不是必须;
+        if (renderItem) {
+            if (!padding)
+                padding = 0;
+            return (React.createElement(GridItem_1.default, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: renderItem.GridX, GridY: renderItem.GridY, w: renderItem.w, h: renderItem.h, onDrag: this.onDrag, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, isUserMove: renderItem.isUserMove !== void 666 ? renderItem.isUserMove : false, UniqueKey: child.key, style: { zIndex: 2 }, static: renderItem.static }, child));
+        }
+    };
+    Dragact.prototype.render = function () {
+        var _this = this;
+        var _a = this.props, width = _a.width, className = _a.className;
+        var containerHeight = this.state.containerHeight;
+        return (React.createElement("div", { className: utils_1.stringJoin('DraggerLayout', className + ''), style: { left: 100, width: width, height: containerHeight, zIndex: 1 } },
+            React.Children.map(this.props.children, function (child, index) { return _this.getGridItem(child, index); }),
+            this.renderPlaceholder()));
+    };
+    return Dragact;
+}(React.Component));
+exports.Dragact = Dragact;

+ 242 - 0
dist/lib/dragger/index.js

@@ -0,0 +1,242 @@
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var React = require("react");
+var utils_1 = require("../utils");
+/// <reference path="react.d.ts" />
+var doc = document;
+var Dragger = /** @class */ (function (_super) {
+    __extends(Dragger, _super);
+    function Dragger(props) {
+        var _this = _super.call(this, props) || this;
+        _this.state = {
+            /** x轴位移,单位是px */
+            x: 0,
+            /** y轴位移,单位是px */
+            y: 0,
+            /**鼠标点击元素的原始位置,单位是px */
+            originX: 0,
+            originY: 0,
+            isUserMove: true,
+            /**已经移动的位移,单位是px */
+            lastX: 0,
+            lastY: 0,
+            /**堆叠的层级 */
+            zIndex: 1
+        };
+        _this.move = _this.move.bind(_this);
+        _this.onDragEnd = _this.onDragEnd.bind(_this);
+        _this.parent = null;
+        _this.self = null;
+        return _this;
+    }
+    Dragger.prototype.move = function (event) {
+        var _a = this.state, lastX = _a.lastX, lastY = _a.lastY;
+        /*  event.client - this.state.origin 表示的是移动的距离,
+        *   elX表示的是原来已经有的位移
+        */
+        var deltaX, deltaY;
+        if (event.type.indexOf('mouse') >= 0) {
+            deltaX = event.clientX - this.state.originX + lastX;
+            deltaY = event.clientY - this.state.originY + lastY;
+        }
+        else {
+            deltaX = event.touches[0].clientX - this.state.originX + lastX;
+            deltaY = event.touches[0].clientY - this.state.originY + lastY;
+        }
+        var bounds = this.props.bounds;
+        if (bounds) {
+            /**
+            * 如果用户指定一个边界,那么在这里处理
+            */
+            var NewBounds = typeof bounds !== 'string' ? utils_1.parseBounds(bounds) : bounds;
+            /**
+             * 网格式移动范围设定,永远移动 n 的倍数
+             * 注意:设定移动范围的时候,一定要在判断bounds之前,否则会造成bounds不对齐
+             */
+            var grid = this.props.grid;
+            if (Array.isArray(grid) && grid.length === 2) {
+                deltaX = Math.round(deltaX / grid[0]) * grid[0];
+                deltaY = Math.round(deltaY / grid[1]) * grid[1];
+            }
+            if (this.props.bounds === 'parent') {
+                NewBounds = {
+                    left: utils_1.int(this.parent.style.paddingLeft) + utils_1.int(this.self.style.marginLeft) - this.self.offsetLeft,
+                    top: utils_1.int(this.parent.style.paddingTop) + utils_1.int(this.self.style.marginTop) - this.self.offsetTop,
+                    right: utils_1.innerWidth(this.parent) - utils_1.outerWidth(this.self) - this.self.offsetLeft +
+                        utils_1.int(this.parent.style.paddingRight) - utils_1.int(this.self.style.marginRight),
+                    bottom: utils_1.innerHeight(this.parent) - utils_1.outerHeight(this.self) - this.self.offsetTop +
+                        utils_1.int(this.parent.style.paddingBottom) - utils_1.int(this.self.style.marginBottom)
+                };
+            }
+            /**
+             * 保证不超出右边界和底部
+             * keep element right and bot can not cross the bounds
+             */
+            if (NewBounds !== 'parent')
+                deltaX = Math.min(deltaX, NewBounds.right);
+            if (NewBounds !== 'parent')
+                deltaY = Math.min(deltaY, NewBounds.bottom);
+            /**
+             * 保证不超出左边和上边
+             * keep element left and top can not cross the bounds
+             */
+            if (NewBounds !== 'parent')
+                deltaX = Math.max(deltaX, NewBounds.left);
+            if (NewBounds !== 'parent')
+                deltaY = Math.max(deltaY, NewBounds.top);
+        }
+        /**如果设置了x,y限制 */
+        deltaX = this.props.allowX ? deltaX : 0;
+        deltaY = this.props.allowY ? deltaY : 0;
+        /**移动时回调,用于外部控制 */
+        if (this.props.onMove)
+            this.props.onMove(event, deltaX, deltaY);
+        this.setState({
+            x: deltaX,
+            y: deltaY
+        });
+    };
+    Dragger.prototype.onDragStart = function (event) {
+        /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
+        doc.body.style.userSelect = 'none';
+        // if (this.props.hasDraggerHandle) {
+        //     if (event.target.className !== 'handle') return
+        // }
+        /**
+         * 把监听事件的回掉函数,绑定在document上
+         * 当设置边界的时候,用户鼠标会离开元素的范围
+         * 绑定在document上可以使得其依旧能够监听
+         * 如果绑定在元素上,则鼠标离开元素,就不会再被监听了
+         */
+        if (event.type.indexOf('mouse') >= 0) {
+            doc.addEventListener('mousemove', this.move);
+            doc.addEventListener('mouseup', this.onDragEnd);
+        }
+        else {
+            doc.addEventListener('touchmove', this.move);
+            doc.addEventListener('touchend', this.onDragEnd);
+        }
+        if (this.props.bounds === 'parent' &&
+            /**为了让 这段代码不会重复执行 */
+            (typeof this.parent === 'undefined' || this.parent === null)) {
+            /**
+             * 在这里我们将父节点缓存下来,保证当用户鼠标离开拖拽区域时,我们仍然能获取到父节点
+             * what we do here is
+             * making sure that we still can retrieve our parent when user's mouse left this node.
+             */
+            this.parent = event.currentTarget.offsetParent; //todo
+            /**
+             * 我们自己
+             * ourself
+             */
+            this.self = event.currentTarget;
+        }
+        this.props.onDragStart && this.props.onDragStart(this.state.x, this.state.y);
+        var originX, originY;
+        if (event.type.indexOf('mouse') >= 0) {
+            originX = event.clientX;
+            originY = event.clientY;
+        }
+        else {
+            originX = event.touches[0].clientX;
+            originY = event.touches[0].clientY;
+        }
+        this.setState({
+            originX: originX,
+            originY: originY,
+            lastX: this.state.x,
+            lastY: this.state.y,
+            zIndex: 10
+        });
+    };
+    Dragger.prototype.onDragEnd = function (event) {
+        /** 取消用户选择限制,用户可以重新选择 */
+        doc.body.style.userSelect = '';
+        this.parent = null;
+        this.self = null;
+        if (event.type.indexOf('mouse') >= 0) {
+            doc.removeEventListener('mousemove', this.move);
+            doc.removeEventListener('mouseup', this.onDragEnd);
+        }
+        else {
+            doc.removeEventListener('touchmove', this.move);
+            doc.removeEventListener('touchend', this.onDragEnd);
+        }
+        this.setState({
+            zIndex: 1
+        });
+        this.props.onDragEnd && this.props.onDragEnd(event);
+    };
+    Dragger.prototype.componentDidMount = function () {
+        /**
+         * 这个函数只会调用一次
+         * 这个只是一个临时的解决方案,因为这样会使得元素进行两次刷新
+        */
+        if (typeof this.props.x === 'number' &&
+            typeof this.props.y === 'number') {
+            this.setState({
+                x: this.props.x,
+                y: this.props.y
+            });
+        }
+    };
+    Dragger.prototype.componentWillReceiveProps = function (nextProps) {
+        /**
+         * 外部props 改变的时候更新元素的内部位置
+         * 这个api设计其实很不好
+         * 以后可能会修改掉
+         */
+        var isUserMove = nextProps.isUserMove;
+        if (!isUserMove) {
+            if (typeof nextProps.x === 'number' &&
+                typeof nextProps.y === 'number') {
+                this.setState({
+                    x: nextProps.x,
+                    y: nextProps.y,
+                    lastX: nextProps.x,
+                    lastY: nextProps.y
+                });
+            }
+        }
+    };
+    Dragger.prototype.render = function () {
+        var _a = this.state, x = _a.x, y = _a.y, zIndex = _a.zIndex;
+        var _b = this.props, style = _b.style, className = _b.className;
+        if (!this.props.isUserMove) {
+            /**当外部设置其props的x,y初始属性的时候,我们在这里设置元素的初始位移 */
+            x = this.props.x ? this.props.x : 0;
+            y = this.props.y ? this.props.y : 0;
+        }
+        /**主要是为了让用户定义自己的className去修改css */
+        var fixedClassName = typeof className === 'undefined' ? '' : className + ' ';
+        return (React.createElement("div", { className: fixedClassName + "WrapDragger", style: __assign({}, style, { zIndex: zIndex, touchAction: 'none!important', transform: "translate(" + x + "px," + y + "px)" }), onMouseDown: this.onDragStart.bind(this), onTouchStart: this.onDragStart.bind(this), onTouchEnd: this.onDragEnd.bind(this), onMouseUp: this.onDragEnd.bind(this) }, React.Children.only(this.props.children)));
+    };
+    /**
+     * 初始变量设置
+     */
+    Dragger.defaultProps = {
+        allowX: true,
+        allowY: true,
+        isUserMove: true
+    };
+    return Dragger;
+}(React.Component));
+exports.Dragger = Dragger;

+ 102 - 0
dist/lib/util/collison.js

@@ -0,0 +1,102 @@
+"use strict";
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.collision = function (a, b) {
+    if (a.GridX === b.GridX && a.GridY === b.GridY &&
+        a.w === b.w && a.h === b.h) {
+        return true;
+    }
+    if (a.GridX + a.w <= b.GridX)
+        return false;
+    if (a.GridX >= b.GridX + b.w)
+        return false;
+    if (a.GridY + a.h <= b.GridY)
+        return false;
+    if (a.GridY >= b.GridY + b.h)
+        return false;
+    return true;
+};
+/**获取layout中,item第一个碰撞到的物体 */
+exports.getFirstCollison = function (layout, item) {
+    for (var i = 0, length_1 = layout.length; i < length_1; i++) {
+        if (exports.collision(layout[i], item)) {
+            return layout[i];
+        }
+    }
+    return null;
+};
+exports.layoutCheck = function (layout, layoutItem, key, fristItemkey, moving) {
+    var i = [], movedItem = []; /**收集所有移动过的物体 */
+    var newlayout = layout.map(function (item, idx) {
+        if (item.key !== key) {
+            if (item.static) {
+                return item;
+            }
+            if (exports.collision(item, layoutItem)) {
+                i.push(item.key);
+                /**
+                 * 这里就是奇迹发生的地方,如果向上移动,那么必须注意的是
+                 * 一格一格的移动,而不是一次性移动
+                 */
+                var offsetY = item.GridY + 1;
+                /**这一行也非常关键,当向上移动的时候,碰撞的元素必须固定 */
+                // if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY
+                if (layoutItem.GridY > item.GridY && layoutItem.GridY < item.GridY + item.h) {
+                    /**
+                     * 元素向上移动时,元素的上面空间不足,则不移动这个元素
+                     * 当元素移动到GridY>所要向上交换的元素时,就不会进入这里,直接交换元素
+                     */
+                    offsetY = item.GridY;
+                }
+                /**
+                 * 物体向下移动的时候
+                 */
+                if (moving > 0) {
+                    if (layoutItem.GridY + layoutItem.h < item.GridY) {
+                        var collision_1;
+                        var copy_1 = __assign({}, item);
+                        while (true) {
+                            var newLayout = layout.filter(function (item) {
+                                if (item.key !== key && (item.key !== copy_1.key)) {
+                                    return item;
+                                }
+                            });
+                            collision_1 = exports.getFirstCollison(newLayout, copy_1);
+                            if (collision_1) {
+                                offsetY = collision_1.GridY + collision_1.h;
+                                break;
+                            }
+                            else {
+                                copy_1.GridY--;
+                            }
+                            if (copy_1.GridY < 0) {
+                                offsetY = 0;
+                                break;
+                            }
+                        }
+                    }
+                }
+                movedItem.push(__assign({}, item, { GridY: offsetY, isUserMove: false }));
+                return __assign({}, item, { GridY: offsetY, isUserMove: false });
+            }
+        }
+        else if (fristItemkey === key) {
+            /**永远保持用户移动的块是 isUserMove === true */
+            return __assign({}, item, { GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true });
+        }
+        return item;
+    });
+    /** 递归调用,将layout中的所有重叠元素全部移动 */
+    var length = movedItem.length;
+    for (var c = 0; c < length; c++) {
+        newlayout = exports.layoutCheck(newlayout, movedItem[c], i[c], fristItemkey, 0);
+    }
+    return newlayout;
+};

+ 55 - 0
dist/lib/util/compact.js

@@ -0,0 +1,55 @@
+"use strict";
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var sort_1 = require("./sort");
+var collison_1 = require("./collison");
+/**
+ * 压缩单个元素,使得每一个元素都会紧挨着边界或者相邻的元素
+ * @param {*} finishedLayout 压缩完的元素会放进这里来,用来对比之后的每一个元素是否需要压缩
+ * @param {*} item
+ */
+exports.compactItem = function (finishedLayout, item) {
+    if (item.static)
+        return item;
+    var newItem = __assign({}, item);
+    if (finishedLayout.length === 0) {
+        return __assign({}, newItem, { GridY: 0 });
+    }
+    /**
+     * 类似一个递归调用
+     */
+    while (true) {
+        var FirstCollison = collison_1.getFirstCollison(finishedLayout, newItem);
+        if (FirstCollison) {
+            /**第一次发生碰撞时,就可以返回了 */
+            newItem.GridY = FirstCollison.GridY + FirstCollison.h;
+            return newItem;
+        }
+        newItem.GridY--;
+        if (newItem.GridY < 0)
+            return __assign({}, newItem, { GridY: 0 }); /**碰到边界的时候,返回 */
+    }
+};
+/**
+ * 压缩layout,使得每一个元素都会紧挨着边界或者相邻的元素
+ * @param {*} layout
+ */
+exports.compactLayout = function (layout) {
+    var sorted = sort_1.sortLayout(layout);
+    var needCompact = Array(layout.length);
+    var compareList = [];
+    for (var i = 0, length_1 = sorted.length; i < length_1; i++) {
+        var finished = exports.compactItem(compareList, sorted[i]);
+        finished.isUserMove = false;
+        compareList.push(finished);
+        needCompact[i] = finished;
+    }
+    return needCompact;
+};

+ 33 - 0
dist/lib/util/correction.js

@@ -0,0 +1,33 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var collison_1 = require("./collison");
+exports.checkInContainer = function (GridX, GridY, col, w) {
+    /**防止元素出container */
+    if (GridX + w > col - 1)
+        GridX = col - w; //右边界
+    if (GridX < 0)
+        GridX = 0; //左边界
+    if (GridY < 0)
+        GridY = 0; //上边界
+    return { GridX: GridX, GridY: GridY };
+};
+/**
+ * 这个函数会有副作用,不是纯函数,会改变item的Gridx和GridY
+ * @param {*} item
+ */
+exports.correctItem = function (item, col) {
+    var _a = exports.checkInContainer(item.GridX, item.GridY, col, item.w), GridX = _a.GridX, GridY = _a.GridY;
+    item.GridX = GridX;
+    item.GridY = GridY;
+};
+exports.correctLayout = function (layout, col) {
+    var copy = layout.slice();
+    for (var i = 0; i < layout.length - 1; i++) {
+        exports.correctItem(copy[i], col);
+        exports.correctItem(copy[i + 1], col);
+        if (collison_1.collision(copy[i], copy[i + 1])) {
+            copy = collison_1.layoutCheck(copy, copy[i], copy[i].UniqueKey, copy[i].UniqueKey, 0);
+        }
+    }
+    return copy;
+};

+ 55 - 0
dist/lib/util/initiate.js

@@ -0,0 +1,55 @@
+"use strict";
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * 把用户移动的块,标记为true
+ * @param {*} layout
+ * @param {*} key
+ * @param {*} GridX
+ * @param {*} GridY
+ * @param {*} isUserMove
+ */
+exports.syncLayout = function (layout, key, GridX, GridY, isUserMove) {
+    var newlayout = layout.map(function (item) {
+        if (item.key === key) {
+            item.GridX = GridX;
+            item.GridY = GridY;
+            item.isUserMove = isUserMove;
+            return item;
+        }
+        return item;
+    });
+    return newlayout;
+};
+/**
+ * 初始化的时候调用
+ * 会把isUserMove和key一起映射到layout中
+ * 不用用户设置
+ * @param {*} layout
+ * @param {*} children
+ */
+exports.MapLayoutTostate = function (layout, children) {
+    return layout.map(function (child, index) {
+        var newChild = __assign({}, child, { isUserMove: true, key: children[index].key, static: children[index].static });
+        return newChild;
+    });
+};
+/**
+ * 用key从layout中拿出item
+ * @param {*} layout 输入进来的布局
+ * @param {*} key
+ */
+exports.layoutItemForkey = function (layout, key) {
+    for (var i = 0, length_1 = layout.length; i < length_1; i++) {
+        if (key === layout[i].key) {
+            return layout[i];
+        }
+    }
+};

+ 29 - 0
dist/lib/util/sort.js

@@ -0,0 +1,29 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function quickSort(a) {
+    return a.length <= 1 ? a : quickSort(a.slice(1).filter(function (item) { return item <= a[0]; })).concat(a[0], quickSort(a.slice(1).filter(function (item) { return item > a[0]; })));
+}
+exports.quickSort = quickSort;
+exports.sortLayout = function (layout) {
+    return [].concat(layout).sort(function (a, b) {
+        if (a.GridY > b.GridY || (a.GridY === b.GridY && a.GridX > b.GridX)) {
+            if (a.static)
+                return 0; //为了静态,排序的时候尽量把静态的放在前面
+            return 1;
+        }
+        else if (a.GridY === b.GridY && a.GridX === b.GridX) {
+            return 0;
+        }
+        return -1;
+    });
+};
+exports.getMaxContainerHeight = function (layout, elementHeight, elementMarginBottom) {
+    if (elementHeight === void 0) { elementHeight = 30; }
+    if (elementMarginBottom === void 0) { elementMarginBottom = 10; }
+    var ar = layout.map(function (item) {
+        return item.GridY + item.h;
+    });
+    var h = quickSort(ar)[ar.length - 1];
+    var height = h * (elementHeight + elementMarginBottom) + elementMarginBottom;
+    return height;
+};

+ 63 - 0
dist/lib/utils.js

@@ -0,0 +1,63 @@
+"use strict";
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+            t[p] = s[p];
+    }
+    return t;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.int = function (number) {
+    if (number === '' || number === null) {
+        return 0;
+    }
+    return parseInt(number, 10);
+};
+exports.innerWidth = function (node) {
+    var width = node.clientWidth;
+    var computedStyle = node.style;
+    width -= exports.int(computedStyle.paddingLeft);
+    width -= exports.int(computedStyle.paddingRight);
+    return width;
+};
+exports.outerWidth = function (node) {
+    var width = node.clientWidth;
+    var computedStyle = node.style;
+    width += exports.int(computedStyle.borderLeftWidth);
+    width += exports.int(computedStyle.borderRightWidth);
+    return width;
+};
+exports.innerHeight = function (node) {
+    var height = node.clientHeight;
+    var computedStyle = node.style;
+    height -= exports.int(computedStyle.paddingTop);
+    height -= exports.int(computedStyle.paddingBottom);
+    return height;
+};
+exports.outerHeight = function (node) {
+    var height = node.clientHeight;
+    var computedStyle = node.style;
+    height += exports.int(computedStyle.borderTopWidth);
+    height += exports.int(computedStyle.borderBottomWidth);
+    return height;
+};
+exports.parseBounds = function (bounds) {
+    return {
+        left: bounds.left,
+        top: bounds.top,
+        right: bounds.right,
+        bottom: bounds.bottom
+    };
+};
+exports.isNumber = function (things) {
+    return typeof things === 'number' ? true : false;
+};
+exports.getDataSet = function (children) {
+    return children.map(function (child) {
+        return __assign({}, child.props['data-set'], { isUserMove: true, key: child.key });
+    });
+};
+exports.stringJoin = function (source, join) {
+    return source + (join ? " " + join : '');
+};

+ 8 - 0
index.d.ts

@@ -0,0 +1,8 @@
+import * as React from 'react';
+import { DragactProps } from './src/lib/dragact';
+
+declare class Dragact extends React.Component<DragactProps, {}> {
+}
+
+export = Dragact;
+export as namespace Dragact;

+ 2 - 2
index.js

@@ -1,7 +1,7 @@
-var Draggable = require('./build/Dragger').default;
+var Dragact = require('./dist/lib/dragact').Dragact;
 
 // Previous versions of this lib exported <Draggable> as the root export. As to not break
 // them, or TypeScript, we export *both* as the root and as 'default'.
 // See https://github.com/mzabriskie/react-draggable/pull/254
 // and https://github.com/mzabriskie/react-draggable/issues/266
-module.exports = Draggable;
+exports.Dragact = Dragact;

+ 1 - 1
src/lib/dragact.tsx

@@ -20,7 +20,7 @@ export interface DragactLayout {
     key?: number | string
 }
 
-interface DragactProps {
+export interface DragactProps {
     layout?: DragactLayout[] //暂时不推荐使用
     /** 
      * 宽度切分比