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