Эх сурвалжийг харах

Merge branch 'master' of https://github.com/215566435/Dragact

* 'master' of https://github.com/215566435/Dragact: (21 commits)
  remove & ignore yarn.lock
  (feat): remove hisotry props type from dragact
  (refactor): 将 操作历史 功能从 dragact 中移出 (changed): 添加 dragact 的 props 中的 layout 改变时 重新计算 mapLayout 等的逻辑
  fix: 调整到正确的 history mode
  fix: 添加 ts 类型给 compact, 并修复错误的 logic
  添加 Historymode 的 demo
  调整是否记录的比较方式 添加 reset 方法
  add history for proform actions
  发布0.1.8
  修复在火狐下的bug
  修正展示界面的add/remove
  add readme/remove add
  adding layout
  change log update
  readme更新
  更新github图标
  优化readme
  readme update
  pre-0.1.7
  优化dom层级,自定义拖拽把手和resize把手
  ...
方正 7 жил өмнө
parent
commit
583e4def9e
42 өөрчлөгдсөн 1186 нэмэгдсэн , 482 устгасан
  1. 1 0
      .gitignore
  2. 94 51
      README.md
  3. 0 0
      build/react-dragger-layout.js
  4. 98 72
      dist/AddRemove/index.js
  5. 15 8
      dist/HandleLayout/index.js
  6. 4 8
      dist/LayoutRestore/index.js
  7. 13 8
      dist/NormalLayout/index.js
  8. 7 7
      dist/StaticWidget/index.js
  9. 57 3
      dist/index.js
  10. 3 3
      dist/lib/GridItem.js
  11. 24 20
      dist/lib/dragact.js
  12. 39 31
      dist/lib/dragger/index.js
  13. 1 1
      dist/lib/util/compact.js
  14. 1 1
      dist/lib/util/correction.js
  15. 9 7
      dist/lib/util/sort.js
  16. 7 8
      dist/mobileLayout/index.js
  17. 26 0
      dist/showdown/index.js
  18. 7 0
      example/changelog.md
  19. BIN
      example/image/dashboard.gif
  20. BIN
      example/image/手感优化前``.gif
  21. 108 1
      package-lock.json
  22. 4 2
      package.json
  23. 92 71
      src/AddRemove/index.tsx
  24. 20 10
      src/HandleLayout/index.tsx
  25. 121 0
      src/HistoryLayout/HistoryLayout.tsx
  26. 13 0
      src/HistoryLayout/index.css
  27. 106 0
      src/HistoryLayout/index.tsx
  28. 31 0
      src/HistoryLayout/largedata.ts
  29. 4 11
      src/LayoutRestore/index.tsx
  30. 21 14
      src/NormalLayout/index.tsx
  31. 10 8
      src/StaticWidget/index.tsx
  32. 68 7
      src/index.tsx
  33. 56 51
      src/lib/dragact.tsx
  34. 60 47
      src/lib/dragger/index.tsx
  35. 6 3
      src/lib/gridItem.tsx
  36. 1 1
      src/lib/util/collison.ts
  37. 3 2
      src/lib/util/compact.ts
  38. 1 1
      src/lib/util/correction.ts
  39. 1 1
      src/lib/util/initiate.ts
  40. 10 7
      src/lib/util/sort.ts
  41. 12 17
      src/mobileLayout/index.tsx
  42. 32 0
      src/showdown/index.ts

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 .DS_Store
 node_modules/
 npm-debug.log
+yarn.lock

+ 94 - 51
README.md

@@ -1,24 +1,24 @@
-# Dragact
+# Dragact 👋
 [![npm version](https://img.shields.io/npm/v/dragact.svg)](https://www.npmjs.com/package/dragact) [![npm downloads](https://img.shields.io/npm/dm/dragact.svg)](https://www.npmjs.com/package/dragact)
 
 
 Dragact 是一款React组件,他能够使你简单、快速的构建出一款强大的 **拖拽式网格(grid)布局**.
 
-![](https://github.com/215566435/React-dragger-layout/blob/master/example/image/NormalLayoutDemo.gif)
-![](https://github.com/215566435/React-dragger-layout/blob/master/example/image/resizing.gif)
+![](https://github.com/215566435/React-dragger-layout/blob/master/example/image/dashboard.gif)
 
-# Demo地址
+# Demo地址 ✌️
 [Live Demo(预览地址)](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html)
 
-# 特点
+# 特点 
 
 - [x] 自动布局的网格系统
 - [x] 手机上也可以操作
 - [x] 高度自适应
-- [x] 静态组件([Live Demo(预览地址)](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html))
-- [x] 拖拽组件([Live Demo(预览地址)](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html))
+- [x] 静态组件
+- [x] 拖拽组件
 - [x] 自动缩放组件
 - [x] 自定义拖拽把手
+- [x] 自定义缩放把手
 
 
 
@@ -41,9 +41,10 @@ const fakeData = [
     { GridX: 0, GridY: 0, w: 4, h: 2, key: '2' }
 ]
 
-const blockStyle = {
-    background: 'grey',
-    height: '100%'
+const getblockStyle = (isDragging) => {
+    return {
+        background: isDragging ? '#1890ff' : 'white',
+    }
 };
 
 ReactDOM.render(
@@ -54,17 +55,27 @@ ReactDOM.render(
         rowHeight={40}//必填项
         margin={[5, 5]}//必填项
         className='plant-layout'//必填项
-        style={{ background: '#eee' }}//非必填项
+        style={{ background: '#333' }}//非必填项
         placeholder={true}//非必填项
     >
-        {(item, isDragging) => {
-            return <div style={blockStyle}>
-                {isDragging ? '正在抓取' : '停放'}
-            </div>
+        {(item, provided) => {
+            return (
+                <div
+                    {...provided.props}
+                    {...provided.dragHandle}
+                    style={{
+                        ...provided.props.style,
+                        ...getblockStyle(provided.isDragging)
+                    }}
+                >
+                    {provided.isDragging ? '正在抓取' : '停放'}
+                </div>
+            )
         }}
     </Dragact>,
     document.getElementById('root')
 );
+
 ```
 
 
@@ -95,18 +106,27 @@ ReactDOM.render(
 ```jsx
     <Dragact
         layout={fakeData}//必填项
-        ....
+        {...something}
     >
-        {(item, isDragging) => {
-            return <div style={blockStyle}>
-                {isDragging ? '正在抓取' : '停放'}
-            </div>
+        {(item, provided) => {
+            return (
+                <div
+                    {...provided.props}
+                    {...provided.dragHandle}
+                    style={{
+                        ...provided.props.style,
+                        ...getblockStyle(provided.isDragging)
+                    }}
+                >
+                    {provided.isDragging ? '正在抓取' : '停放'}
+                </div>
+            )
         }}
     </Dragact>,
 ```
-现在,我们子元素渲染变成一个小小的**构造函数**,第一个入参是您输入数据的每一项,第二个参数就是**isDragging**,状态监听参数。
+现在,我们子元素渲染变成一个小小的**构造函数**,第一个入参是您输入数据的每一项,第二个参数就是**provided**,提供了所有的拖拽属性
 
-这么做,轻易的实现了,组件漂亮,不用写map函数,不用写key,同时更容易监听每一个组件的拖拽状态**isDragging**.
+这么做,轻易的实现了,减少组件层级,组件漂亮,不用写map函数,不用写key,同时更容易监听每一个组件的拖拽状态**provided.isDragging**.
 
 更多的依赖注入思想以及好处,请看我的知乎问答:[知乎,方正的回答:如何设计一款组件库](https://www.zhihu.com/question/266745124/answer/322998960)
 
@@ -129,20 +149,47 @@ ReactDOM.render(
 通过获取dragact组件的实例,我提供了一个api ```getLayout():DragactLayout;```,用于获取当前的**布局信息**。
 
 
-### 4.拖拽把手的设计
-设计一个拖拽把手,必须要两个步骤。
-1. 挂件中拖拽把手拥有一个```id='dragact-handle'```的html tag(```<div id='dragact-handle'>我是把手</div>```);
-2. 在数据中标记是否存在把手
-```ts
-const layout = [
-    { GridX: 0, GridY: 0, w: 4, h: 2, key: '0',handle:true },
-    { GridX: 0, GridY: 0, w: 4, h: 2, key: '1' },
-    { GridX: 0, GridY: 0, w: 4, h: 2, key: '2' }
-]
+### 4.滑动中心
+经过不断的努力和尝试,现在所有的widget移动都是依赖重力中心去移动的。
+
+这意味着当我们拖动一个widget的时候更加得心应手和自然。
+
+
+>让我们举例说明,看看一款非常著名和出色的jQuery插件实是怎么做的
+
+![非常标准的做法](https://github.com/215566435/Dragact/blob/master/example/image/%E6%89%8B%E6%84%9F%E4%BC%98%E5%8C%96%E5%89%8D%60%60.gif)
+
+
+再看看```dragact```优化前是怎样的
+
+![非常长的一条块,已经拖动超出了屏幕很多才会交换方块](https://github.com/215566435/Dragact/blob/master/example/image/%E6%89%8B%E6%84%9F%E4%BC%98%E5%8C%96%E5%89%8D.gif)
+
+
+再看看优化以后的```dragact```是怎样的体验
+
+![当长方条的中心,超过下面方块的中心的时候,就会发生移动](https://github.com/215566435/Dragact/blob/master/example/image/%E6%89%8B%E6%84%9F%E4%BC%98%E5%8C%96%E5%90%8E%20.gif)
+
+
+这样的一种优化,带来的是拖动手感的差异,我们向下拖动物块的目的,很大程度上是因为想和下方的某一物块交换位置。
+
+通过这种趋势的判断和大量实验,```dragact```选择了重力中心为移动点,更自然,手感更顺滑.
+
+### 5.性能优异
+
+让我们用直观的动图来观看性能吧!
+
+![](https://github.com/215566435/Dragact/blob/master/example/image/v.17%E4%BC%98%E5%8C%96%E5%89%8D.gif)
+
+这是一条超过300行的大量数据,在优化前,我们可以看到,会有明显的卡顿。
+
+![](https://github.com/215566435/Dragact/blob/master/example/image/v.17%E4%BC%98%E5%8C%96%E5%90%8E.gif)
+
+用过react组件的优化后,依旧是一条超过300行的大量数据。
+
+可以看到组件插入速度的明显的变化。
+
 
-```
 
-这样的一个设计,略显繁杂,但是起码能够保证了把手的**自定义**,或许在下个版本中我将设计一款高皆组件,使得书写拖拽把手更加轻便简洁。
 
 
 
@@ -153,7 +200,7 @@ const layout = [
 数据属性指的是我们每一个组件所拥有的属性,类似以下的一组数据
 ```ts
 const layout = [
-    { GridX: 0, GridY: 0, w: 4, h: 2, key: '0',canResize:false,static:true,canDrag:false,handle:true },
+    { GridX: 0, GridY: 0, w: 4, h: 2, key: '0' },
     { GridX: 0, GridY: 0, w: 4, h: 2, key: '1' },
     { GridX: 0, GridY: 0, w: 4, h: 2, key: '2' }
 ]
@@ -163,17 +210,13 @@ GridY:number//必填,挂件布局中的纵坐标
 w:number//必填,挂件布局中宽度,整数
 h:number//必填,挂件布局中高度,整数
 key:number|string//必填,挂件在布局中的唯一id
-canResize:boolean //非必要,能否调整大小的开关
-static:boolean //非必要,静态组件的开关
-canDrag:boolean //非必要,是否能拖拽的开关
-handle:boolean //非必要,是否有拖拽把手的开关
 ```
 
 
 ### 组件属性
 ```ts
-interface DragactProps {
-    layout?: DragactLayout[] //暂时不推荐使用
+export interface DragactProps {
+    layout: DragactLayoutItem[]
     /** 
      * 宽度切分比 
      * 这个参数会把容器的宽度平均分为col等份
@@ -194,7 +237,7 @@ interface DragactProps {
      */
     padding?: number,
 
-    children: any[] | any
+    children: (Item: DragactLayoutItem, provided: GridItemProvided) => any,
 
 
     // 
@@ -220,7 +263,7 @@ interface DragactProps {
     /**
      * 拖动结束的回调
      */
-    onDragEnd?: (key: number | string) => void
+    onDragEnd?: (event: GridItemEvent) => void
 
     /**
      * 每个元素的margin,第一个参数是左右,第二个参数是上下
@@ -231,8 +274,13 @@ interface DragactProps {
      * layout的名字
     */
     className: number | string
-}
 
+    /**是否有placeholder */
+    placeholder?: Boolean
+
+    style?: React.CSSProperties
+
+}
 ```
 
 # Ref Api
@@ -269,11 +317,6 @@ npm run test
 如果你发现了本项目的Bug,请务必马上告诉我。添加一个issue,并且帮忙给出最最简单重现的例子,这能让我快速定位到Bug帮你解决,谢谢!
 
 
+# LICENSE
 
-
-# TODO-LIST
-- [ ] horizontal swaping
-- [x] resizing
-- [x] touch handle
-- [ ] responsive layout
-- [ ] SSR/server rendering 
+MIT

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
build/react-dragger-layout.js


+ 98 - 72
dist/AddRemove/index.js

@@ -1,72 +1,98 @@
-"use strict";
-// import *as React from 'react';
-// import { Dragact } from '../lib/dragact';
-// const 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' }
-// ]
-// const Card = (props: any) => {
-//     const item: any = props.item;
-//     const dataSet: any = props['data-set'];
-//     return (
-//         <div className='layout-Item' >
-//             <img src={item.img} style={{ width: '100%', height: '60%' }} draggable={false} alt='card'></img>
-//             <div style={{ padding: 5, textAlign: 'center', color: '#595959' }}>{dataSet.handle ? <div className='card-handle' id="dragact-handle">点我拖动</div> : item.content}</div>
-//         </div>
-//     )
-// }
-// export class AddRemove extends React.Component<{}, {}> {
-//     layoutWrap: HTMLDivElement | null
-//     dragactNode: Dragact;
-//     state = {
-//         layout: [1]
-//     }
-//     componentDidMount() {
-//         this.setState({
-//             layout: this.dragactNode.getLayout()
-//         })
-//     }
-//     handleClick = () => {
-//         this.setState({
-//             layout: [...this.state.layout, 1]
-//         })
-//         console.log(this.state.layout)
-//     }
-//     handleDeleteClick = () => {
-//         this.state.layout.shift()
-//         this.setState({
-//             layout: [...this.state.layout]
-//         })
-//     }
-//     render() {
-//         const margin: [number, number] = [5, 5];
-//         const dragactInit = {
-//             width: 800,
-//             col: 12,
-//             rowHeight: 800 / 12,
-//             margin: margin,
-//             className: 'normal-layout'
-//         }
-//         return (
-//             <div>
-//                 <div style={{ display: 'flex', justifyContent: 'center' }} >
-//                     <div>
-//                         <h1 style={{ textAlign: 'center' }}>AddRemove Demo</h1>
-//                         <Dragact {...dragactInit} ref={node => node ? this.dragactNode = node : null} >
-//                             {this.state.layout.map((el, i) => {
-//                                 return (
-//                                     <Card item={Words[0]} key={i} data-set={{ GridX: i * 3, GridY: 0, w: 3, h: 3 }} />
-//                                 )
-//                             })}
-//                         </Dragact>
-//                         <button onClick={this.handleClick}>新增</button>
-//                         <button onClick={this.handleDeleteClick}>删除</button>
-//                     </div>
-//                 </div>
-//             </div>
-//         )
-//     }
-// }
+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;
+};
+import * as React from 'react';
+import { Dragact } from '../lib/dragact';
+var Words = [
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' }
+];
+var Card = function (_a) {
+    var item = _a.item, provided = _a.provided, onDelete = _a.onDelete;
+    return (React.createElement("div", __assign({ className: 'layout-Item' }, provided.props, provided.dragHandle),
+        React.createElement("div", { style: {
+                position: 'absolute',
+                width: 10, height: 10, right: 15, top: 5, cursor: 'pointer'
+            }, onClick: function () { return onDelete(item.key); } }, "\u274C"),
+        React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } }, item.content)));
+};
+var fakeData = function () {
+    var Y = 0;
+    return Words.map(function (item, index) {
+        if (index % 4 === 0)
+            Y++;
+        return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index });
+    });
+};
+var makeOne = function () {
+    return { content: 'added', GridX: 0, GridY: 0, w: 4, h: 3, key: Date.now() };
+};
+var AddRemove = /** @class */ (function (_super) {
+    __extends(AddRemove, _super);
+    function AddRemove() {
+        var _this = _super !== null && _super.apply(this, arguments) || this;
+        _this.state = {
+            layout: fakeData()
+        };
+        _this.handleClick = function () {
+            _this.setState({
+                layout: _this.state.layout.concat([makeOne()])
+            });
+            console.log(_this.state.layout);
+        };
+        _this.hanldeOnDelete = function (key) {
+            var layout = _this.state.layout.filter(function (item) {
+                if (item.key !== key) {
+                    return item;
+                }
+            });
+            _this.setState({
+                layout: layout
+            });
+        };
+        return _this;
+    }
+    AddRemove.prototype.componentDidMount = function () {
+    };
+    AddRemove.prototype.render = function () {
+        var _this = this;
+        var margin = [5, 5];
+        var dragactInit = {
+            width: 600,
+            col: 12,
+            rowHeight: 800 / 12,
+            margin: margin,
+            className: 'normal-layout',
+            layout: this.state.layout,
+            placeholder: true
+        };
+        return (React.createElement("div", null,
+            React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
+                React.createElement("div", null,
+                    React.createElement("h1", { style: { textAlign: 'center' } }, "AddRemove Demo"),
+                    React.createElement("button", { onClick: this.handleClick }, "\u65B0\u589E"),
+                    React.createElement(Dragact, __assign({}, dragactInit), function (item, provided) {
+                        return React.createElement(Card, { item: item, provided: provided, onDelete: _this.hanldeOnDelete });
+                    })))));
+    };
+    return AddRemove;
+}(React.Component));
+export { AddRemove };

+ 15 - 8
dist/HandleLayout/index.js

@@ -17,12 +17,12 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     return t;
 };
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact } from '../../src/lib/dragact';
 import './index.css';
 var Words = [
     { content: 'You can do anything, but not everything.' },
     { content: 'Those who dare to fail miserably can achieve greatly.' },
-    { content: 'You miss 100 percent of the shots you never take.', handle: true },
+    { content: 'You miss 100 percent of the shots you never take.' },
     { content: 'Those who believe in telekinetics, raise my hand.' },
     { content: 'I’d rather live with a good question than a bad answer.' }
 ];
@@ -34,10 +34,17 @@ var fakeData = function () {
         return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 2, key: index + '' });
     });
 };
-var Card = function (props) {
-    var item = props.item;
-    return (React.createElement("div", { className: 'layout-Item' },
-        React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } }, item.handle ? React.createElement("div", { className: 'card-handle', id: "dragact-handle" }, "\u70B9\u6211\u62D6\u52A8") : item.content)));
+var Card = function (_a) {
+    var item = _a.item, provided = _a.provided;
+    var style = { padding: 5, textAlign: 'center', color: '#595959' };
+    if (item.key !== '3') {
+        return (React.createElement("div", __assign({ className: 'layout-Item' }, provided.props, provided.dragHandle),
+            React.createElement("div", { style: style }, item.content)));
+    }
+    return (React.createElement("div", __assign({ className: 'layout-Item' }, provided.props),
+        React.createElement("div", { style: style },
+            item.content,
+            React.createElement("div", __assign({ className: 'card-handle' }, provided.dragHandle), "\u70B9\u6211\u62D6\u52A8"))));
 };
 var HandleLayout = /** @class */ (function (_super) {
     __extends(HandleLayout, _super);
@@ -59,8 +66,8 @@ var HandleLayout = /** @class */ (function (_super) {
             React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
                 React.createElement("div", null,
                     React.createElement("h1", { style: { textAlign: 'center' } }, "\u62D6\u62FD\u628A\u624B Demo"),
-                    React.createElement(Dragact, __assign({}, dragactInit), function (item, isDragging) {
-                        return React.createElement(Card, { item: item });
+                    React.createElement(Dragact, __assign({}, dragactInit), function (item, provided) {
+                        return React.createElement(Card, { item: item, provided: provided });
                     })))));
     };
     return HandleLayout;

+ 4 - 8
dist/LayoutRestore/index.js

@@ -17,7 +17,8 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     return t;
 };
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact } from '../../src/lib/dragact';
+import { Card } from '../NormalLayout/index';
 import './index.css';
 var Words = [
     { content: 'You can do anything, but not everything.' },
@@ -34,11 +35,6 @@ var fakeData = function () {
         return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 2, key: index + '' });
     });
 };
-var Card = function (props) {
-    var item = props.item;
-    return (React.createElement("div", { className: 'layout-Item' },
-        React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } }, item.content)));
-};
 var storeLayout = void 666;
 var LayoutRestore = /** @class */ (function (_super) {
     __extends(LayoutRestore, _super);
@@ -60,8 +56,8 @@ var LayoutRestore = /** @class */ (function (_super) {
                 layout: storeLayout ? storeLayout : fakeData(),
                 placeholder: true
             };
-            return (React.createElement(Dragact, __assign({}, dragactInit, { ref: function (node) { return node ? _this.dragactNode = node : null; }, onDragEnd: _this.handleOnDragEnd }), function (item) {
-                return React.createElement(Card, { item: item });
+            return (React.createElement(Dragact, __assign({}, dragactInit, { ref: function (node) { return node ? _this.dragactNode = node : null; }, onDragEnd: _this.handleOnDragEnd }), function (item, provided) {
+                return React.createElement(Card, { item: item, provided: provided });
             }));
         };
         return _this;

+ 13 - 8
dist/NormalLayout/index.js

@@ -17,7 +17,7 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     return t;
 };
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact } from '../../src/lib/dragact';
 import { Words } from './largedata';
 import './index.css';
 var fakeData = function () {
@@ -28,14 +28,19 @@ var fakeData = function () {
         return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '' });
     });
 };
-var Card = function (props) {
-    var item = props.item;
-    var isDragging = props.isDragging;
-    return (React.createElement("div", { className: 'layout-Item', style: { background: "" + (isDragging ? '#eaff8f' : 'white') } },
+export var Card = function (_a) {
+    var item = _a.item, provided = _a.provided;
+    return (React.createElement("div", __assign({ className: 'layout-Item' }, provided.props, provided.dragHandle, { style: __assign({}, provided.props.style, { background: "" + (provided.isDragging ? '#eaff8f' : 'white') }) }),
         React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } },
             React.createElement("span", null, "title"),
             React.createElement("div", { style: { borderBottom: '1px solid rgba(120,120,120,0.1)' } }),
-            item.content)));
+            item.content),
+        React.createElement("span", __assign({}, provided.resizeHandle, { style: {
+                position: 'absolute',
+                width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+                borderRight: '2px solid rgba(15,15,15,0.2)',
+                borderBottom: '2px solid rgba(15,15,15,0.2)'
+            } }))));
 };
 var LayoutDemo = /** @class */ (function (_super) {
     __extends(LayoutDemo, _super);
@@ -60,8 +65,8 @@ var LayoutDemo = /** @class */ (function (_super) {
                 React.createElement("h1", { style: { textAlign: 'center' } }, "\u666E\u901A\u5E03\u5C40demo"),
                 React.createElement(Dragact, __assign({}, dragactInit, { placeholder: true, style: {
                         background: '#003A8C'
-                    } }), function (item, isDragging) {
-                    return React.createElement(Card, { item: item, isDragging: isDragging });
+                    } }), function (item, provided) {
+                    return React.createElement(Card, { item: item, provided: provided });
                 }))));
     };
     return LayoutDemo;

+ 7 - 7
dist/StaticWidget/index.js

@@ -7,7 +7,7 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     return t;
 };
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact } from '../../src/lib/dragact';
 import './index.css';
 var Words = [
     { content: 'Sorry I just can not move in any circumstances', static: true },
@@ -24,16 +24,16 @@ var fakeData = function () {
         return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 4, key: index + '', canResize: false });
     });
 };
-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("div", { style: { paddingLeft: 12, color: '#595959' } }, item.content)));
+var Cell = function (_a) {
+    var item = _a.item, provided = _a.provided;
+    return (React.createElement("div", __assign({}, provided.props, provided.dragHandle, { className: "layout-Cell " + (item.static ? "static" : ""), style: __assign({}, provided.props.style, { background: item.static ? "#e8e8e8" : "" }) }),
+        React.createElement("div", { style: { padding: 10, color: '#595959' } }, item.content)));
 };
 export var SortedTableWithStatic = function () {
     return (React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } },
         React.createElement("div", null,
             React.createElement("h1", { style: { textAlign: 'center' } }, "\u9759\u6001\u7EC4\u4EF6 Demo"),
-            React.createElement(Dragact, { width: 600, col: 16, rowHeight: 30, margin: [2, 2], className: 'normal-layout', layout: fakeData(), placeholder: true }, function (item, isDragging) {
-                return React.createElement(Cell, { item: item });
+            React.createElement(Dragact, { width: 600, col: 16, rowHeight: 30, margin: [2, 2], className: 'normal-layout', layout: fakeData(), placeholder: true }, function (item, provided) {
+                return React.createElement(Cell, { item: item, provided: provided });
             }))));
 };

+ 57 - 3
dist/index.js

@@ -14,16 +14,17 @@ import { LayoutDemo } from './NormalLayout/index';
 import { SortedTableWithStatic } from "./StaticWidget/index";
 import { LayoutRestore } from "./LayoutRestore/index";
 import { HandleLayout } from "./HandleLayout/index";
-// import { AddRemove } from "./AddRemove/index";
+import { AddRemove } from "./AddRemove/index";
 import { Mobile } from "./mobileLayout/index";
 import './index.css';
+// import { Dragact } from "./lib/dragact";
 var DemoMap = {
     normalLayout: React.createElement(LayoutDemo, null),
     // SortedTable: <SortedTable />,
     StaticHeader: React.createElement(SortedTableWithStatic, null),
     LayoutRestore: React.createElement(LayoutRestore, null),
     HandleLayout: React.createElement(HandleLayout, null),
-    // AddRemove: <AddRemove />,
+    AddRemove: React.createElement(AddRemove, null),
     Mobile: React.createElement(Mobile, null)
 };
 var DemoDispatcher = /** @class */ (function (_super) {
@@ -43,17 +44,70 @@ var DemoDispatcher = /** @class */ (function (_super) {
     DemoDispatcher.prototype.render = function () {
         var _this = this;
         return (React.createElement("div", null,
+            React.createElement("iframe", { src: "https://ghbtns.com/github-btn.html?user=215566435&repo=Dragact&type=star&count=true&size=large", frameBorder: '0', scrolling: "0", width: "160px", height: "30px" }),
+            React.createElement("iframe", { src: "https://ghbtns.com/github-btn.html?user=215566435&repo=Dragact&type=fork&count=true&size=large", frameBorder: "0", scrolling: "0", width: "158px", height: "30px" }),
             React.createElement("div", null, "\u5207\u6362 Demos"),
             React.createElement("div", { className: 'demo-button-layout' },
                 React.createElement("button", { onClick: function () { return _this.handleLayoutChange('normalLayout'); } }, "\u666E\u901A\u5E03\u5C40"),
                 React.createElement("button", { onClick: function () { return _this.handleLayoutChange('StaticHeader'); } }, "\u9759\u6001\u7EC4\u4EF6"),
                 React.createElement("button", { onClick: function () { return _this.handleLayoutChange('LayoutRestore'); } }, "\u5B58\u50A8\u5E03\u5C40"),
                 React.createElement("button", { onClick: function () { return _this.handleLayoutChange('HandleLayout'); } }, "\u62D6\u62FD\u628A\u624B"),
+                React.createElement("button", { onClick: function () { return _this.handleLayoutChange('AddRemove'); } }, "\u589E\u52A0\u548C\u5220\u9664"),
                 React.createElement("button", { onClick: function () { return _this.handleLayoutChange('Mobile'); } }, "\u79FB\u52A8\u7AEF")),
             this.state.demo));
     };
     return DemoDispatcher;
 }(React.Component));
-React.createElement(DemoDispatcher, null);
+{ }
+//<Dragact/> */}
+// const fakeData = [
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '0' },
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '1' },
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '2' }
+// ]
+// const getblockStyle = (isDragging: Boolean) => {
+//     return {
+//         background: isDragging ? '#1890ff' : 'white',
+//     }
+// };
+// const Handle = ({ provided }: any) => {
+//     return (
+//         <div
+//             {...provided.dragHandle}
+//             style={{
+//                 ...getblockStyle(provided.isDragging),
+//                 borderBottom: '1px solid rgba(120,120,120,0.3)',
+//                 textAlign: 'center'
+//             }}
+//         >
+//             点击拖拽
+//         </div>
+//     )
+// }
+// ReactDOM.render(
+//     <Dragact
+//         layout={fakeData}//必填项
+//         col={16}//必填项
+//         width={800}//必填项
+//         rowHeight={40}//必填项
+//         margin={[5, 5]}//必填项
+//         className='plant-layout'//必填项
+//         style={{ background: '#333' }}//非必填项
+//         placeholder={true}//非必填项
+//     >
+//         {(item: any, provided: any) => {
+//             return (
+//                 <div
+//                     {...provided.props}
+//                     style={{ ...provided.props.style, background: 'white' }}
+//                 >
+//                     <Handle provided={provided} />
+//                     {provided.isDragging ? '正在抓取' : '停放'}
+//                 </div>
+//             )
+//         }}
+//     </Dragact>,
+//     document.getElementById('root')
+// );
 ReactDOM.render(React.createElement(DemoDispatcher, null), document.getElementById('root'));
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

+ 3 - 3
dist/lib/GridItem.js

@@ -114,7 +114,7 @@ var GridItem = /** @class */ (function (_super) {
             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 + ''
+            event: null, GridX: GridX, GridY: GridY, w: w, h: h, UniqueKey: UniqueKey + ''
         });
     };
     GridItem.prototype.onDrag = function (event, x, y) {
@@ -133,11 +133,11 @@ var GridItem = /** @class */ (function (_super) {
             this.props.onDragEnd({ GridX: GridX, GridY: GridY, w: w, h: h, UniqueKey: UniqueKey + '', event: event });
     };
     GridItem.prototype.render = function () {
+        var _this = this;
         var _a = this.props, w = _a.w, h = _a.h, style = _a.style, bounds = _a.bounds, GridX = _a.GridX, GridY = _a.GridY, handle = _a.handle, canDrag = _a.canDrag, canResize = _a.canResize;
         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(Dragger, { style: __assign({}, style, { width: wPx, height: hPx, position: 'absolute', transition: this.props.isUserMove ? '' : 'all .2s ease-out', zIndex: this.props.isUserMove ? (this.props.dragType === 'drag' ? 10 : 2) : 2 }), onDragStart: this.onDragStart, onMove: this.onDrag, onDragEnd: this.onDragEnd, onResizeStart: this.onResizeStart, onResizing: this.onResizing, onResizeEnd: this.onResizeEnd, x: x, y: y, w: wPx, h: hPx, isUserMove: this.props.isUserMove, bounds: bounds, handle: handle, canDrag: canDrag, canResize: canResize },
-            React.createElement("div", { style: { height: '100%', width: "100%" } }, React.Children.map(this.props.children, function (child) { return child; }))));
+        return (React.createElement(Dragger, { style: __assign({}, style, { width: wPx, height: hPx, position: 'absolute', transition: this.props.isUserMove ? '' : 'all .2s ease-out', zIndex: this.props.isUserMove ? (this.props.dragType === 'drag' ? 10 : 2) : 2 }), onDragStart: this.onDragStart, onMove: this.onDrag, onDragEnd: this.onDragEnd, onResizeStart: this.onResizeStart, onResizing: this.onResizing, onResizeEnd: this.onResizeEnd, x: x, y: y, w: wPx, h: hPx, isUserMove: this.props.isUserMove, bounds: bounds, handle: handle, canDrag: canDrag, canResize: canResize }, function (provided, draggerProps, resizerProps) { return _this.props.children(provided, draggerProps, resizerProps); }));
     };
     GridItem.defaultProps = {
         col: 12,

+ 24 - 20
dist/lib/dragact.js

@@ -46,7 +46,7 @@ var Dragact = /** @class */ (function (_super) {
             }
         };
         _this.onResizing = function (layoutItem) {
-            var newLayout = layoutCheck(_this.state.layout, layoutItem, layoutItem.UniqueKey, layoutItem.UniqueKey, 0);
+            var newLayout = layoutCheck(_this.state.layout, layoutItem, layoutItem.UniqueKey + '', layoutItem.UniqueKey + '', 0);
             var _a = compactLayout(newLayout, layoutItem, _this.state.mapLayout), compacted = _a.compacted, mapLayout = _a.mapLayout;
             _this.setState({
                 layout: compacted,
@@ -87,7 +87,6 @@ var Dragact = /** @class */ (function (_super) {
     Dragact.prototype.onDragStart = function (bundles) {
         var GridX = bundles.GridX, GridY = bundles.GridY, w = bundles.w, h = bundles.h;
         if (this.state.mapLayout) {
-            var newlayout = syncLayout(this.state.mapLayout, bundles);
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -95,7 +94,7 @@ var Dragact = /** @class */ (function (_super) {
                 hMoving: h,
                 placeholderShow: true,
                 placeholderMoving: true,
-                mapLayout: newlayout,
+                mapLayout: syncLayout(this.state.mapLayout, bundles),
                 dragType: 'drag'
             });
         }
@@ -104,7 +103,7 @@ var Dragact = /** @class */ (function (_super) {
     Dragact.prototype.onDrag = function (layoutItem) {
         var GridY = layoutItem.GridY, UniqueKey = layoutItem.UniqueKey;
         var moving = GridY - this.state.GridYMoving;
-        var newLayout = layoutCheck(this.state.layout, layoutItem, UniqueKey, UniqueKey /*用户移动方块的key */, moving);
+        var newLayout = layoutCheck(this.state.layout, layoutItem, UniqueKey + '', UniqueKey + '' /*用户移动方块的key */, moving);
         var _a = compactLayout(newLayout, layoutItem, this.state.mapLayout), compacted = _a.compacted, mapLayout = _a.mapLayout;
         this.setState({
             GridXMoving: layoutItem.GridX,
@@ -134,18 +133,18 @@ var Dragact = /** @class */ (function (_super) {
             return null;
         if (!padding)
             padding = 0;
-        return (React.createElement(GridItem, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: GridXMoving, GridY: GridYMoving, w: wMoving, h: hMoving, style: { background: 'rgba(15,15,15,0.3)', zIndex: dragType === 'drag' ? 1 : 10, transition: ' all .15s ease-out' }, isUserMove: !placeholderMoving, dragType: dragType, canDrag: false, canResize: false }));
+        return (React.createElement(GridItem, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: GridXMoving, GridY: GridYMoving, w: wMoving, h: hMoving, style: { background: 'rgba(15,15,15,0.3)', zIndex: dragType === 'drag' ? 1 : 10, transition: ' all .15s ease-out' }, isUserMove: !placeholderMoving, dragType: dragType, canDrag: false, canResize: false }, function (p, resizerProps) { return React.createElement("div", __assign({}, p)); }));
     };
     Dragact.prototype.componentWillReceiveProps = function (nextProps) {
-        if (this.props.children.length > nextProps.children.length) {
+        if (this.props.layout.length > nextProps.layout.length) {
             var mapLayoutCopy_1 = __assign({}, this.state.mapLayout);
-            nextProps.children.forEach(function (child) {
-                if (mapLayoutCopy_1[child.key] !== void 666)
-                    delete mapLayoutCopy_1[child.key];
+            nextProps.layout.forEach(function (child) {
+                if (mapLayoutCopy_1[child.key + ''] !== void 666)
+                    delete mapLayoutCopy_1[child.key + ''];
             });
             var _loop_1 = function (key) {
                 var newLayout_1 = this_1.state.layout.filter(function (child) {
-                    if (child.key !== key)
+                    if (child.key + '' !== key + '')
                         return child;
                 });
                 var _a = compactLayout(newLayout_1, undefined, this_1.state.mapLayout), compacted = _a.compacted, mapLayout = _a.mapLayout;
@@ -160,22 +159,21 @@ var Dragact = /** @class */ (function (_super) {
                 _loop_1(key);
             }
         }
-        if (this.props.children.length < nextProps.children.length) {
+        if (this.props.layout.length < nextProps.layout.length) {
             var item;
-            for (var idx in nextProps.children) {
-                var i = nextProps.children[idx];
-                if (this.state.mapLayout && !this.state.mapLayout[i.key]) {
+            for (var idx in nextProps.layout) {
+                var i = nextProps.layout[idx];
+                if (this.state.mapLayout && !this.state.mapLayout[i.key + '']) {
                     item = i;
                     break;
                 }
             }
             if (item !== void 666) {
-                var dataSet = __assign({}, item.props['data-set'], { isUserMove: false, key: item.key });
+                var dataSet = __assign({}, item, { isUserMove: false, key: item.key + '' });
                 var newLayout = this.state.layout.concat([dataSet]);
-                newLayout = correctLayout(newLayout, this.props.col);
                 var _a = compactLayout(newLayout, undefined, this.state.mapLayout), compacted = _a.compacted, mapLayout = _a.mapLayout;
                 this.setState({
-                    containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight),
+                    containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight, false),
                     layout: compacted,
                     mapLayout: mapLayout
                 });
@@ -190,18 +188,24 @@ var Dragact = /** @class */ (function (_super) {
             _this.setState({
                 layout: compacted,
                 mapLayout: mapLayout,
-                containerHeight: getMaxContainerHeight(compacted, _this.props.rowHeight, _this.props.margin[1], _this.state.containerHeight)
+                containerHeight: getMaxContainerHeight(compacted, _this.props.rowHeight, _this.props.margin[1], _this.state.containerHeight, false)
             });
         }, 1);
     };
     Dragact.prototype.getGridItem = function (child, index) {
+        var _this = this;
         var _a = this.state, dragType = _a.dragType, mapLayout = _a.mapLayout;
         var _b = this.props, col = _b.col, width = _b.width, padding = _b.padding, rowHeight = _b.rowHeight, margin = _b.margin;
         if (mapLayout) {
-            var renderItem = layoutItemForkey(mapLayout, child.key);
+            var renderItem_1 = layoutItemForkey(mapLayout, child.key + '');
             if (!padding)
                 padding = 0;
-            return (React.createElement(GridItem, __assign({}, renderItem, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, onDrag: this.onDrag, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, isUserMove: renderItem.isUserMove !== void 666 ? renderItem.isUserMove : false, UniqueKey: child.key, onResizing: this.onResizing, onResizeStart: this.onResizeStart, onResizeEnd: this.onResizeEnd, dragType: dragType, key: child.key }), this.props.children(child, renderItem.isUserMove)));
+            return (React.createElement(GridItem, __assign({}, renderItem_1, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, onDrag: this.onDrag, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, isUserMove: renderItem_1.isUserMove !== void 666 ? renderItem_1.isUserMove : false, UniqueKey: child.key, onResizing: this.onResizing, onResizeStart: this.onResizeStart, onResizeEnd: this.onResizeEnd, dragType: dragType, key: child.key }), function (GridItemProvided, dragHandle, resizeHandle) { return _this.props.children(child, {
+                isDragging: renderItem_1.isUserMove !== void 666 ? renderItem_1.isUserMove : false,
+                props: GridItemProvided,
+                dragHandle: dragHandle,
+                resizeHandle: resizeHandle
+            }); }));
         }
     };
     Dragact.prototype.render = function () {

+ 39 - 31
dist/lib/dragger/index.js

@@ -105,7 +105,7 @@ var Dragger = /** @class */ (function (_super) {
              * 调整手感
              * 无论是向上移动还是向下移动,全部都是根据重力中心
              * */
-            var height = _this.refs['dragger'].getClientRects()[0].height;
+            var height = _this.Ref.getClientRects()[0].height;
             var upNdown = _this.state.y - deltaY;
             var fixY = deltaY + (upNdown >= 0 ? 0 : height / 2);
             /**移动时回调,用于外部控制 */
@@ -119,10 +119,7 @@ var Dragger = /** @class */ (function (_super) {
         _this.onDragStart = function (event) {
             /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
             doc.body.style.userSelect = 'none';
-            if (_this.props.handle) {
-                if (event.target.id !== 'dragact-handle')
-                    return;
-            }
+            // if (event.target.id !== 'dragact-handle') return
             /**
              * 把监听事件的回掉函数,绑定在document上
              * 当设置边界的时候,用户鼠标会离开元素的范围
@@ -233,22 +230,16 @@ var Dragger = /** @class */ (function (_super) {
             _this.props.onResizeEnd && _this.props.onResizeEnd(event, _this.state.w, _this.state.h);
         };
         _this.mixin = function () {
-            var dragMix = {};
-            if (_this.props.canDrag === void 666 || _this.props.canDrag === true) {
-                dragMix = {
-                    onMouseDown: _this.onDragStart,
-                    onTouchStart: _this.onDragStart,
-                    onTouchEnd: _this.onDragEnd,
-                    onMouseUp: _this.onDragEnd
-                };
-            }
-            var resizeMix = {};
-            if (_this.props.canResize === void 666 || _this.props.canDrag === true) {
-                resizeMix = {
-                    onMouseDown: _this.onResizeStart,
-                    onMouseUp: _this.onResizeEnd
-                };
-            }
+            var dragMix = {
+                onMouseDown: _this.onDragStart,
+                onTouchStart: _this.onDragStart,
+                onTouchEnd: _this.onDragEnd,
+                onMouseUp: _this.onDragEnd
+            };
+            var resizeMix = {
+                onMouseDown: _this.onResizeStart,
+                onMouseUp: _this.onResizeEnd
+            };
             return {
                 dragMix: dragMix, resizeMix: resizeMix
             };
@@ -294,6 +285,7 @@ var Dragger = /** @class */ (function (_super) {
         }
     };
     Dragger.prototype.render = function () {
+        var _this = this;
         var _a = this.state, x = _a.x, y = _a.y, w = _a.w, h = _a.h;
         var _b = this.props, style = _b.style, className = _b.className, canResize = _b.canResize;
         if (!this.props.isUserMove) {
@@ -312,16 +304,15 @@ var Dragger = /** @class */ (function (_super) {
         }
         var _c = this.mixin(), dragMix = _c.dragMix, resizeMix = _c.resizeMix;
         /**主要是为了让用户定义自己的className去修改css */
-        var fixedClassName = typeof className === 'undefined' ? '' : className + ' ';
-        return (React.createElement("div", __assign({ className: fixedClassName + "WrapDragger", ref: 'dragger', style: __assign({}, style, { touchAction: 'none!important', transform: "translate(" + x + "px," + y + "px)", width: w, height: h }) }, dragMix),
-            React.Children.only(this.props.children),
-            canResize !== false ?
-                React.createElement("span", __assign({}, resizeMix, { style: {
-                        position: 'absolute',
-                        width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
-                        borderRight: '2px solid rgba(15,15,15,0.2)',
-                        borderBottom: '2px solid rgba(15,15,15,0.2)'
-                    } })) : null));
+        // const fixedClassName = typeof className === 'undefined' ? '' : className + ' '
+        resizeMix;
+        canResize;
+        className;
+        var provided = {
+            style: __assign({}, style, { touchAction: 'none!important', transform: "translate(" + x + "px," + y + "px)", width: w, height: h }),
+            ref: function (node) { return _this.Ref = node; }
+        };
+        return this.props.children(provided, dragMix, resizeMix);
     };
     /**
      * 初始变量设置
@@ -334,3 +325,20 @@ var Dragger = /** @class */ (function (_super) {
     return Dragger;
 }(React.Component));
 export { Dragger };
+// return (
+//     <div className={`${fixedClassName}WrapDragger`}
+//         ref={'dragger'}
+//     >
+//         {this.props.children(provided)}
+//         {canResize !== false ?
+//             <span
+//                 {...resizeMix}
+//                 style={{
+//                     position: 'absolute',
+//                     width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+//                     borderRight: '2px solid rgba(15,15,15,0.2)',
+//                     borderBottom: '2px solid rgba(15,15,15,0.2)'
+//                 }}
+//             /> : null}
+//     </div>
+// )

+ 1 - 1
dist/lib/util/compact.js

@@ -16,7 +16,7 @@ import { getFirstCollison } from "./collison";
 export var compactItem = function (finishedLayout, item) {
     if (item.static)
         return item;
-    var newItem = __assign({}, item);
+    var newItem = __assign({}, item, { key: item.key + '' });
     if (finishedLayout.length === 0) {
         return __assign({}, newItem, { GridY: 0 });
     }

+ 1 - 1
dist/lib/util/correction.js

@@ -24,7 +24,7 @@ export var correctLayout = function (layout, col) {
         correctItem(copy[i], col);
         correctItem(copy[i + 1], col);
         if (collision(copy[i], copy[i + 1])) {
-            copy = layoutCheck(copy, copy[i], copy[i].UniqueKey, copy[i].UniqueKey, 0);
+            copy = layoutCheck(copy, copy[i], copy[i].UniqueKey + '', copy[i].UniqueKey + '', 0);
         }
     }
     return copy;

+ 9 - 7
dist/lib/util/sort.js

@@ -18,16 +18,18 @@ export var sortLayout = function (layout) {
  * 这个函数带有记忆功能
  */
 export var getMaxContainerHeight = function () {
-    var lastOneGridY = 0;
-    return function (layout, elementHeight, elementMarginBottom, currentHeight) {
+    var lastOneYNH = 0;
+    return function (layout, elementHeight, elementMarginBottom, currentHeight, useCache) {
         if (elementHeight === void 0) { elementHeight = 30; }
         if (elementMarginBottom === void 0) { elementMarginBottom = 10; }
-        var length = layout.length;
-        var currentLastOne = layout[length - 1];
-        if (currentLastOne.GridY === lastOneGridY) {
-            return currentHeight;
+        if (useCache !== false) {
+            var length_1 = layout.length;
+            var currentLastOne = layout[length_1 - 1];
+            if (currentLastOne.GridY + currentLastOne.h === lastOneYNH) {
+                return currentHeight;
+            }
+            lastOneYNH = currentLastOne.GridY + currentLastOne.h;
         }
-        lastOneGridY = currentLastOne.GridY;
         var ar = layout.map(function (item) {
             return item.GridY + item.h;
         });

+ 7 - 8
dist/mobileLayout/index.js

@@ -17,7 +17,7 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     return t;
 };
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact } from '../../src/lib/dragact';
 import { Words } from './largedata';
 import './index.css';
 var fakeData = function () {
@@ -25,13 +25,12 @@ var fakeData = function () {
     return Words.map(function (item, index) {
         if (index % 4 === 0)
             Y++;
-        return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '', canResize: false });
+        return __assign({}, item, { GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '' });
     });
 };
-var Card = function (props) {
-    var item = props.item;
-    var isDragging = props.isDragging;
-    return (React.createElement("div", { className: 'layout-Item', style: { background: "" + (isDragging ? '#eaff8f' : 'white') } },
+var Card = function (_a) {
+    var item = _a.item, provided = _a.provided;
+    return (React.createElement("div", __assign({ className: 'layout-Item' }, provided.props, provided.dragHandle, { style: __assign({}, provided.props.style, { background: "" + (provided.isDragging ? '#eaff8f' : 'white') }) }),
         React.createElement("div", { style: { padding: 5, textAlign: 'center', color: '#595959' } },
             React.createElement("span", null, "title"),
             React.createElement("div", { style: { borderBottom: '1px solid rgba(120,120,120,0.1)' } }),
@@ -60,8 +59,8 @@ var Mobile = /** @class */ (function (_super) {
                 React.createElement("h1", { style: { textAlign: 'center' } }, "\u624B\u673A\u666E\u901A\u5E03\u5C40demo"),
                 React.createElement(Dragact, __assign({}, dragactInit, { placeholder: true, style: {
                         background: '#003A8C'
-                    } }), function (item, isDragging) {
-                    return React.createElement(Card, { item: item, isDragging: isDragging });
+                    } }), function (item, provided) {
+                    return React.createElement(Card, { item: item, provided: provided });
                 }))));
     };
     return Mobile;

+ 26 - 0
dist/showdown/index.js

@@ -0,0 +1,26 @@
+var showdown = require('showdown');
+var hljs = require('highlightjs');
+var decodeHtml = require("html-encoder-decoder").decode;
+function showdownHighlight() {
+    return [{
+            type: "output",
+            filter: function filter(text, converter, options) {
+                var left = "<pre><code\\b[^>]*>", right = "</code></pre>", flags = "g", replacement = function replacement(wholeMatch, match, left, right) {
+                    match = decodeHtml(match);
+                    var lang = (left.match(/class=\"([^ \"]+)/) || [])[1];
+                    console.log(left + hljs.highlight(lang, match).value + right);
+                    if (lang) {
+                        return left + hljs.highlight(lang, match).value + right;
+                    }
+                    else {
+                        return left + hljs.highlightAuto(match).value + right;
+                    }
+                };
+                return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
+            }
+        }];
+}
+;
+export var convertor = new showdown.Converter({
+    extensions: [showdownHighlight]
+});

+ 7 - 0
example/changelog.md

@@ -1,6 +1,13 @@
+v0.2.0
+- 版本跳跃
+- 添加增加add/remove
+
 v0.1.7
 - 优化性能-使用reselect的原理
 - 拖拽手感优化
+- 优化dom的层级
+- 自定义拖拽把手和resize把手
+- 拓展了child的渲染方式
 
 v0.1.6
 - 修正zIndex的错误

BIN
example/image/dashboard.gif


BIN
example/image/手感优化前``.gif


+ 108 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "dragact",
-  "version": "0.1.6",
+  "version": "0.1.7",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -4305,6 +4305,11 @@
         "sntp": "2.1.0"
       }
     },
+    "highlightjs": {
+      "version": "9.10.0",
+      "resolved": "https://registry.npmjs.org/highlightjs/-/highlightjs-9.10.0.tgz",
+      "integrity": "sha1-/Km3jdqjsavKidbD7hBa0nCoAZA="
+    },
     "hmac-drbg": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -8290,6 +8295,108 @@
       "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
       "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
     },
+    "showdown": {
+      "version": "1.8.6",
+      "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.8.6.tgz",
+      "integrity": "sha1-kepO47elRIqspoIKTifmkMatdxw=",
+      "requires": {
+        "yargs": "10.1.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+        },
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+        },
+        "cliui": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
+          "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+          "requires": {
+            "string-width": "2.1.1",
+            "strip-ansi": "4.0.0",
+            "wrap-ansi": "2.1.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "requires": {
+            "locate-path": "2.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+        },
+        "os-locale": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+          "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+          "requires": {
+            "execa": "0.7.0",
+            "lcid": "1.0.0",
+            "mem": "1.1.0"
+          }
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "which-module": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+          "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+        },
+        "yargs": {
+          "version": "10.1.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz",
+          "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==",
+          "requires": {
+            "cliui": "4.0.0",
+            "decamelize": "1.2.0",
+            "find-up": "2.1.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "2.1.0",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "2.1.1",
+            "which-module": "2.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "8.1.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz",
+          "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==",
+          "requires": {
+            "camelcase": "4.1.0"
+          }
+        }
+      }
+    },
     "signal-exit": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",

+ 4 - 2
package.json

@@ -1,7 +1,7 @@
 {
   "name": "dragact",
-  "version": "0.1.6",
-  "description": "",
+  "version": "0.1.8",
+  "description": "A powerful draggable layout system",
   "main": "index.js",
   "scripts": {
     "temp": "NODE_ENV=production webpack -p --config webpack.pro.config.js ",
@@ -56,12 +56,14 @@
     "babel-plugin-transform-object-rest-spread": "^6.26.0",
     "babel-plugin-transform-react-jsx": "^6.24.1",
     "babel-plugin-transform-runtime": "^6.23.0",
+    "highlightjs": "^9.10.0",
     "jest": "^22.3.0",
     "power-assert": "^1.4.4",
     "prop-types": "^15.5.10",
     "react": "^16.3.0-alpha.1",
     "react-dom": "^16.3.0-alpha.1",
     "reselect": "^3.0.1",
+    "showdown": "^1.8.6",
     "typescript-babel-jest": "^1.0.5"
   }
 }

+ 92 - 71
src/AddRemove/index.tsx

@@ -1,78 +1,99 @@
-// import *as React from 'react';
-// import { Dragact } from '../lib/dragact';
+import *as React from 'react';
+import { Dragact } from '../lib/dragact';
 
-// const 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' }
-// ]
+const Words = [
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' }
+]
 
 
-// const Card = (props: any) => {
-//     const item: any = props.item;
-//     const dataSet: any = props['data-set'];
-//     return (
-//         <div className='layout-Item' >
-//             <img src={item.img} style={{ width: '100%', height: '60%' }} draggable={false} alt='card'></img>
-//             <div style={{ padding: 5, textAlign: 'center', color: '#595959' }}>{dataSet.handle ? <div className='card-handle' id="dragact-handle">点我拖动</div> : item.content}</div>
-//         </div>
-//     )
-// }
+const Card = ({ item, provided, onDelete }: any) => {
+    return (
+        <div
+            className='layout-Item'
+            {...provided.props}
+            {...provided.dragHandle}
+        >
+            <div
+                style={{
+                    position: 'absolute',
+                    width: 10, height: 10, right: 15, top: 5, cursor: 'pointer'
+                }}
+                onClick={() => onDelete(item.key)}
+            >❌</div>
+            <div style={{ padding: 5, textAlign: 'center', color: '#595959' }}>{item.content}</div>
+        </div>
+    )
+}
 
+const fakeData = () => {
+    var Y = 0;
+    return Words.map((item, index) => {
+        if (index % 4 === 0) Y++;
 
-// export class AddRemove extends React.Component<{}, {}> {
-//     layoutWrap: HTMLDivElement | null
-//     dragactNode: Dragact;
-//     state = {
-//         layout: [1]
-//     }
+        return { ...item, GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index }
+    })
+}
 
-//     componentDidMount() {
-//         this.setState({
-//             layout: this.dragactNode.getLayout()
-//         })
-//     }
-//     handleClick = () => {
-//         this.setState({
-//             layout: [...this.state.layout, 1]
-//         })
-//         console.log(this.state.layout)
-//     }
-//     handleDeleteClick = () => {
-//         this.state.layout.shift()
-//         this.setState({
-//             layout: [...this.state.layout]
-//         })
-//     }
+const makeOne = () => {
+    return { content: 'added', GridX: 0, GridY: 0, w: 4, h: 3, key: Date.now() }
+}
 
-//     render() {
-//         const margin: [number, number] = [5, 5];
-//         const dragactInit = {
-//             width: 800,
-//             col: 12,
-//             rowHeight: 800 / 12,
-//             margin: margin,
-//             className: 'normal-layout'
-//         }
-//         return (
-//             <div>
-//                 <div style={{ display: 'flex', justifyContent: 'center' }} >
-//                     <div>
-//                         <h1 style={{ textAlign: 'center' }}>AddRemove Demo</h1>
-//                         <Dragact {...dragactInit} ref={node => node ? this.dragactNode = node : null} >
-//                             {this.state.layout.map((el, i) => {
-//                                 return (
-//                                     <Card item={Words[0]} key={i} data-set={{ GridX: i * 3, GridY: 0, w: 3, h: 3 }} />
-//                                 )
-//                             })}
-//                         </Dragact>
-//                         <button onClick={this.handleClick}>新增</button>
-//                         <button onClick={this.handleDeleteClick}>删除</button>
-//                     </div>
-//                 </div>
-//             </div>
-//         )
-//     }
-// }
+
+export class AddRemove extends React.Component<{}, {}> {
+    state = {
+        layout: fakeData()
+    }
+
+    componentDidMount() {
+
+    }
+    handleClick = () => {
+        this.setState({
+            layout: [...this.state.layout, makeOne()]
+        })
+        console.log(this.state.layout)
+    }
+    hanldeOnDelete = (key: any) => {
+        const layout = this.state.layout.filter((item) => {
+            if (item.key !== key) {
+                return item;
+            }
+        })
+        this.setState({
+            layout: layout
+        })
+    }
+
+    render() {
+        const margin: [number, number] = [5, 5];
+        const dragactInit = {
+            width: 600,
+            col: 12,
+            rowHeight: 800 / 12,
+            margin: margin,
+            className: 'normal-layout',
+            layout: this.state.layout,
+            placeholder: true
+        }
+        return (
+            <div>
+                <div style={{ display: 'flex', justifyContent: 'center' }} >
+                    <div>
+
+                        <h1 style={{ textAlign: 'center' }}>AddRemove Demo</h1>
+                        <button onClick={this.handleClick}>新增</button>
+                        <Dragact {...dragactInit} >
+                            {(item, provided) => {
+                                return <Card item={item} provided={provided} onDelete={this.hanldeOnDelete} />
+                            }}
+                        </Dragact>
+                    </div>
+                </div>
+            </div>
+        )
+    }
+}

+ 20 - 10
src/HandleLayout/index.tsx

@@ -1,12 +1,12 @@
 import * as React from 'react';
-import { Dragact } from '../lib/dragact';
+import { Dragact, DragactLayoutItem, GridItemProvided } from '../../src/lib/dragact'
 
 import './index.css';
 
 const Words = [
     { content: 'You can do anything, but not everything.' },
     { content: 'Those who dare to fail miserably can achieve greatly.' },
-    { content: 'You miss 100 percent of the shots you never take.', handle: true },
+    { content: 'You miss 100 percent of the shots you never take.' },
     { content: 'Those who believe in telekinetics, raise my hand.' },
     { content: 'I’d rather live with a good question than a bad answer.' }
 ]
@@ -20,13 +20,23 @@ const fakeData = () => {
 }
 
 
-const Card = (props: any) => {
-    const item: any = props.item;
+const Card: (item: any) => any = ({ item, provided }) => {
+    const style = { padding: 5, textAlign: 'center', color: '#595959' }
+
+    if (item.key !== '3') {
+        return (
+            <div className='layout-Item' {...provided.props} {...provided.dragHandle}>
+                <div style={style}>
+                    {item.content}
+                </div>
+            </div>
+        )
+    }
     return (
-        <div className='layout-Item' >
-            <div style={{ padding: 5, textAlign: 'center', color: '#595959' }}>
-                {item.handle ? <div className='card-handle' id="dragact-handle">点我拖动
-            </div> : item.content}
+        <div className='layout-Item' {...provided.props}>
+            <div style={style}>
+                {item.content}
+                <div className='card-handle' {...provided.dragHandle} >点我拖动</div>
             </div>
         </div>
     )
@@ -52,8 +62,8 @@ export class HandleLayout extends React.Component<{}, {}> {
                     <div>
                         <h1 style={{ textAlign: 'center' }}>拖拽把手 Demo</h1>
                         <Dragact {...dragactInit}  >
-                            {(item: any, isDragging: Boolean) => {
-                                return <Card item={item} />
+                            {(item: DragactLayoutItem, provided: GridItemProvided) => {
+                                return <Card item={item} provided={provided} />
                             }}
                         </Dragact>
                     </div>

+ 121 - 0
src/HistoryLayout/HistoryLayout.tsx

@@ -0,0 +1,121 @@
+import * as React from 'react';
+
+import { DragactProps, DragactLayoutItem, Dragact } from '../lib/dragact';
+import { GridItemEvent } from '../lib/GridItem';
+
+interface HistoryDragactState {
+  layout: DragactLayoutItem[]
+}
+
+export class HistoryDragact extends React.Component<DragactProps, HistoryDragactState > {
+  _actionsHistory : string[] = []
+  _cacheLayouts: string;
+  _activeItem: GridItemEvent
+  _dragact: Dragact | null
+  constructor(props: DragactProps) {
+      super(props);
+      this.state= {layout: props.layout} as any;
+  }
+
+  _cacheCurrentLayoutStart = (layoutItem: GridItemEvent) => {
+      this._activeItem = layoutItem
+      if (!this._dragact) {
+          return;
+      }
+      this._cachingLayouts(this._dragact);
+  }
+
+  _cacheCurrentLayoutEnd = (layoutItem: GridItemEvent) => {
+      const { GridY, GridX, h, w } = this._activeItem;
+      if (GridX === layoutItem.GridX && GridY === layoutItem.GridY && h === layoutItem.h && w === layoutItem.w) {
+          return;
+  }
+      this._storeLayoutToHistory(this._cacheLayouts)
+  }
+ 
+  _cachingLayouts = (d: Dragact) => {
+      const initiateSnapShot = JSON.stringify({
+          layout: d.getLayout(),
+      })
+      return this._cacheLayouts = initiateSnapShot;
+  }
+
+  goBack = () => {
+      const mapLayoutHistory = this._actionsHistory;
+      if (mapLayoutHistory.length > 1) {
+          const last = mapLayoutHistory.pop();
+          if(!last) {
+              return;
+          }
+          this._changeDragactLayouts(last);
+      }
+  }
+
+  reset = () => {
+      if (!this._dragact) {
+          return;
+      }
+      this._cachingLayouts(this._dragact);
+      this._storeLayoutToHistory(this._cacheLayouts);
+      const initiateSnapShot = this._actionsHistory[0];
+      this._changeDragactLayouts(initiateSnapShot);        
+  }
+  
+  clear = () => {
+      this._actionsHistory = this._actionsHistory.slice(0, 1);
+      this._changeDragactLayouts(this._actionsHistory[0]);
+  }
+
+  onDragStart = (event: GridItemEvent) => {
+      this._cacheCurrentLayoutStart(event)
+      this.props.onDragStart && this.props.onDragStart(event)
+  }
+
+  onDragEnd = (event: GridItemEvent) => {
+      this._cacheCurrentLayoutEnd(event);
+      this.props.onDragEnd && this.props.onDragEnd(event)
+  }
+
+  _changeDragactLayouts = (snapshot: string) => {
+      if(!this._dragact) {
+          return;
+      }
+      try {
+          const {layout} = JSON.parse(snapshot);
+          this.setState({
+              layout
+          })
+      }catch (e) {
+      }
+     
+  }
+
+  _storeLayoutToHistory = (layouts: string) => {
+      this._actionsHistory.push(layouts);
+  }
+
+  componentDidMount() {
+      if (this._dragact) {
+          const initiateSnapShot = this._cachingLayouts(this._dragact);
+          this._storeLayoutToHistory(initiateSnapShot)
+      }
+  }
+
+  componentWillReceiveProps(nextProps: DragactProps) {
+      this.setState({
+          layout: nextProps.layout
+      })
+  }
+  _dragactRefCallback = (d: Dragact) => {
+      this._dragact = d;
+  }
+
+  get getDragact() {
+      return this._dragact;
+  }
+
+  render () {
+      const layout = this.state.layout;
+      return <Dragact ref={this._dragactRefCallback} {...this.props} layout={layout} onDragStart={this.onDragStart} onDragEnd={this.onDragEnd} />
+    }
+}

+ 13 - 0
src/HistoryLayout/index.css

@@ -0,0 +1,13 @@
+.layout-Item {
+    background: white;
+    height: 100%;
+    border-radius: 3px;
+}
+
+.layout-item:hover {
+    cursor: -webkit-grab;
+}
+
+.normal-layout {
+    background: #d9d9d9;
+}

+ 106 - 0
src/HistoryLayout/index.tsx

@@ -0,0 +1,106 @@
+import *as React from 'react';
+import { DragactLayoutItem, GridItemProvided} from '../../src/lib/dragact'
+import { HistoryDragact } from './HistoryLayout'
+import { Words } from './largedata';
+import './index.css';
+
+const fakeData = () => {
+    var Y = 0;
+    return Words.map((item, index) => {
+        if (index % 4 === 0) Y++;
+
+        return { ...item, GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '' }
+    })
+}
+
+
+export const Card: (any: any) => any = ({ item, provided }) => {
+    return (
+        <div
+            className='layout-Item'
+            {...provided.props}
+            {...provided.dragHandle}
+            style={{
+                ...provided.props.style,
+                background: `${provided.isDragging ? '#eaff8f' : 'white'}`
+            }}
+        >
+            <div
+                style={{ padding: 5, textAlign: 'center', color: '#595959' }}
+            >
+                <span>title</span>
+                <div style={{ borderBottom: '1px solid rgba(120,120,120,0.1)' }} />
+                {item.content}
+            </div>
+            <span
+                {...provided.resizeHandle}
+                style={{
+                    position: 'absolute',
+                    width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+                    borderRight: '2px solid rgba(15,15,15,0.2)',
+                    borderBottom: '2px solid rgba(15,15,15,0.2)'
+                }}
+            />
+        </div>
+    )
+}
+
+
+export class HistoryDemo extends React.Component<{}, {}> {
+    drag: HistoryDragact | null
+    render() {
+        const margin: [number, number] = [5, 5];
+        const dragactInit = {
+            width: 600,
+            col: 16,
+            rowHeight: 40,
+            margin: margin,
+            className: 'normal-layout',
+            layout: fakeData()
+        }
+        return (
+            <div
+                style={{
+                    display: 'flex',
+                    justifyContent: 'center'
+                }}
+            >
+                <div>
+                    <h1 style={{ textAlign: 'center' }}>
+                        复原操作demo
+                    </h1>
+                    <button onClick={ () => {
+                        if (this.drag) {
+                            this.drag.goBack();
+                        }
+                    }}>back</button>
+                    <button onClick={ () => {
+                        if (this.drag) {
+                            this.drag.reset();
+                        }
+                    }}>reset</button>
+                    <button onClick={ () => {
+                        if (this.drag) {
+                            this.drag.clear();
+                        }
+                    }}>clear</button>
+                    <HistoryDragact
+                        {...dragactInit}
+                        placeholder={true}
+                        ref={n => this.drag = n}
+                        style={{
+                            background: '#003A8C'
+                        }}
+                    >
+                        {(item: DragactLayoutItem, provided: GridItemProvided) => {
+                            return <Card
+                                item={item}
+                                provided={provided}
+                            />
+                        }}
+                    </HistoryDragact>
+                </div>
+            </div>
+        )
+    }
+}

+ 31 - 0
src/HistoryLayout/largedata.ts

@@ -0,0 +1,31 @@
+export const Words = [
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' },
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' },
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' },
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' },
+    { content: 'I’d rather live with a good question than a bad answer.' },
+    { content: 'You can do anything, but not everything.' },
+    { content: 'Those who dare to fail miserably can achieve greatly.' },
+    { content: 'You miss 100 percent of the shots you never take.' },
+    { content: 'Those who believe in telekinetics, raise my hand.' }
+]

+ 4 - 11
src/LayoutRestore/index.tsx

@@ -1,5 +1,6 @@
 import * as React from 'react';
-import { Dragact } from '../lib/dragact'
+import { Dragact } from '../../src/lib/dragact'
+import { Card } from '../NormalLayout/index';
 import './index.css';
 
 const Words = [
@@ -21,14 +22,6 @@ const fakeData = () => {
 }
 
 
-const Card = (props: any) => {
-    const item = props.item;
-    return (
-        <div className='layout-Item'>
-            <div style={{ padding: 5, textAlign: 'center', color: '#595959' }}>{item.content}</div>
-        </div>
-    )
-}
 
 
 var storeLayout: any = void 666;
@@ -66,8 +59,8 @@ export class LayoutRestore extends React.Component<{}, {}> {
                 onDragEnd={this.handleOnDragEnd}
 
             >
-                {(item: any) => {
-                    return <Card item={item} />
+                {(item: any, provided: any) => {
+                    return <Card item={item} provided={provided} />
                 }}
             </Dragact>
         )

+ 21 - 14
src/NormalLayout/index.tsx

@@ -1,15 +1,9 @@
 import *as React from 'react';
-import { Dragact, DragactLayoutItem } from '../lib/dragact'
-import { Words } from './largedata'
+import { Dragact, DragactLayoutItem, GridItemProvided } from '../../src/lib/dragact'
+import { Words } from './largedata';
 import './index.css';
 
 
-interface CardItem {
-    content: string,
-    img: string
-}
-
-
 
 const fakeData = () => {
     var Y = 0;
@@ -21,13 +15,17 @@ const fakeData = () => {
 }
 
 
-const Card = (props: any) => {
-    const item: CardItem = props.item;
-    const isDragging: Boolean = props.isDragging;
+export const Card: (any: any) => any = ({ item, provided }) => {
     return (
         <div
             className='layout-Item'
-            style={{ background: `${isDragging ? '#eaff8f' : 'white'}` }}>
+            {...provided.props}
+            {...provided.dragHandle}
+            style={{
+                ...provided.props.style,
+                background: `${provided.isDragging ? '#eaff8f' : 'white'}`
+            }}
+        >
             <div
                 style={{ padding: 5, textAlign: 'center', color: '#595959' }}
             >
@@ -35,6 +33,15 @@ const Card = (props: any) => {
                 <div style={{ borderBottom: '1px solid rgba(120,120,120,0.1)' }} />
                 {item.content}
             </div>
+            <span
+                {...provided.resizeHandle}
+                style={{
+                    position: 'absolute',
+                    width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+                    borderRight: '2px solid rgba(15,15,15,0.2)',
+                    borderBottom: '2px solid rgba(15,15,15,0.2)'
+                }}
+            />
         </div>
     )
 }
@@ -69,10 +76,10 @@ export class LayoutDemo extends React.Component<{}, {}> {
                             background: '#003A8C'
                         }}
                     >
-                        {(item: DragactLayoutItem, isDragging: Boolean) => {
+                        {(item: DragactLayoutItem, provided: GridItemProvided) => {
                             return <Card
                                 item={item}
-                                isDragging={isDragging}
+                                provided={provided}
                             />
                         }}
                     </Dragact>

+ 10 - 8
src/StaticWidget/index.tsx

@@ -1,5 +1,5 @@
 import * as React from 'react';
-import { Dragact } from '../lib/dragact'
+import { Dragact } from '../../src/lib/dragact'
 import './index.css'
 
 const Words = [
@@ -19,13 +19,15 @@ const fakeData = () => {
     })
 }
 
-const Cell = (props: any) => {
-    const { item } = props;
+const Cell: (any: any) => any = ({ item, provided }) => {
     return (
-        <div className={`layout-Cell ${item.static ? "static" : ""}`}
-            style={{ background: item.static ? "#e8e8e8" : "", width: "100%" }}
+        <div
+            {...provided.props}
+            {...provided.dragHandle}
+            className={`layout-Cell ${item.static ? "static" : ""}`}
+            style={{ ...provided.props.style, background: item.static ? "#e8e8e8" : "" }}
         >
-            <div style={{ padding:10,color: '#595959' }}>{item.content}</div>
+            <div style={{ padding: 10, color: '#595959' }}>{item.content}</div>
         </div>
     )
 }
@@ -44,8 +46,8 @@ export const SortedTableWithStatic = () => {
                     layout={fakeData()}
                     placeholder={true}
                 >
-                    {(item: any, isDragging: number) => {
-                        return <Cell item={item} />
+                    {(item: any, provided: any) => {
+                        return <Cell item={item} provided={provided} />
                     }}
                 </Dragact>
             </div>

+ 68 - 7
src/index.tsx

@@ -4,9 +4,11 @@ import { LayoutDemo } from './NormalLayout/index';
 import { SortedTableWithStatic } from "./StaticWidget/index";
 import { LayoutRestore } from "./LayoutRestore/index";
 import { HandleLayout } from "./HandleLayout/index";
-// import { AddRemove } from "./AddRemove/index";
+import { AddRemove } from "./AddRemove/index";
+import { HistoryDemo } from "./HistoryLayout/index";
 import { Mobile } from "./mobileLayout/index";
 import './index.css'
+// import { Dragact } from "./lib/dragact";
 
 
 
@@ -16,8 +18,9 @@ const DemoMap: any = {
     StaticHeader: <SortedTableWithStatic />,
     LayoutRestore: <LayoutRestore />,
     HandleLayout: <HandleLayout />,
-    // AddRemove: <AddRemove />,
-    Mobile: <Mobile />
+    AddRemove: <AddRemove />,
+    Mobile: <Mobile />,
+    HistoryLayout: <HistoryDemo />
 }
 
 class DemoDispatcher extends React.Component<{}, {}> {
@@ -35,12 +38,18 @@ class DemoDispatcher extends React.Component<{}, {}> {
     render() {
         return (
             <div>
+                <iframe src="https://ghbtns.com/github-btn.html?user=215566435&repo=Dragact&type=star&count=true&size=large"
+                    frameBorder='0' scrolling="0" width="160px" height="30px"></iframe>
+                <iframe src="https://ghbtns.com/github-btn.html?user=215566435&repo=Dragact&type=fork&count=true&size=large"
+                    frameBorder="0" scrolling="0" width="158px" height="30px"></iframe>
                 <div>切换 Demos</div>
                 <div className='demo-button-layout'>
                     <button onClick={() => this.handleLayoutChange('normalLayout')}>普通布局</button>
                     <button onClick={() => this.handleLayoutChange('StaticHeader')}>静态组件</button>
                     <button onClick={() => this.handleLayoutChange('LayoutRestore')}>存储布局</button>
+                    <button onClick={() => this.handleLayoutChange('HistoryLayout')}>记忆操作布局</button>
                     <button onClick={() => this.handleLayoutChange('HandleLayout')}>拖拽把手</button>
+                    <button onClick={() => this.handleLayoutChange('AddRemove')}>增加和删除</button>
                     <button onClick={() => this.handleLayoutChange('Mobile')}>移动端</button>
                 </div>
                 {this.state.demo}
@@ -49,10 +58,62 @@ class DemoDispatcher extends React.Component<{}, {}> {
     }
 }
 
-<DemoDispatcher />
-
-
-
+{/* <DemoDispatcher /> */ }
+
+//<Dragact/> */}
+
+// const fakeData = [
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '0' },
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '1' },
+//     { GridX: 0, GridY: 0, w: 4, h: 2, key: '2' }
+// ]
+
+// const getblockStyle = (isDragging: Boolean) => {
+//     return {
+//         background: isDragging ? '#1890ff' : 'white',
+//     }
+// };
+
+// const Handle = ({ provided }: any) => {
+//     return (
+//         <div
+//             {...provided.dragHandle}
+//             style={{
+//                 ...getblockStyle(provided.isDragging),
+//                 borderBottom: '1px solid rgba(120,120,120,0.3)',
+//                 textAlign: 'center'
+//             }}
+//         >
+//             点击拖拽
+//         </div>
+//     )
+// }
+
+// ReactDOM.render(
+//     <Dragact
+//         layout={fakeData}//必填项
+//         col={16}//必填项
+//         width={800}//必填项
+//         rowHeight={40}//必填项
+//         margin={[5, 5]}//必填项
+//         className='plant-layout'//必填项
+//         style={{ background: '#333' }}//非必填项
+//         placeholder={true}//非必填项
+//     >
+//         {(item: any, provided: any) => {
+//             return (
+//                 <div
+//                     {...provided.props}
+//                     style={{ ...provided.props.style, background: 'white' }}
+//                 >
+//                     <Handle provided={provided} />
+//                     {provided.isDragging ? '正在抓取' : '停放'}
+//                 </div>
+//             )
+//         }}
+//     </Dragact>,
+//     document.getElementById('root')
+// );
 
 
 

+ 56 - 51
src/lib/dragact.tsx

@@ -24,7 +24,7 @@ export interface DragactLayoutItem {
 }
 
 export interface DragactProps {
-    layout: DragactLayoutItem[] //暂时不推荐使用
+    layout: DragactLayoutItem[]
     /** 
      * 宽度切分比 
      * 这个参数会把容器的宽度平均分为col等份
@@ -45,7 +45,7 @@ export interface DragactProps {
      */
     padding?: number,
 
-    children: any[] | any
+    children: (Item: DragactLayoutItem, provided: GridItemProvided) => any,
 
 
     // 
@@ -104,10 +104,17 @@ interface DragactState {
     containerHeight: number
     dragType: 'drag' | 'resize'
     mapLayout: mapLayout | undefined
+}
 
+export interface GridItemProvided {
+    isDragging: Boolean
+    dragHandle: any;
+    resizeHandle: any;
+    props: any;
 }
 
 export class Dragact extends React.Component<DragactProps, DragactState> {
+   
     constructor(props: DragactProps) {
         super(props)
         this.onDrag = this.onDrag.bind(this)
@@ -115,7 +122,6 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
         this.onDragEnd = this.onDragEnd.bind(this)
 
         const layout = props.layout;
-
         this.state = {
             GridXMoving: 0,
             GridYMoving: 0,
@@ -129,6 +135,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
             mapLayout: undefined
         }
     }
+
     onResizeStart = (layoutItem: GridItemEvent) => {
         const { GridX, GridY, w, h } = layoutItem
         if (this.state.mapLayout) {
@@ -144,11 +151,12 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 dragType: 'resize'
             })
         }
+        this.props.onDragStart && this.props.onDragStart(layoutItem);
     }
 
     onResizing = (layoutItem: GridItemEvent) => {
 
-        const newLayout = layoutCheck(this.state.layout, layoutItem, layoutItem.UniqueKey, layoutItem.UniqueKey, 0);
+        const newLayout = layoutCheck(this.state.layout, layoutItem, layoutItem.UniqueKey + '', layoutItem.UniqueKey + '', 0);
 
         const { compacted, mapLayout } = compactLayout(newLayout, layoutItem, this.state.mapLayout)
 
@@ -174,22 +182,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
 
     onDragStart(bundles: GridItemEvent) {
         const { GridX, GridY, w, h } = bundles
-
         if (this.state.mapLayout) {
-            const newlayout = syncLayout(this.state.mapLayout, bundles)
-
-
-            // this.state = {
-            //     ...this.state,
-            //     GridXMoving: GridX,
-            //     GridYMoving: GridY,
-            //     wMoving: w,
-            //     hMoving: h,
-            //     placeholderShow: true,
-            //     placeholderMoving: true,
-            //     mapLayout: newlayout,
-            //     dragType: 'drag'
-            // }
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -197,22 +190,19 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 hMoving: h,
                 placeholderShow: true,
                 placeholderMoving: true,
-                mapLayout: newlayout,
+                mapLayout: syncLayout(this.state.mapLayout, bundles),
                 dragType: 'drag'
             })
         }
-
-        this.props.onDragStart && this.props.onDragStart(bundles)
+        this.props.onDragStart && this.props.onDragStart(bundles);
     }
 
     onDrag(layoutItem: GridItemEvent) {
-
         const { GridY, UniqueKey } = layoutItem;
         const moving = GridY - this.state.GridYMoving;
 
-        const newLayout = layoutCheck(this.state.layout, layoutItem, UniqueKey, UniqueKey/*用户移动方块的key */, moving);
+        const newLayout = layoutCheck(this.state.layout, layoutItem, UniqueKey + '', UniqueKey + ''/*用户移动方块的key */, moving);
         const { compacted, mapLayout } = compactLayout(newLayout, layoutItem, this.state.mapLayout);
-
         this.setState({
             GridXMoving: layoutItem.GridX,
             GridYMoving: layoutItem.GridY,
@@ -224,18 +214,16 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
     }
 
     onDragEnd(layoutItem: GridItemEvent) {
-
         const { compacted, mapLayout } = compactLayout(this.state.layout, undefined, this.state.mapLayout)
-
         this.setState({
             placeholderShow: false,
             layout: compacted,
             mapLayout: mapLayout,
             containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight)
         })
-
         this.props.onDragEnd && this.props.onDragEnd(layoutItem);
     }
+
     renderPlaceholder() {
         if (!this.state.placeholderShow) return null
         var { col, width, padding, rowHeight, margin, placeholder } = this.props
@@ -259,20 +247,24 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 dragType={dragType}
                 canDrag={false}
                 canResize={false}
-            />
+            >
+                {(p: any, resizerProps: any) => <div {...p} />}
+            </GridItem>
         )
     }
 
     componentWillReceiveProps(nextProps: any) {
-        if (this.props.children.length > nextProps.children.length) { //remove
+        if (this.props.layout.length > nextProps.layout.length) { //remove
             const mapLayoutCopy = { ...this.state.mapLayout };
-            nextProps.children.forEach((child: any) => {
-                if ((mapLayoutCopy as any)[child.key] !== void 666) delete (mapLayoutCopy as any)[child.key];
+            nextProps.layout.forEach((child: any) => {
+                if ((mapLayoutCopy as any)[child.key + ''] !== void 666) delete (mapLayoutCopy as any)[child.key + ''];
             })
+
             for (const key in mapLayoutCopy) {
                 const newLayout = this.state.layout.filter((child) => {
-                    if (child.key !== key) return child
+                    if (child.key + '' !== key + '') return child
                 })
+
                 const { compacted, mapLayout } = compactLayout(newLayout, undefined, this.state.mapLayout);
                 this.setState({
                     containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight),
@@ -280,41 +272,47 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                     mapLayout
                 })
             }
-        }
-
-        if (this.props.children.length < nextProps.children.length) { //add
+        }  else  if (this.props.layout.length < nextProps.layout.length) {//add
             var item;
-            for (const idx in nextProps.children) {
-                const i = nextProps.children[idx];
-                if (this.state.mapLayout && !this.state.mapLayout[i.key]) {
+            for (const idx in nextProps.layout) {
+                const i = nextProps.layout[idx];
+                if (this.state.mapLayout && !this.state.mapLayout[i.key + '']) {
                     item = i;
                     break;
                 }
             }
             if (item !== void 666) {
-                const dataSet = { ...item.props['data-set'], isUserMove: false, key: item.key };
+                const dataSet = { ...item, isUserMove: false, key: item.key + '' };
                 var newLayout = [...this.state.layout, dataSet]
-                newLayout = correctLayout(newLayout, this.props.col)
                 const { compacted, mapLayout } = compactLayout(newLayout, undefined, this.state.mapLayout);
                 this.setState({
-                    containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight),
+                    containerHeight: getMaxContainerHeight(compacted,
+                        this.props.rowHeight,
+                        this.props.margin[1],
+                        this.state.containerHeight,
+                        false),
                     layout: compacted,
                     mapLayout
                 })
             }
+        } else {
+            this.recalculateLayout(nextProps.layout, nextProps.col);
         }
+    }
 
+    recalculateLayout = (layout: DragactLayoutItem[], col: number) => {
+        const corrected = correctLayout(layout, col)
+        const { compacted, mapLayout } = compactLayout(corrected, undefined, undefined);
+        this.setState({
+            layout: compacted,
+            mapLayout: mapLayout,
+            containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight, false)
+        })
     }
 
     componentDidMount() {
         setTimeout(() => {
-            let layout = correctLayout(this.state.layout, this.props.col)
-            const { compacted, mapLayout } = compactLayout(layout, undefined, this.state.mapLayout);
-            this.setState({
-                layout: compacted,
-                mapLayout: mapLayout,
-                containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight)
-            })
+            this.recalculateLayout(this.state.layout, this.props.col)
         }, 1);
     }
 
@@ -322,7 +320,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
         const { dragType, mapLayout } = this.state;
         var { col, width, padding, rowHeight, margin } = this.props;
         if (mapLayout) {
-            const renderItem = layoutItemForkey(mapLayout, child.key);
+            const renderItem = layoutItemForkey(mapLayout, child.key + '');
             if (!padding) padding = 0;
             return (
                 <GridItem
@@ -343,11 +341,17 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                     dragType={dragType}
                     key={child.key}
                 >
-                    {this.props.children(child, renderItem.isUserMove)}
+                    {(GridItemProvided, dragHandle, resizeHandle) => this.props.children(child, {
+                        isDragging: renderItem.isUserMove !== void 666 ? renderItem.isUserMove : false,
+                        props: GridItemProvided,
+                        dragHandle,
+                        resizeHandle
+                    })}
                 </GridItem >
             )
         }
     }
+
     render() {
         const {
             width,
@@ -359,6 +363,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
 
         return (
             <div
+
                 className={stringJoin('DraggerLayout', className + '')}
                 style={{
                     ...style,

+ 60 - 47
src/lib/dragger/index.tsx

@@ -64,11 +64,15 @@ interface DraggerProps {
     canDrag?: Boolean;
 
     canResize?: Boolean;
+
+    children: (provided: any, resizeMix: any, dragMix: any) => any;
 }
 
+
 export class Dragger extends React.Component<DraggerProps, {}> {
     parent: any;
     self: any;
+    Ref: any;
 
     constructor(props: DraggerProps) {
         super(props)
@@ -187,7 +191,7 @@ export class Dragger extends React.Component<DraggerProps, {}> {
          * 调整手感 
          * 无论是向上移动还是向下移动,全部都是根据重力中心
          * */
-        const height = (this.refs['dragger'] as HTMLDivElement).getClientRects()[0].height;
+        const height = (this.Ref as HTMLDivElement).getClientRects()[0].height;
         const upNdown = this.state.y - deltaY;
         const fixY = deltaY + (upNdown >= 0 ? 0 : height / 2);
         /**移动时回调,用于外部控制 */
@@ -203,9 +207,10 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
         doc.body.style.userSelect = 'none'
 
-        if (this.props.handle) {
-            if (event.target.id !== 'dragact-handle') return
-        }
+       
+
+        // if (event.target.id !== 'dragact-handle') return
+
 
         /**
          * 把监听事件的回掉函数,绑定在document上
@@ -239,9 +244,11 @@ export class Dragger extends React.Component<DraggerProps, {}> {
             this.self = event.currentTarget
         }
 
-        this.props.onDragStart && this.props.onDragStart(this.state.x, this.state.y)
+       
 
+        this.props.onDragStart && this.props.onDragStart(this.state.x, this.state.y)
 
+        
         let originX, originY;
         if (event.type.indexOf('mouse') >= 0) {
             originX = (event as MouseEvent).clientX
@@ -251,6 +258,8 @@ export class Dragger extends React.Component<DraggerProps, {}> {
             originY = (event as TouchEvent).touches[0].clientY
         }
 
+        
+
         this.setState({
             originX: originX,
             originY: originY,
@@ -372,24 +381,17 @@ export class Dragger extends React.Component<DraggerProps, {}> {
     }
 
     mixin = () => {
-        var dragMix = {};
-        if (this.props.canDrag === void 666 || this.props.canDrag === true) {
-            dragMix = {
-                onMouseDown: this.onDragStart,
-                onTouchStart: this.onDragStart,
-                onTouchEnd: this.onDragEnd,
-                onMouseUp: this.onDragEnd
-            }
-        }
+        var dragMix = {
+            onMouseDown: this.onDragStart,
+            onTouchStart: this.onDragStart,
+            onTouchEnd: this.onDragEnd,
+            onMouseUp: this.onDragEnd
+        };
 
-        var resizeMix = {}
-        if (this.props.canResize === void 666 || this.props.canDrag === true) {
-            resizeMix = {
-                onMouseDown: this.onResizeStart,
-                onMouseUp: this.onResizeEnd
-            }
+        var resizeMix = {
+            onMouseDown: this.onResizeStart,
+            onMouseUp: this.onResizeEnd
         }
-
         return {
             dragMix, resizeMix
         };
@@ -416,31 +418,42 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         const { dragMix, resizeMix } = this.mixin();
 
         /**主要是为了让用户定义自己的className去修改css */
-        const fixedClassName = typeof className === 'undefined' ? '' : className + ' '
-        return (
-            <div className={`${fixedClassName}WrapDragger`}
-                ref={'dragger'}
-                style={{
-                    ...style,
-                    touchAction: 'none!important',
-                    transform: `translate(${x}px,${y}px)`,
-                    width: w,
-                    height: h,
-                }}
-                {...dragMix}
-            >
-                {this.props.children ? React.Children.only(this.props.children) : null}
-                {canResize !== false ?
-                    <span
-                        {...resizeMix}
-                        style={{
-                            position: 'absolute',
-                            width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
-                            borderRight: '2px solid rgba(15,15,15,0.2)',
-                            borderBottom: '2px solid rgba(15,15,15,0.2)'
-                        }}
-                    /> : null}
-            </div>
-        )
+        // const fixedClassName = typeof className === 'undefined' ? '' : className + ' '
+        resizeMix;
+        canResize;
+        className;
+
+
+        const provided = {
+            style: {
+                ...style,
+                touchAction: 'none!important',
+                transform: `translate(${x}px,${y}px)`,
+                width: w,
+                height: h,
+            },
+            ref: (node: any) => this.Ref = node
+        }
+
+        return this.props.children(provided, dragMix, resizeMix)
     }
 }
+
+
+// return (
+//     <div className={`${fixedClassName}WrapDragger`}
+//         ref={'dragger'}
+//     >
+//         {this.props.children(provided)}
+//         {canResize !== false ?
+//             <span
+//                 {...resizeMix}
+//                 style={{
+//                     position: 'absolute',
+//                     width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+//                     borderRight: '2px solid rgba(15,15,15,0.2)',
+//                     borderBottom: '2px solid rgba(15,15,15,0.2)'
+//                 }}
+//             /> : null}
+//     </div>
+// )

+ 6 - 3
src/lib/gridItem.tsx

@@ -31,7 +31,7 @@ export interface GridItemProps {
 
     isUserMove: Boolean
 
-    UniqueKey?: string | number
+    UniqueKey?: string
 
     static?: Boolean
 
@@ -46,6 +46,8 @@ export interface GridItemProps {
     canDrag?: Boolean
 
     canResize?: Boolean
+
+    children: (provided: any, draggerProps: any, resizerProps: any) => any;
 }
 
 export interface GridItemEvent {
@@ -161,12 +163,13 @@ export default class GridItem extends React.Component<GridItemProps, {}> {
 
     onDragStart(x: number, y: number) {
         const { w, h, UniqueKey } = this.props;
+
         if (this.props.static) return;
 
         const { GridX, GridY } = this.calGridXY(x, y)
 
         this.props.onDragStart && this.props.onDragStart({
-            event, GridX, GridY, w, h, UniqueKey: UniqueKey + ''
+            event: null, GridX, GridY, w, h, UniqueKey: UniqueKey + ''
         })
     }
     onDrag(event: any, x: number, y: number) {
@@ -231,7 +234,7 @@ export default class GridItem extends React.Component<GridItemProps, {}> {
                 canDrag={canDrag}
                 canResize={canResize}
             >
-                {this.props.children}
+                {(provided, draggerProps, resizerProps) => this.props.children(provided, draggerProps, resizerProps)}
             </Dragger>
         )
     }

+ 1 - 1
src/lib/util/collison.ts

@@ -34,7 +34,7 @@ export const layoutCheck = function () {
     var caches: any = {};
 
     const _layoutCheck = function (layout: DragactLayoutItem[], layoutItem: GridItemEvent,
-        key: string | number, fristItemkey: string | number, moving: number) {
+        key: string, fristItemkey: string, moving: number) {
 
 
         if (layoutItem.GridX === caches.GridX

+ 3 - 2
src/lib/util/compact.ts

@@ -10,7 +10,7 @@ import { GridItemEvent } from "../GridItem";
  */
 export const compactItem = (finishedLayout: DragactLayoutItem[], item: DragactLayoutItem) => {
     if (item.static) return item;
-    const newItem = { ...item }
+    const newItem = { ...item, key: item.key + '' }
     if (finishedLayout.length === 0) {
         return { ...newItem, GridY: 0 }
     }
@@ -39,7 +39,7 @@ export const compactLayout = function () {
     var _cache: any = {
     };
 
-    return function (layout: DragactLayoutItem[], movingItem: GridItemEvent | undefined, mapedLayout: any) {
+    return function (layout: DragactLayoutItem[], movingItem: GridItemEvent | undefined, mapedLayout: mapLayout | undefined) {
         if (movingItem) {
             if (_cache.GridX === movingItem.GridX
                 && _cache.GridY === movingItem.GridY &&
@@ -59,6 +59,7 @@ export const compactLayout = function () {
         const compareList = []
         const mapLayout: mapLayout = {};
 
+
         for (let i = 0, length = sorted.length; i < length; i++) {
             let finished = compactItem(compareList, sorted[i])
             if (movingItem) {

+ 1 - 1
src/lib/util/correction.ts

@@ -28,7 +28,7 @@ export const correctLayout = (layout: DragactLayoutItem[], col: number) => {
         correctItem(copy[i + 1], col);
 
         if (collision(copy[i], copy[i + 1])) {
-            copy = layoutCheck(copy, <GridItemEvent>copy[i], (<GridItemEvent>copy[i]).UniqueKey, (<GridItemEvent>copy[i]).UniqueKey, 0)
+            copy = layoutCheck(copy, <GridItemEvent>copy[i], (<GridItemEvent>copy[i]).UniqueKey + '', (<GridItemEvent>copy[i]).UniqueKey + '', 0)
         }
     }
 

+ 1 - 1
src/lib/util/initiate.ts

@@ -48,7 +48,7 @@ export const MapLayoutTostate = (layout: DragactLayoutItem[], children: any[]) =
  * @param {*} layout 输入进来的布局
  * @param {*} key 
  */
-export const layoutItemForkey = (layout: mapLayout, key: number) => {
+export const layoutItemForkey = (layout: mapLayout, key: string) => {
     return layout[key]
 }
 

+ 10 - 7
src/lib/util/sort.ts

@@ -22,19 +22,22 @@ export const sortLayout = (layout: any) => {
  * 这个函数带有记忆功能
  */
 export const getMaxContainerHeight = function () {
-    var lastOneGridY = 0;
-    return function (layout: DragactLayoutItem[], elementHeight = 30, elementMarginBottom = 10, currentHeight: number) {
-        const length = layout.length;
-        const currentLastOne = layout[length - 1];
-        if (currentLastOne.GridY === lastOneGridY) {
-            return currentHeight
+    var lastOneYNH = 0;
+    return function (layout: DragactLayoutItem[], elementHeight = 30, elementMarginBottom = 10, currentHeight: number, useCache?: Boolean) {
+        if (useCache !== false) {
+            const length = layout.length;
+            const currentLastOne = layout[length - 1];
+            if (currentLastOne.GridY + currentLastOne.h === lastOneYNH) {
+                return currentHeight
+            }
+            lastOneYNH = currentLastOne.GridY + currentLastOne.h;
         }
-        lastOneGridY = currentLastOne.GridY;
         const ar = layout.map((item) => {
             return item.GridY + item.h
         })
         const h = quickSort(ar)[ar.length - 1];
         const height = h * (elementHeight + elementMarginBottom) + elementMarginBottom
+
         return height
     }
 }();

+ 12 - 17
src/mobileLayout/index.tsx

@@ -1,33 +1,29 @@
 import *as React from 'react';
-import { Dragact, DragactLayoutItem } from '../lib/dragact'
+import { Dragact, DragactLayoutItem } from '../../src/lib/dragact'
 import { Words } from './largedata'
 import './index.css';
 
-
-interface CardItem {
-    content: string,
-    img: string
-}
-
-
-
 const fakeData = () => {
     var Y = 0;
     return Words.map((item, index) => {
         if (index % 4 === 0) Y++;
 
-        return { ...item, GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '', canResize: false }
+        return { ...item, GridX: index % 4 * 4, GridY: Y * 4, w: 4, h: 3, key: index + '' }
     })
 }
 
 
-const Card = (props: any) => {
-    const item: CardItem = props.item;
-    const isDragging: Boolean = props.isDragging;
+const Card: (any: any) => any = ({ item, provided }) => {
     return (
         <div
             className='layout-Item'
-            style={{ background: `${isDragging ? '#eaff8f' : 'white'}` }}>
+            {...provided.props}
+            {...provided.dragHandle}
+            style={{
+                ...provided.props.style,
+                background: `${provided.isDragging ? '#eaff8f' : 'white'}`
+            }}
+        >
             <div
                 style={{ padding: 5, textAlign: 'center', color: '#595959' }}
             >
@@ -39,7 +35,6 @@ const Card = (props: any) => {
     )
 }
 
-
 export class Mobile extends React.Component<{}, {}> {
     render() {
         const margin: [number, number] = [5, 5];
@@ -69,10 +64,10 @@ export class Mobile extends React.Component<{}, {}> {
                             background: '#003A8C'
                         }}
                     >
-                        {(item: DragactLayoutItem, isDragging: Boolean) => {
+                        {(item: DragactLayoutItem, provided: any) => {
                             return <Card
                                 item={item}
-                                isDragging={isDragging}
+                                provided={provided}
                             />
                         }}
                     </Dragact>

+ 32 - 0
src/showdown/index.ts

@@ -0,0 +1,32 @@
+const showdown = require('showdown');
+const hljs = require('highlightjs');
+
+var decodeHtml = require("html-encoder-decoder").decode;
+
+function showdownHighlight() {
+    return [{
+        type: "output",
+        filter: function filter(text: any, converter: any, options: any) {
+            var left = "<pre><code\\b[^>]*>",
+                right = "</code></pre>",
+                flags = "g",
+                replacement = function replacement(wholeMatch: any, match: any, left: any, right: any) {
+                    match = decodeHtml(match);
+                    var lang = (left.match(/class=\"([^ \"]+)/) || [])[1];
+                    console.log(left + hljs.highlight(lang, match).value + right);
+                    if (lang) {
+                        return left + hljs.highlight(lang, match).value + right;
+                    } else {
+                        return left + hljs.highlightAuto(match).value + right;
+                    }
+                };
+
+            return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
+        }
+    }];
+};
+
+
+export const convertor = new showdown.Converter({
+    extensions: [showdownHighlight]
+});

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно