Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Add Ghost Element for Drag & Drop move #1754

Merged
merged 6 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-add-drag-drop-ghost
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Add Ghost Element for Drag & Drop

We've added a custom ghost element for the drag&drop functionality in the OcTableFiles to
better visualize the action to the user.

https://github.com/owncloud/web/issues/5788
https://github.com/owncloud/owncloud-design-system/pull/1754
57 changes: 57 additions & 0 deletions src/components/molecules/OcTable/GhostElement/GhostElement.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<div id="ghost-element" class="ghost-element">
<oc-icon :name="firstPreviewIcon" size="large" />
<span class="badge">{{ itemCount }}</span>
</div>
</template>

<script>
/**
* Please head to the OcTableFiles component (https://owncloud.design/#/oC%20Components/OcTableFiles) for a demo of the Ghost Element.
*/
export default {
lookacat marked this conversation as resolved.
Show resolved Hide resolved
name: "GhostElement",
props: {
previewItems: {
type: Array,
required: true,
},
},
computed: {
firstPreviewIcon() {
const icon = this.previewItems[0].icon
return icon ? icon : "file"
},
itemCount() {
return this.previewItems.length
},
},
}
</script>

<style lang="scss">
.ghost-element {
background-color: transparent;
padding-top: 4px;
padding-left: 5px;
z-index: var(--oc-z-index-modal);
position: absolute;
.badge {
position: absolute;
top: -2px;
right: -8px;
padding: 4px;
line-height: 10px;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
min-width: 10px;
height: 10px;
text-align: center;

font-size: 12px;
background: red;
color: white;
}
}
</style>
39 changes: 36 additions & 3 deletions src/components/molecules/OcTable/OcTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@
$emit(constants.EVENT_TROW_CONTEXTMENU, $refs[`row-${trIndex}`][0], $event, item)
"
@hook:mounted="$emit(constants.EVENT_TROW_MOUNTED, item, $refs[`row-${trIndex}`][0])"
@dragstart.native="dragStart(item)"
@dragstart.native="dragStart(item, $event)"
@drop.native="dropRowEvent(item.id, $event)"
@dragenter.native.prevent="dropRowStyling(item.id, false, $event)"
@dragleave.native.prevent="dropRowStyling(item.id, true, $event)"
@mouseleave="dropRowStyling(item.id, true, $event)"
@dragover.native.prevent
@dragover.native="dragOver($event)"
>
<oc-td
v-for="(field, tdIndex) in fields"
Expand Down Expand Up @@ -79,6 +79,7 @@
</table>
</template>
<script>
import Vue from "vue"
import OcThead from "../../atoms/_OcTableHeader/_OcTableHeader.vue"
import OcTbody from "../../atoms/_OcTableBody/_OcTableBody.vue"
import OcTr from "../../atoms/_OcTableRow/_OcTableRow"
Expand All @@ -87,6 +88,7 @@ import OcTd from "../../atoms/_OcTableCellData/_OcTableCellData.vue"
import OcButton from "../../atoms/OcButton/OcButton.vue"
import SortMixin from "../../../mixins/sort"
import { getSizeClass } from "../../../utils/sizeClasses"
import GhostElement from "./GhostElement/GhostElement.vue"

import {
EVENT_THEAD_CLICKED,
Expand Down Expand Up @@ -214,6 +216,11 @@ export default {
required: false,
default: false,
},
selection: {
type: Array,
required: false,
default: () => [],
},
},
data() {
return {
Expand Down Expand Up @@ -248,8 +255,34 @@ export default {
},
},
methods: {
dragStart(file) {
dragOver(event) {
event.preventDefault()
},
setGhostElement(file, event) {
const selection = [...this.selection]
selection.splice(
selection.findIndex(function (i) {
return i.id === file.id
}),
1
)
const GhostElementComponent = Vue.extend(GhostElement)
const ghostInstances = new GhostElementComponent({
propsData: {
previewItems: [file, ...selection],
},
})
ghostInstances.$mount()
const ghost = document.body.appendChild(ghostInstances.$el)
lookacat marked this conversation as resolved.
Show resolved Hide resolved
ghost.style.left = "-99999px"
ghost.style.top = "-99999px"
event.dataTransfer.setDragImage(ghost, 0, 0)
event.dataTransfer.dropEffect = "move"
event.dataTransfer.effectAllowed = "move"
},
dragStart(file, event) {
if (!this.dragDrop) return
this.setGhostElement(file, event)
this.$emit(EVENT_FILE_DRAGGED, file)
},
dropRowEvent(id, event) {
Expand Down
1 change: 1 addition & 0 deletions src/components/templates/OcTableFiles/OcTableFiles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:header-position="headerPosition"
:drag-drop="dragDrop"
:hover="hover"
:selection="selection"
@highlight="fileClicked"
@rowMounted="rowMounted"
@contextmenuClicked="showContextMenu"
Expand Down