소스 검색

1.readme
2.build

Z F 7 년 전
부모
커밋
4ee04893fd
13개의 변경된 파일526개의 추가작업 그리고 136개의 파일을 삭제
  1. 22 2
      README.md
  2. 2 3
      app/src/App.js
  3. 5 10
      app/src/SortedTable/index.js
  4. 19 0
      app/src/StaticHeader/index.css
  5. 36 0
      app/src/StaticHeader/index.js
  6. 2 0
      app/src/index.js
  7. 112 97
      build/App.js
  8. 43 9
      build/Dragger.js
  9. 27 13
      build/GridItem.js
  10. 62 0
      build/NormalLayout/index.js
  11. 59 0
      build/SortedTable/index.js
  12. 58 0
      build/StaticHeader/index.js
  13. 79 2
      build/index.js

+ 22 - 2
README.md

@@ -6,12 +6,32 @@ Dragact is a react component, which allows you to build your own **dragable grid
 
 
 # Demo
-[Live Demo  ](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html)
+[Live Demo](http://htmlpreview.github.io/?https://github.com/215566435/React-dragger-layout/blob/master/build/index.html)
 
 
 # Feature
 - [x] auto sorted layout
 - [x] mobile device supported
 - [x] auto height fixed
-- [x] 
+- [x] static component
 
+
+
+
+# Contribute
+
+### Want a new feature?
+1. If you have a feature request, please add it as an issue or make a pull request.
+2. After adding some awesome feature, please run the test and make sure it will pass all tests before you make a PR.
+
+### a Bug?
+If you have a bug to report, please reproduce the bug in Github issue with a sample code to help us easily isolate it.
+
+
+
+
+# TODO-LIST
+- [ ] horizontal swaping
+- [ ] resizing
+- [ ] touch handle
+- [ ] responsive layout

+ 2 - 3
app/src/App.js

@@ -384,9 +384,8 @@ export class DraggerLayout extends React.Component {
 
     getGridItem(child, index) {
         const { layout } = this.state
-        const { col, width, padding, rowHeight, margin } = this.props
-        const renderItem = layoutItemForkey(layout, child.key)
-
+        const { col, width, padding, rowHeight, margin } = this.props;
+        const renderItem = layoutItemForkey(layout, child.key);//TODO:可以优化速度,这一步不是必须;
         return (
             <GridItem
                 margin={margin}

+ 5 - 10
app/src/SortedTable/index.js

@@ -21,9 +21,6 @@ const Cell = ({ item }) => {
 }
 
 
-// {Words.map((el, index) => {
-//     return <Cell item={el} key={index} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} />
-// })}
 
 export const SortedTable = () => {
 
@@ -31,15 +28,13 @@ export const SortedTable = () => {
         <div style={{ display: 'flex', justifyContent: 'center' }}>
             <div>
                 <h1 style={{ textAlign: 'center' }}>Sorted Table Demo</h1>
-                <DraggerLayout width={800} col={6} rowHeight={60} margin={[2, 2]} className='normal-layout'>
-                    <div key={1} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} className='layout-Cell'>1</div>
-                    <div key={2} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} className='layout-Cell'>1</div>
-                    <div key={3} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} className='layout-Cell'>1</div>
-                    <div key={4} data-set={{ GridX: 3, GridY: 2, w: 1, h: 1, static: true }} className='layout-Cell'>静态</div>
-                    <div key={5} data-set={{ GridX: 3, GridY: 0, w: 1, h: 1 }} className='layout-Cell'>1</div>
-                    <div key={6} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} className='layout-Cell'>1</div>
+                <DraggerLayout width={800} col={1} rowHeight={60} margin={[2, 2]} className='normal-layout'>
+                    {Words.map((el, index) => {
+                        return <Cell item={el} key={index} data-set={{ GridX: 0, GridY: 0, w: 1, h: 1 }} />
+                    })}
                 </DraggerLayout>
             </div>
         </div>
     )
 }
+

+ 19 - 0
app/src/StaticHeader/index.css

@@ -0,0 +1,19 @@
+.layout-Cell>img {
+    border-radius: 5px;
+}
+
+.layout-Cell {
+    background: white;
+    display: flex;
+    align-items: center;
+    height: 100%;
+    padding-left: 12px;
+}
+
+.layout-Cell:hover {
+    cursor: -webkit-grab;
+}
+
+.layout-Cell.static:hover {
+    cursor: no-drop;
+}

+ 36 - 0
app/src/StaticHeader/index.js

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

+ 2 - 0
app/src/index.js

@@ -3,6 +3,7 @@ import React from 'react';
 import ReactDOM from 'react-dom';
 import { LayoutDemo } from './NormalLayout';
 import { SortedTable } from './SortedTable';
+import { SortedTableWithStatic } from './StaticHeader';
 
 
 
@@ -10,6 +11,7 @@ ReactDOM.render(
     <div>
         <LayoutDemo />
         <SortedTable />
+        <SortedTableWithStatic />
     </div>,
     document.getElementById('root')
 );

+ 112 - 97
build/App.js

@@ -7,17 +7,33 @@ import _extends from 'babel-runtime/helpers/extends';
 import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray';
 import React from 'react';
 import PropTypes from 'prop-types';
-import GridItem from './GridItem';
+import GridItem, { checkInContainer } from './GridItem';
 
 import './style.css';
 
-var correctLayout = function correctLayout(layout) {
+/**
+ * 这个函数会有副作用,不是纯函数,会改变item的Gridx和GridY
+ * @param {*} item 
+ */
+var correctItem = function correctItem(item, col) {
+    var _checkInContainer = checkInContainer(item.GridX, item.GridY, col, item.w),
+        GridX = _checkInContainer.GridX,
+        GridY = _checkInContainer.GridY;
+
+    item.GridX = GridX;
+    item.GridY = GridY;
+};
+var correctLayout = function correctLayout(layout, col) {
     var copy = [].concat(_toConsumableArray(layout));
     for (var i = 0; i < layout.length - 1; i++) {
+        correctItem(copy[i], col);
+        correctItem(copy[i + 1], col);
+
         if (collision(copy[i], copy[i + 1])) {
-            copy = layoutCheck(copy, layout[i], layout[i].key, layout[i].key, undefined);
+            copy = layoutCheck(copy, copy[i], copy[i].key, copy[i].key, undefined);
         }
     }
+
     return copy;
 };
 
@@ -44,7 +60,7 @@ var layoutItemForkey = function layoutItemForkey(layout, key) {
 
 var MapLayoutTostate = function MapLayoutTostate(layout, children) {
     return layout.map(function (child, index) {
-        var newChild = _extends({}, child, { isUserMove: true, key: children[index].key });
+        var newChild = _extends({}, child, { isUserMove: true, key: children[index].key, static: children[index].static });
         return newChild;
     });
 };
@@ -84,6 +100,7 @@ var collision = function collision(a, b) {
 var sortLayout = function sortLayout(layout) {
     return [].concat(layout).sort(function (a, b) {
         if (a.GridY > b.GridY || a.GridY === b.GridY && a.GridX > b.GridX) {
+            if (a.static) return 0; //为了静态,排序的时候尽量把静态的放在前面
             return 1;
         } else if (a.GridY === b.GridY && a.GridX === b.GridX) {
             return 0;
@@ -108,10 +125,9 @@ var getFirstCollison = function getFirstCollison(layout, item) {
  * @param {*} item 
  */
 var compactItem = function compactItem(finishedLayout, item) {
+    if (item.static) return item;
     var newItem = _extends({}, item);
-
     if (finishedLayout.length === 0) {
-
         return _extends({}, newItem, { GridY: 0 });
     }
     /**
@@ -144,16 +160,20 @@ var compactLayout = function compactLayout(layout) {
         var finished = compactItem(compareList, sorted[i]);
         finished.isUserMove = false;
         compareList.push(finished);
-        needCompact[i] = finished; //用于输出从小到大的位置
+        needCompact[i] = finished;
     }
-    return sortLayout(needCompact);
+    return needCompact;
 };
 
 var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, moving) {
     var i = [],
         movedItem = []; /**收集所有移动过的物体 */
     var newlayout = layout.map(function (item, idx) {
+
         if (item.key !== key) {
+            if (item.static) {
+                return item;
+            }
             if (collision(item, layoutItem)) {
                 i.push(item.key);
                 /**
@@ -169,13 +189,13 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                     /**
                      * 元素向上移动时,元素的上面空间不足,则不移动这个元素
                      * 当元素移动到GridY>所要向上交换的元素时,就不会进入这里,直接交换元素
-                     * 
                      */
                     offsetY = item.GridY;
                 }
                 /**
                  * 物体向下移动的时候
                  */
+
                 if (moving > 0) {
                     if (layoutItem.GridY + layoutItem.h < item.GridY) {
                         (function () {
@@ -202,13 +222,16 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                         })();
                     }
                 }
+
                 movedItem.push(_extends({}, item, { GridY: offsetY, isUserMove: false }));
                 return _extends({}, item, { GridY: offsetY, isUserMove: false });
             }
         } else if (fristItemkey === key) {
+
             /**永远保持用户移动的块是 isUserMove === true */
             return _extends({}, item, { GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true });
         }
+
         return item;
     });
     /** 递归调用,将layout中的所有重叠元素全部移动 */
@@ -219,14 +242,37 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
     return newlayout;
 };
 
-var getMaxContainerHeight = function getMaxContainerHeight(layout, elementHeight) {
+function quickSort(a) {
+    return a.length <= 1 ? a : quickSort(a.slice(1).filter(function (item) {
+        return item <= a[0];
+    })).concat(a[0], quickSort(a.slice(1).filter(function (item) {
+        return item > a[0];
+    })));
+}
+
+var getMaxContainerHeight = function getMaxContainerHeight(layout) {
+    var elementHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30;
+    var elementMarginBottom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10;
 
-    var height = (layout[layout.length - 1].GridY + layout[layout.length - 1].h) * (30 + 10) + 10;
-    console.log(height);
+    var ar = layout.map(function (item) {
+        return item.GridY + item.h;
+    });
+    var h = quickSort(ar)[ar.length - 1];
+    var height = h * (elementHeight + elementMarginBottom) + elementMarginBottom;
     return height;
 };
 
-var DraggerLayout = function (_React$Component) {
+var getDataSet = function getDataSet(children) {
+    return children.map(function (child) {
+        return _extends({}, child.props['data-set'], { isUserMove: true, key: child.key });
+    });
+};
+
+var stringJoin = function stringJoin(source, join) {
+    return source + (join ? ' ' + join : '');
+};
+
+export var DraggerLayout = function (_React$Component) {
     _inherits(DraggerLayout, _React$Component);
 
     function DraggerLayout(props) {
@@ -234,6 +280,12 @@ var DraggerLayout = function (_React$Component) {
 
         var _this = _possibleConstructorReturn(this, (DraggerLayout.__proto__ || _Object$getPrototypeOf(DraggerLayout)).call(this, props));
 
+        _this.onDrag = _this.onDrag.bind(_this);
+        _this.onDragStart = _this.onDragStart.bind(_this);
+        _this.onDragEnd = _this.onDragEnd.bind(_this);
+
+        var layout = props.layout ? MapLayoutTostate(props.layout, props.children) : getDataSet(props.children);
+
         _this.state = {
             GridXMoving: 0,
             GridYMoving: 0,
@@ -241,13 +293,9 @@ var DraggerLayout = function (_React$Component) {
             hMoving: 0,
             placeholderShow: false,
             placeholderMoving: false,
-            layout: MapLayoutTostate(_this.props.layout, _this.props.children),
+            layout: layout,
             containerHeight: 500
         };
-
-        _this.onDrag = _this.onDrag.bind(_this);
-        _this.onDragStart = _this.onDragStart.bind(_this);
-        _this.onDragEnd = _this.onDragEnd.bind(_this);
         return _this;
     }
 
@@ -262,6 +310,7 @@ var DraggerLayout = function (_React$Component) {
 
 
             var newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
+
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -271,6 +320,7 @@ var DraggerLayout = function (_React$Component) {
                 placeholderMoving: true,
                 layout: newlayout
             });
+            this.props.onDragStart && this.props.onDragStart({ GridX: GridX, GridY: GridY });
         }
     }, {
         key: 'onDrag',
@@ -283,26 +333,27 @@ var DraggerLayout = function (_React$Component) {
             var newLayout = layoutCheck(this.state.layout, layoutItem, key, key /*用户移动方块的key */, moving);
             var compactedLayout = compactLayout(newLayout);
             for (var i = 0; i < compactedLayout.length; i++) {
-                if (key === compactedLayout[i].key) {
+                var compactedItem = compactedLayout[i];
+                if (key === compactedItem.key) {
                     /**
                      * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
                      * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
                      * 但是实际layout中的位置还是会改变
                      * (isUserMove=true用于解除placeholder和元素的绑定)
                      */
-                    compactedLayout[i].isUserMove = true;
-                    layoutItem.GridX = compactedLayout[i].GridX;
-                    layoutItem.GridY = compactedLayout[i].GridY;
+                    compactedItem.isUserMove = true;
+                    layoutItem.GridX = compactedItem.GridX;
+                    layoutItem.GridY = compactedItem.GridY;
                     break;
                 }
             }
-
             this.setState({
                 GridXMoving: layoutItem.GridX,
                 GridYMoving: layoutItem.GridY,
                 layout: compactedLayout,
-                containerHeight: getMaxContainerHeight(compactedLayout)
+                containerHeight: getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
             });
+            this.props.onDrag && this.props.onDrag({ GridX: GridX, GridY: GridY });
         }
     }, {
         key: 'onDragEnd',
@@ -311,18 +362,21 @@ var DraggerLayout = function (_React$Component) {
             this.setState({
                 placeholderShow: false,
                 layout: compactedLayout,
-                containerHeight: getMaxContainerHeight(compactedLayout)
+                containerHeight: getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
             });
+
+            this.props.onDragEnd && this.props.onDragEnd();
         }
     }, {
-        key: 'placeholder',
-        value: function placeholder() {
+        key: 'renderPlaceholder',
+        value: function renderPlaceholder() {
             if (!this.state.placeholderShow) return null;
             var _props = this.props,
                 col = _props.col,
                 width = _props.width,
                 padding = _props.padding,
-                rowHeight = _props.rowHeight;
+                rowHeight = _props.rowHeight,
+                margin = _props.margin;
             var _state = this.state,
                 GridXMoving = _state.GridXMoving,
                 GridYMoving = _state.GridYMoving,
@@ -332,6 +386,7 @@ var DraggerLayout = function (_React$Component) {
 
 
             return React.createElement(GridItem, {
+                margin: margin,
                 col: col,
                 containerWidth: width,
                 containerPadding: padding,
@@ -340,20 +395,21 @@ var DraggerLayout = function (_React$Component) {
                 GridY: GridYMoving,
                 w: wMoving,
                 h: hMoving,
-                style: { background: '#a31', zIndex: -1, transition: ' all .15s' },
+                style: { background: '#d6e4ff', zIndex: 1, transition: ' all .15s' },
                 isUserMove: !placeholderMoving
             });
         }
     }, {
         key: 'componentDidMount',
         value: function componentDidMount() {
-            var that = this;
+            var _this2 = this;
+
             setTimeout(function () {
-                var layout = correctLayout(that.state.layout);
+                var layout = correctLayout(_this2.state.layout, _this2.props.col);
                 var compacted = compactLayout(layout);
-                that.setState({
+                _this2.setState({
                     layout: compacted,
-                    containerHeight: getMaxContainerHeight(compacted)
+                    containerHeight: getMaxContainerHeight(compacted, _this2.props.rowHeight, _this2.props.margin[1])
                 });
             }, 1);
         }
@@ -365,12 +421,14 @@ var DraggerLayout = function (_React$Component) {
                 col = _props2.col,
                 width = _props2.width,
                 padding = _props2.padding,
-                rowHeight = _props2.rowHeight;
+                rowHeight = _props2.rowHeight,
+                margin = _props2.margin;
 
-            var renderItem = layoutItemForkey(layout, child.key);
+            var renderItem = layoutItemForkey(layout, child.key); //TODO:可以优化速度,这一步不是必须;
             return React.createElement(
                 GridItem,
                 {
+                    margin: margin,
                     col: col,
                     containerWidth: width,
                     containerPadding: padding,
@@ -384,8 +442,9 @@ var DraggerLayout = function (_React$Component) {
                     onDragEnd: this.onDragEnd,
                     index: index,
                     isUserMove: renderItem.isUserMove,
-                    style: { background: '#329' },
-                    UniqueKey: child.key
+                    UniqueKey: child.key,
+                    style: { zIndex: 2 },
+                    'static': renderItem.static
                 },
                 child
             );
@@ -393,34 +452,35 @@ var DraggerLayout = function (_React$Component) {
     }, {
         key: 'render',
         value: function render() {
-            var _this2 = this;
+            var _this3 = this;
 
             var _props3 = this.props,
                 layout = _props3.layout,
                 col = _props3.col,
                 width = _props3.width,
                 padding = _props3.padding,
-                rowHeight = _props3.rowHeight;
+                rowHeight = _props3.rowHeight,
+                className = _props3.className;
+            var containerHeight = this.state.containerHeight;
 
 
             return React.createElement(
                 'div',
                 {
-                    className: 'DraggerLayout',
-                    style: { left: 100, width: this.props.width, height: this.state.containerHeight, border: '1px solid black' }
+                    className: stringJoin('DraggerLayout', className),
+                    style: { left: 100, width: width, height: containerHeight, zIndex: 1 }
                 },
                 React.Children.map(this.props.children, function (child, index) {
-                    return _this2.getGridItem(child, index);
+                    return _this3.getGridItem(child, index);
                 }),
-                this.placeholder()
+                this.renderPlaceholder()
             );
         }
     }]);
 
     return DraggerLayout;
 }(React.Component);
-
-DraggerLayout.PropTypes = {
+DraggerLayout.propTypes = {
     /**外部属性 */
     layout: PropTypes.array,
     col: PropTypes.number,
@@ -429,55 +489,6 @@ DraggerLayout.PropTypes = {
     rowHeight: PropTypes.number,
     padding: PropTypes.number
 };
-
-var LayoutDemo = function (_React$Component2) {
-    _inherits(LayoutDemo, _React$Component2);
-
-    function LayoutDemo() {
-        _classCallCheck(this, LayoutDemo);
-
-        return _possibleConstructorReturn(this, (LayoutDemo.__proto__ || _Object$getPrototypeOf(LayoutDemo)).apply(this, arguments));
-    }
-
-    _createClass(LayoutDemo, [{
-        key: 'render',
-        value: function render() {
-            var layout = [{
-                GridX: 0, GridY: 0, w: 5, h: 5
-            }, {
-                GridX: 0, GridY: 0, w: 3, h: 3
-            }, {
-                GridX: 0, GridY: 0, w: 3, h: 3
-            }, {
-                GridX: 0, GridY: 0, w: 3, h: 3
-            }, {
-                GridX: 3, GridY: 8, w: 3, h: 3
-            }, {
-                GridX: 3, GridY: 8, w: 3, h: 3
-            }, {
-                GridX: 3, GridY: 8, w: 3, h: 3
-            }, {
-                GridX: 3, GridY: 8, w: 3, h: 3
-            }];
-            return React.createElement(
-                DraggerLayout,
-                { layout: layout, width: 800, col: 12 },
-                layout.map(function (el, index) {
-                    return React.createElement(
-                        'div',
-                        { key: index },
-                        index
-                    );
-                })
-            );
-        }
-    }]);
-
-    return LayoutDemo;
-}(React.Component);
-
-var _default = LayoutDemo;
-export default _default;
 ;
 
 var _temp = function () {
@@ -485,6 +496,8 @@ var _temp = function () {
         return;
     }
 
+    __REACT_HOT_LOADER__.register(correctItem, 'correctItem', 'app/src/App.js');
+
     __REACT_HOT_LOADER__.register(correctLayout, 'correctLayout', 'app/src/App.js');
 
     __REACT_HOT_LOADER__.register(layoutItemForkey, 'layoutItemForkey', 'app/src/App.js');
@@ -505,13 +518,15 @@ var _temp = function () {
 
     __REACT_HOT_LOADER__.register(layoutCheck, 'layoutCheck', 'app/src/App.js');
 
+    __REACT_HOT_LOADER__.register(quickSort, 'quickSort', 'app/src/App.js');
+
     __REACT_HOT_LOADER__.register(getMaxContainerHeight, 'getMaxContainerHeight', 'app/src/App.js');
 
-    __REACT_HOT_LOADER__.register(DraggerLayout, 'DraggerLayout', 'app/src/App.js');
+    __REACT_HOT_LOADER__.register(getDataSet, 'getDataSet', 'app/src/App.js');
 
-    __REACT_HOT_LOADER__.register(LayoutDemo, 'LayoutDemo', 'app/src/App.js');
+    __REACT_HOT_LOADER__.register(stringJoin, 'stringJoin', 'app/src/App.js');
 
-    __REACT_HOT_LOADER__.register(_default, 'default', 'app/src/App.js');
+    __REACT_HOT_LOADER__.register(DraggerLayout, 'DraggerLayout', 'app/src/App.js');
 }();
 
 ;

+ 43 - 9
build/Dragger.js

@@ -39,7 +39,10 @@ var Dragger = function (_React$Component) {
 
             /**已经移动的位移,单位是px */
             lastX: 0,
-            lastY: 0
+            lastY: 0,
+
+            /**堆叠的层级 */
+            zIndex: 1
         };
 
         _this.move = _this.move.bind(_this);
@@ -63,8 +66,15 @@ var Dragger = function (_React$Component) {
             *   elX表示的是原来已经有的位移
             */
 
-            var deltaX = event.clientX - this.state.originX + lastX;
-            var deltaY = event.clientY - this.state.originY + lastY;
+            var deltaX = void 0,
+                deltaY = void 0;
+            if (event.clientX) {
+                deltaX = event.clientX - this.state.originX + lastX;
+                deltaY = event.clientY - this.state.originY + lastY;
+            } else {
+                deltaX = event.touches[0].clientX - this.state.originX + lastX;
+                deltaY = event.touches[0].clientY - this.state.originY + lastY;
+            }
 
             var bounds = this.props.bounds;
 
@@ -138,7 +148,10 @@ var Dragger = function (_React$Component) {
              * 如果绑定在元素上,则鼠标离开元素,就不会再被监听了
              */
             doc.addEventListener('mousemove', this.move);
+            doc.addEventListener('touchmove', this.move);
+
             doc.addEventListener('mouseup', this.onDragEnd);
+            doc.addEventListener('touchend', this.onDragEnd);
 
             if (this.props.bounds === 'parent' && (
             /**为了让 这段代码不会重复执行 */
@@ -158,11 +171,22 @@ var Dragger = function (_React$Component) {
 
             this.props.onDragStart(this.state.x, this.state.y);
 
+            var originX = void 0,
+                originY = void 0;
+            if (event.clientX) {
+                originX = event.clientX;
+                originY = event.clientY;
+            } else {
+                originX = event.touches[0].clientX;
+                originY = event.touches[0].clientY;
+            }
+
             this.setState({
-                originX: event.clientX,
-                originY: event.clientY,
+                originX: originX,
+                originY: originY,
                 lastX: this.state.x,
-                lastY: this.state.y
+                lastY: this.state.y,
+                zIndex: 10
             });
         }
     }, {
@@ -173,8 +197,15 @@ var Dragger = function (_React$Component) {
             this.parent = null;
             this.self = null;
             doc.removeEventListener('mousemove', this.move);
+            doc.removeEventListener('touchmove', this.move);
+
+            doc.removeEventListener('touchend', this.onDragEnd);
             doc.removeEventListener('mouseup', this.onDragEnd);
 
+            this.setState({
+                zIndex: 1
+            });
+
             this.props.onDragEnd(event);
         }
     }, {
@@ -217,7 +248,8 @@ var Dragger = function (_React$Component) {
         value: function render() {
             var _state2 = this.state,
                 x = _state2.x,
-                y = _state2.y;
+                y = _state2.y,
+                zIndex = _state2.zIndex;
             var _props = this.props,
                 bounds = _props.bounds,
                 style = _props.style,
@@ -236,11 +268,13 @@ var Dragger = function (_React$Component) {
             return React.createElement(
                 'div',
                 _extends({ className: fixedClassName + 'WrapDragger',
-                    style: _extends({}, style, { touchAction: 'none!important', transform: 'translate(' + x + 'px,' + y + 'px)' }),
+                    style: _extends({}, style, { zIndex: zIndex, touchAction: 'none!important', transform: 'translate(' + x + 'px,' + y + 'px)' }),
                     onMouseDown: this.onDragStart.bind(this),
+                    onTouchStart: this.onDragStart.bind(this),
+                    onTouchEnd: this.onDragEnd.bind(this),
                     onMouseUp: this.onDragEnd.bind(this)
                 }, others),
-                React.cloneElement(React.Children.only(this.props.children), {})
+                React.Children.only(this.props.children)
             );
         }
     }]);

+ 27 - 13
build/GridItem.js

@@ -9,6 +9,14 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import Dragger from './Dragger';
 
+export var checkInContainer = function checkInContainer(GridX, GridY, col, w) {
+    /**防止元素出container */
+    if (GridX + w > col - 1) GridX = col - w; //右边界
+    if (GridX < 0) GridX = 0; //左边界
+    if (GridY < 0) GridY = 0; //上边界
+    return { GridX: GridX, GridY: GridY };
+};
+
 var GridItem = function (_React$Component) {
     _inherits(GridItem, _React$Component);
 
@@ -57,12 +65,8 @@ var GridItem = function (_React$Component) {
             var GridX = Math.round(x / containerWidth * col);
             var GridY = Math.round(y / (this.props.rowHeight + margin[1]));
 
-            /**防止元素出container */
-            if (GridX + w > col - 1) GridX = col - w; //右边界
-            if (GridX < 0) GridX = 0; //左边界
-            if (GridY < 0) GridY = 0; //上边界
-
-            return { GridX: GridX, GridY: GridY };
+            // /**防止元素出container */
+            return checkInContainer(GridX, GridY, col, w);
         }
 
         /**给予一个grid的位置,算出元素具体的在容器中位置在哪里,单位是px */
@@ -78,6 +82,7 @@ var GridItem = function (_React$Component) {
 
             var x = Math.round(GridX * this.calColWidth() + (GridX + 1) * margin[0]);
             var y = Math.round(GridY * this.props.rowHeight + margin[1] * (GridY + 1));
+
             return {
                 x: x,
                 y: y
@@ -109,6 +114,8 @@ var GridItem = function (_React$Component) {
                 h = _props5.h,
                 UniqueKey = _props5.UniqueKey;
 
+            if (this.props.static) return;
+
             var _calGridXY = this.calGridXY(x, y),
                 GridX = _calGridXY.GridX,
                 GridY = _calGridXY.GridY;
@@ -120,6 +127,8 @@ var GridItem = function (_React$Component) {
     }, {
         key: 'onDrag',
         value: function onDrag(event, x, y) {
+            if (this.props.static) return;
+
             var _calGridXY2 = this.calGridXY(x, y),
                 GridX = _calGridXY2.GridX,
                 GridY = _calGridXY2.GridY;
@@ -135,21 +144,24 @@ var GridItem = function (_React$Component) {
     }, {
         key: 'onDragEnd',
         value: function onDragEnd() {
+            if (this.props.static) return;
             if (this.props.onDragEnd) this.props.onDragEnd(this.props.UniqueKey);
         }
     }, {
         key: 'render',
         value: function render() {
-            var _calGridItemPosition = this.calGridItemPosition(this.props.GridX, this.props.GridY),
-                x = _calGridItemPosition.x,
-                y = _calGridItemPosition.y;
-
             var _props7 = this.props,
                 w = _props7.w,
                 h = _props7.h,
                 margin = _props7.margin,
                 style = _props7.style,
-                bounds = _props7.bounds;
+                bounds = _props7.bounds,
+                GridX = _props7.GridX,
+                GridY = _props7.GridY;
+
+            var _calGridItemPosition = this.calGridItemPosition(this.props.GridX, this.props.GridY),
+                x = _calGridItemPosition.x,
+                y = _calGridItemPosition.y;
 
             var _calWHtoPx = this.calWHtoPx(w, h),
                 wPx = _calWHtoPx.wPx,
@@ -170,7 +182,7 @@ var GridItem = function (_React$Component) {
                 },
                 React.createElement(
                     'div',
-                    null,
+                    { style: { width: wPx, height: hPx } },
                     React.Children.map(this.props.children, function (child) {
                         return child;
                     })
@@ -182,7 +194,7 @@ var GridItem = function (_React$Component) {
     return GridItem;
 }(React.Component);
 
-GridItem.PropTypes = {
+GridItem.propTypes = {
     /**外部容器属性 */
     col: PropTypes.number,
     containerWidth: PropTypes.number,
@@ -220,6 +232,8 @@ var _temp = function () {
         return;
     }
 
+    __REACT_HOT_LOADER__.register(checkInContainer, 'checkInContainer', 'app/src/GridItem.js');
+
     __REACT_HOT_LOADER__.register(GridItem, 'GridItem', 'app/src/GridItem.js');
 
     __REACT_HOT_LOADER__.register(_default, 'default', 'app/src/GridItem.js');

+ 62 - 0
build/NormalLayout/index.js

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

+ 59 - 0
build/SortedTable/index.js

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

+ 58 - 0
build/StaticHeader/index.js

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

+ 79 - 2
build/index.js

@@ -2,13 +2,90 @@
 
 import React from 'react';
 import ReactDOM from 'react-dom';
-import LayoutDemo from './App';
+import { LayoutDemo } from './NormalLayout';
+import { SortedTable } from './SortedTable';
+import { SortedTableWithStatic } from './StaticHeader';
 
 ReactDOM.render(React.createElement(
     'div',
     null,
-    React.createElement(LayoutDemo, null)
+    React.createElement(LayoutDemo, null),
+    React.createElement(SortedTable, null),
+    React.createElement(SortedTableWithStatic, null)
 ), document.getElementById('root'));
+
+document.body.addEventListener('touchmove', function (event) {
+    event.preventDefault();
+}, false);
+
+// const ThemeContext = React.createContext();
+
+// class ThemeProvider extends React.Component {
+//     state = {
+//         theme: "dark",
+//         color: "blue"
+//     };
+
+//     changeTheme = theme => {
+//         this.setState({
+//             theme
+//         });
+//     };
+
+//     changeColor = color => {
+//         this.setState({
+//             color
+//         });
+//     };
+
+//     render() {
+//         return (
+//             <ThemeContext.Provider
+//                 value={{
+//                     theme: this.state.theme,
+//                     color: this.state.color,
+//                     changeColor: this.changeColor
+//                 }}
+//             >
+//                 <button onClick={() => this.changeTheme("light")}>change theme</button>
+//                 {this.props.children}
+//             </ThemeContext.Provider>
+//         );
+//     }
+// }
+// const SubComponent = props => (
+//     <div>
+//         <div>{props.theme}</div>
+//         <button onClick={() => props.changeColor("red")}>change color</button>
+//         <div>{props.color}</div>
+//         <ThemeContext.Consumer>
+//             {context => (
+//                 <div>{context.theme}{context.color}{context.changeColor}
+//                 </div>
+//             )}
+//         </ThemeContext.Consumer>
+//     </div>
+// );
+// class App extends React.Component {
+//     render() {
+//         return (
+//             <ThemeProvider>
+//                 <ThemeContext.Consumer>
+//                     {context => (
+//                         <SubComponent
+//                             theme={context.theme}
+//                             color={context.color}
+//                             changeColor={context.changeColor}
+//                         />
+//                     )}
+//                 </ThemeContext.Consumer>
+//             </ThemeProvider>
+//         );
+//     }
+// }
+
+// ReactDOM.render(<App />, document.getElementById("root"));
+
 ;
 
 var _temp = function () {