From 2ec40ff91ee24330b263eae901527e80d46cc9ea Mon Sep 17 00:00:00 2001
From: yugasun <yuga_sun@163.com>
Date: Mon, 23 Apr 2018 15:13:44 +0800
Subject: [PATCH] feat: add drag kanban component demo

---
 package.json                             |   1 +
 src/lang/en.js                           |   1 +
 src/lang/zh.js                           |   1 +
 src/router/index.js                      |   3 +-
 src/views/components-demo/dragKanban.vue | 210 +++++++++++++++++++++++
 5 files changed, 215 insertions(+), 1 deletion(-)
 create mode 100644 src/views/components-demo/dragKanban.vue

diff --git a/package.json b/package.json
index 96742a86..c19bc0cf 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
     "jsonlint": "1.6.2",
     "jszip": "3.1.5",
     "mockjs": "1.0.1-beta3",
+    "muuri": "^0.5.4",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "screenfull": "3.3.2",
diff --git a/src/lang/en.js b/src/lang/en.js
index c08c88ef..fc0405c9 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -19,6 +19,7 @@ export default {
     componentMixin: 'Mixin',
     backToTop: 'BackToTop',
     dragDialog: 'Drag Dialog',
+    dragKanban: 'Drag Kanban',
     charts: 'Charts',
     keyboardChart: 'Keyboard Chart',
     lineChart: 'Line Chart',
diff --git a/src/lang/zh.js b/src/lang/zh.js
index a4cc93d4..28f9aab8 100644
--- a/src/lang/zh.js
+++ b/src/lang/zh.js
@@ -19,6 +19,7 @@ export default {
     componentMixin: '小组件',
     backToTop: '返回顶部',
     dragDialog: '拖拽 Dialog',
+    dragKanban: 'Drag Kanban',
     charts: '图表',
     keyboardChart: '键盘图表',
     lineChart: '折线图',
diff --git a/src/router/index.js b/src/router/index.js
index a5d704ef..5e1c80f1 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -112,7 +112,8 @@ export const asyncRouterMap = [
       { path: 'count-to', component: _import('components-demo/countTo'), name: 'countTo-demo', meta: { title: 'countTo' }},
       { path: 'mixin', component: _import('components-demo/mixin'), name: 'componentMixin-demo', meta: { title: 'componentMixin' }},
       { path: 'back-to-top', component: _import('components-demo/backToTop'), name: 'backToTop-demo', meta: { title: 'backToTop' }},
-      { path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }}
+      { path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }},
+      { path: 'drag-grid', component: _import('components-demo/dragKanban'), name: 'dragKanban-demo', meta: { title: 'dragKanban' }}
     ]
   },
 
diff --git a/src/views/components-demo/dragKanban.vue b/src/views/components-demo/dragKanban.vue
new file mode 100644
index 00000000..b28751fe
--- /dev/null
+++ b/src/views/components-demo/dragKanban.vue
@@ -0,0 +1,210 @@
+<template>
+  <div class="board">
+    <div class="board-column todo">
+      <div class="board-column-header">To do</div>
+      <div class="board-column-content-wrapper">
+        <div class="board-column-content">
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>1</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>2</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>3</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>4</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>5</div></div>
+        </div>
+      </div>
+    </div>
+    <div class="board-column working">
+      <div class="board-column-header">Working</div>
+      <div class="board-column-content-wrapper">
+        <div class="board-column-content">
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>6</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>7</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>8</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>9</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>10</div></div>
+        </div>
+      </div>
+    </div>
+    <div class="board-column done">
+      <div class="board-column-header">Done</div>
+      <div class="board-column-content-wrapper">
+        <div class="board-column-content">
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>11</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>12</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>13</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>14</div></div>
+          <div class="board-item"><div class="board-item-content"><span>Item #</span>15</div></div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+// inspire by https://codepen.io/niklasramo/pen/BrYaOp
+
+import Muuri from 'muuri'
+
+export default {
+  name: 'dragKanban-demo',
+  data() {
+    return {
+      columnGrids: [],
+      boardGrid: null
+    }
+  },
+  mounted() {
+    const itemContainers = [].slice.call(
+      document.querySelectorAll('.board-column-content')
+    )
+    const me = this
+
+    // Define the column grids so we can drag those
+    // items around.
+    itemContainers.forEach(function(container) {
+      // Instantiate column grid.
+      var grid = new Muuri(container, {
+        items: '.board-item',
+        layoutDuration: 400,
+        layoutEasing: 'ease',
+        dragEnabled: true,
+        dragSort: function() {
+          return me.columnGrids
+        },
+        dragSortInterval: 0,
+        dragContainer: document.body,
+        dragReleaseDuration: 400,
+        dragReleaseEasing: 'ease'
+      })
+        .on('dragStart', function(item) {
+          // Let's set fixed widht/height to the dragged item
+          // so that it does not stretch unwillingly when
+          // it's appended to the document body for the
+          // duration of the drag.
+          item.getElement().style.width = item.getWidth() + 'px'
+          item.getElement().style.height = item.getHeight() + 'px'
+        })
+        .on('dragReleaseEnd', function(item) {
+          // Let's remove the fixed width/height from the
+          // dragged item now that it is back in a grid
+          // column and can freely adjust to it's
+          // surroundings.
+          item.getElement().style.width = ''
+          item.getElement().style.height = ''
+          // Just in case, let's refresh the dimensions of all items
+          // in case dragging the item caused some other items to
+          // be different size.
+          me.columnGrids.forEach(function(grid) {
+            grid.refreshItems()
+          })
+        })
+        .on('layoutStart', function() {
+          // Let's keep the board grid up to date with the
+          // dimensions changes of column grids.
+          me.boardGrid.refreshItems().layout()
+        })
+
+      // Add the column grid reference to the column grids
+      // array, so we can access it later on.
+      me.columnGrids.push(grid)
+    })
+
+    // Instantiate the board grid so we can drag those
+    // columns around.
+    me.boardGrid = new Muuri('.board', {
+      layoutDuration: 400,
+      layoutEasing: 'ease',
+      dragEnabled: true,
+      dragSortInterval: 0,
+      dragStartPredicate: {
+        handle: '.board-column-header'
+      },
+      dragReleaseDuration: 400,
+      dragReleaseEasing: 'ease'
+    })
+  }
+}
+</script>
+
+<style scoped>
+.board {
+  position: relative;
+  margin-left: 1%;
+  margin-top: 20px;
+}
+.board-column {
+  position: absolute;
+  left: 0;
+  right: 0;
+  width: 30%;
+  margin: 0 1.5%;
+  background: #f0f0f0;
+  border-radius: 3px;
+  z-index: 1;
+}
+.board-column.muuri-item-releasing {
+  z-index: 2;
+}
+.board-column.muuri-item-dragging {
+  z-index: 3;
+  cursor: move;
+}
+.board-column-header {
+  position: relative;
+  height: 50px;
+  line-height: 50px;
+  overflow: hidden;
+  padding: 0 20px;
+  text-align: center;
+  background: #333;
+  color: #fff;
+  border-radius: 3px 3px 0 0;
+}
+.board-column.todo .board-column-header {
+  background: #4a9ff9;
+}
+.board-column.working .board-column-header {
+  background: #f9944a;
+}
+.board-column.done .board-column-header {
+  background: #2ac06d;
+}
+/* This is the secret sauce,
+   always use a wrapper for setting
+   the "overflow: scroll/auto" */
+.board-column-content-wrapper {
+  position: relative;
+  max-height: 400px;
+  overflow-y: auto;
+}
+/* Never ever set "overflow: auto/scroll"
+   to the muuri element, stuff will break */
+.board-column-content {
+  position: relative;
+  border: 10px solid transparent;
+  min-height: 95px;
+}
+.board-item {
+  position: absolute;
+  width: 100%;
+  margin: 5px 0;
+}
+.board-item.muuri-item-releasing {
+  z-index: 9998;
+}
+.board-item.muuri-item-dragging {
+  z-index: 9999;
+  cursor: move;
+}
+.board-item.muuri-item-hidden {
+  z-index: 0;
+}
+.board-item-content {
+  position: relative;
+  padding: 20px;
+  background: #fff;
+  border-radius: 4px;
+  font-size: 17px;
+  cursor: pointer;
+  -webkit-box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
+  box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
+}
+</style>