From 93265cb3e0112701a583222130661f69435d2824 Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Wed, 25 Oct 2023 13:43:19 +0200
Subject: [PATCH] Create Example for isDraggedOver and containerDrag events

---
 example/src/App.vue             |  10 ++
 example/src/ExampleAOverlay.vue | 268 ++++++++++++++++++++++++++++++++
 2 files changed, 278 insertions(+)
 create mode 100644 example/src/ExampleAOverlay.vue

diff --git a/example/src/App.vue b/example/src/App.vue
index ce591a5..007744d 100644
--- a/example/src/App.vue
+++ b/example/src/App.vue
@@ -8,6 +8,7 @@ import Example6Disabled from "./Example6Disabled.vue";
 import Example7DisabledItems from "./Example7DisabledItems.vue";
 import Example8Responsive from "./Example8Responsive.vue";
 import Example9MultipleItemsY from "./Example9MultipleItemsY.vue";
+import ExampleAOverlay from "./ExampleAOverlay.vue";
 </script>
 
 <template>
@@ -96,6 +97,15 @@ import Example9MultipleItemsY from "./Example9MultipleItemsY.vue";
       width of every item has to be <kbd>1</kbd>)
     </p>
     <example9-multiple-items-y />
+
+    <h2>Example 10:</h2>
+    <p>
+      This example shows, how one can find out, if the user is dragging an item,
+      which item is being dragged and which grid is being dragged over. This is
+      an example for the proper <kbd>isDraggedOver</kbd> and the
+      <kbd>containerDragStart</kbd> and <kbd>containerDragEnd</kbd> events.
+    </p>
+    <example-a-overlay />
   </div>
 </template>
 
diff --git a/example/src/ExampleAOverlay.vue b/example/src/ExampleAOverlay.vue
new file mode 100644
index 0000000..14dfcef
--- /dev/null
+++ b/example/src/ExampleAOverlay.vue
@@ -0,0 +1,268 @@
+<script>
+function initialState() {
+  return {
+    items: [
+      {
+        key: "key1",
+        x: 1,
+        y: 5,
+        w: 1,
+        h: 1,
+        data: { name: "Cat", grid: false },
+      },
+      {
+        key: "key2",
+        x: 4,
+        y: 3,
+        w: 1,
+        h: 1,
+        data: { name: "Penguin", grid: false },
+      },
+      {
+        key: "key3",
+        x: 2,
+        y: 3,
+        w: 1,
+        h: 1,
+        data: { name: "Dog", grid: false },
+      },
+      {
+        key: "key4",
+        x: 5,
+        y: 4,
+        w: 1,
+        h: 1,
+        data: { name: "Chinchilla", grid: false },
+      },
+      {
+        key: "key5",
+        x: 5,
+        y: 1,
+        w: 1,
+        h: 1,
+        data: { name: "Iguana", grid: false },
+      },
+      {
+        key: "key6",
+        x: 3,
+        y: 4,
+        w: 1,
+        h: 1,
+        data: { name: "Axolotl", grid: true },
+        disabled: true,
+      },
+    ],
+    overlays: [
+      { key: "overlay1", x: 2, y: 2, animal: "Dog" },
+      { key: "overlay2", x: 3, y: 5, animal: "Iguana" },
+      { key: "overlay3", x: 4, y: 2, animal: "Chinchilla" },
+      { key: "overlay4", x: 2, y: 4, animal: "Penguin" },
+      { key: "overlay5", x: 4, y: 4, animal: "Cat" },
+    ],
+    dragged: {
+      key1: false,
+      key2: false,
+      key3: false,
+      key4: false,
+      key5: false,
+      key6: false,
+    },
+    showOverlayOnlyOnDragover: false,
+    showAllHighlights: false,
+  };
+}
+
+export default {
+  name: "ExampleAOverlay",
+  data() {
+    return initialState();
+  },
+  methods: {
+    handleItemChanged(element, gridId) {
+      if (gridId === "second-grid" && element.originGridId === "second-grid") {
+        // Disable movement inside the second grid
+        return;
+      }
+
+      let overlay = this.overlays.find((o) => o.animal === element.data.name);
+      this.items.map((item) => {
+        if (item.key === element.key) {
+          item.data.grid = gridId === "ov-grid";
+          item.x = element.x;
+          item.y = element.y;
+          item.disabled =
+            overlay && overlay.x === element.x && overlay.y === element.y;
+        }
+        return item;
+      });
+      if (overlay && overlay.x === element.x && overlay.y === element.y) {
+        this.overlays = this.overlays.filter((o) => o.key !== overlay.key);
+      }
+    },
+    reset() {
+      Object.assign(this.$data, initialState());
+    },
+    handleContainerDrag(element, type) {
+      this.dragged[element.key] = type === "start";
+    },
+  },
+  computed: {
+    gridOneItems() {
+      return this.items.filter((item) => item.data.grid);
+    },
+    gridTwoItems() {
+      return this.items
+        .filter((item) => !item.data.grid)
+        .map((item) => ({
+          ...item,
+          x: () => 0,
+          y: () => 0,
+          disabled: false,
+        }));
+    },
+    computedOverlays() {
+      if (this.showAllHighlights) {
+        return Object.values(this.dragged).some((obj) => !!obj)
+          ? this.overlays
+          : [];
+      }
+      return this.overlays.filter(
+        (o) =>
+          this.dragged[
+            ((a) => (a ? a.key : a))(
+              // Get the key of the dragged item or null
+              this.items.find((item) => item.data.name === o.animal),
+            )
+          ],
+      );
+    },
+  },
+};
+</script>
+
+<template>
+  <div>
+    <drag-grid
+      :value="gridOneItems"
+      :cols="5"
+      :rows="5"
+      id="ov-grid"
+      context="animals"
+      grid-id="ov-grid"
+      @itemChanged="handleItemChanged($event, 'ov-grid')"
+      @containerDragStart="handleContainerDrag($event, 'start')"
+      @containerDragEnd="handleContainerDrag($event, 'end')"
+    >
+      <template #item="{ rawItem }">
+        <div :class="{ container: true, disabled: rawItem.disabled }">
+          <span>{{ rawItem.data.name }}</span>
+        </div>
+      </template>
+      <template #default="{ isDraggedOver }">
+        <div
+          class="container goal"
+          v-for="goal in computedOverlays"
+          v-show="isDraggedOver || !showOverlayOnlyOnDragover"
+          :key="goal.key"
+          :style="{
+            gridColumn: goal.x + ' / span 1',
+            gridRow: goal.y + ' / span 1',
+          }"
+        >
+          {{ goal.animal }} here!
+        </div>
+      </template>
+    </drag-grid>
+    <drag-grid
+      :value="gridTwoItems"
+      :cols="1"
+      :rows="5"
+      id="second-grid"
+      context="animals"
+      grid-id="second-grid"
+      no-highlight
+      @itemChanged="handleItemChanged($event, 'second-grid')"
+      @containerDragStart="handleContainerDrag($event, 'start')"
+      @containerDragEnd="handleContainerDrag($event, 'end')"
+    >
+      <template #item="{ rawItem }">
+        <div :class="{ container: true, disabled: rawItem.disabled }">
+          <span>{{ rawItem.data.name }}</span>
+        </div>
+      </template>
+    </drag-grid>
+    <span>
+      <button @click="reset">Reset</button><br />
+      <button @click="showOverlayOnlyOnDragover = !showOverlayOnlyOnDragover">
+        Show overlay
+        {{ showOverlayOnlyOnDragover ? "always" : "only on dragover" }}</button
+      ><br />
+      <button @click="showAllHighlights = !showAllHighlights">
+        {{
+          showAllHighlights
+            ? "Only show overlay for dragged item"
+            : "Show overlay for all items"
+        }}
+      </button>
+    </span>
+  </div>
+</template>
+
+<style scoped>
+#ov-grid,
+#second-grid {
+  max-width: 600px;
+  border-radius: 1em;
+  border: 0.2em solid #e0e0e0;
+  box-shadow: 0.2em 0.2em 0 0.1em #bdc3c7;
+  padding: 0.3em 0.4em 0.4em 0.3em;
+}
+
+#second-grid {
+  width: fit-content;
+  height: 100%;
+}
+
+div {
+  display: flex;
+  flex-direction: row;
+  gap: 1em;
+  align-items: stretch;
+}
+
+.container {
+  background: #3498db;
+  color: #ecf0f1;
+  width: 100%;
+  height: 100%;
+  user-select: none;
+  text-align: center;
+  border-radius: 0.6em;
+  box-shadow: #2980b9 0.1em 0.1em 0 0.1em;
+  min-height: 3rem;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.container.disabled {
+  background: #bdc3c7;
+  box-shadow: #95a5a6 0.1em 0.1em 0 0.1em;
+}
+
+.container.goal {
+  background: #2ecc71;
+  box-shadow: #27ae60 0.1em 0.1em 0 0.1em;
+}
+
+button {
+  margin-top: 1em;
+  padding: 0.5em 1em;
+  border-radius: 0.5em;
+  border: 0.2em solid #e0e0e0;
+  background: #ecf0f1;
+  color: #3498db;
+  font-weight: bold;
+  cursor: pointer;
+}
+</style>
-- 
GitLab