Skip to content

Commit

Permalink
Vue 3: Use Teleport for the drag ghost item (#8258)
Browse files Browse the repository at this point in the history
* Use Teleport for the drag ghost item

* Add PR link to changelog

* Fix warnings

* Do not make OcTable a multi root component for now

... to avoid having to deal with class inheritance

Co-authored-by: Dominik Schmidt <[email protected]>
  • Loading branch information
JammingBen and dschmidt authored Jan 18, 2023
1 parent 5626822 commit 8a23b1a
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 39 deletions.
1 change: 1 addition & 0 deletions changelog/unreleased/change-update-vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ https://github.com/owncloud/web/pull/8213
https://github.com/owncloud/web/pull/8214
https://github.com/owncloud/web/pull/8221
https://github.com/owncloud/web/pull/8256
https://github.com/owncloud/web/pull/8258
5 changes: 0 additions & 5 deletions packages/design-system/src/components/OcAvatar/OcAvatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,6 @@ export default defineComponent({
return ''
}
},
mounted() {
if (!this.isImage) {
this.$emit('avatar-initials', this.userName, this.userInitial)
}
},
methods: {
onImgError() {
this.imgError = true
Expand Down
2 changes: 1 addition & 1 deletion packages/design-system/src/components/OcList/OcList.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<ul :ref="ref" class="oc-list oc-my-rm oc-mx-rm" :class="{ 'oc-list-raw': raw }">
<ul class="oc-list oc-my-rm oc-mx-rm" :class="{ 'oc-list-raw': raw }">
<slot />
</ul>
</template>
Expand Down
69 changes: 36 additions & 33 deletions packages/design-system/src/components/OcTable/OcTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,15 @@
</td>
</tr>
</tfoot>
<Teleport v-if="dragItem" to="body">
<oc-ghost-element
ref="ghostElement"
:preview-items="[dragItem, ...dragSelection]"
></oc-ghost-element>
</Teleport>
</table>
</template>
<script lang="ts">
import Vue from 'vue'
import OcThead from '../_OcTableHeader/_OcTableHeader.vue'
import OcTbody from '../_OcTableBody/_OcTableBody.vue'
import OcTr from '../_OcTableRow/_OcTableRow.vue'
Expand All @@ -91,7 +96,7 @@ import OcGhostElement from '../_OcGhostElement/_OcGhostElement.vue'
import OcButton from '../OcButton/OcButton.vue'
import SortMixin from '../../mixins/sort'
import { getSizeClass } from '../../utils/sizeClasses'
import { defineComponent } from 'vue'
import { defineComponent, ref } from 'vue'
import {
EVENT_THEAD_CLICKED,
Expand All @@ -115,7 +120,8 @@ export default defineComponent({
OcTr,
OcTh,
OcTd,
OcButton
OcButton,
OcGhostElement
},
mixins: [SortMixin],
props: {
Expand Down Expand Up @@ -252,16 +258,16 @@ export default defineComponent({
EVENT_TROW_MOUNTED,
EVENT_TROW_CONTEXTMENU
],
data() {
return {
constants: {
EVENT_THEAD_CLICKED,
EVENT_TROW_CLICKED,
EVENT_TROW_MOUNTED,
EVENT_TROW_CONTEXTMENU
},
ghostElement: null
setup() {
const ghostElement = ref()
const dragItem = ref()
const constants = {
EVENT_THEAD_CLICKED,
EVENT_TROW_CLICKED,
EVENT_TROW_MOUNTED,
EVENT_TROW_CONTEXTMENU
}
return { ghostElement, dragItem, constants }
},
computed: {
tableClasses() {
Expand All @@ -280,43 +286,40 @@ export default defineComponent({
fullColspan() {
return this.fields.length
},
dragSelection() {
const selection = [...this.selection]
selection.splice(
selection.findIndex((i) => i.id === this.dragItem.id),
1
)
return selection
}
},
methods: {
dragOver(event) {
event.preventDefault()
},
setGhostElement(item, event) {
const selection = [...this.selection]
selection.splice(
selection.findIndex((i) => i.id === item.id),
1
)
const GhostElementComponent = Vue.extend(OcGhostElement)
const ghostInstances = new GhostElementComponent({
propsData: {
previewItems: [item, ...selection]
}
})
ghostInstances.$mount()
this.ghostElement = document.body.appendChild(ghostInstances.$el)
this.ghostElement.ariaHidden = 'true'
this.ghostElement.style.left = '-99999px'
this.ghostElement.style.top = '-99999px'
event.dataTransfer.setDragImage(this.ghostElement, 0, 0)
async setDragItem(item, event) {
this.dragItem = item
await this.$nextTick()
this.ghostElement.$el.ariaHidden = 'true'
this.ghostElement.$el.style.left = '-99999px'
this.ghostElement.$el.style.top = '-99999px'
event.dataTransfer.setDragImage(this.ghostElement.$el, 0, 0)
event.dataTransfer.dropEffect = 'move'
event.dataTransfer.effectAllowed = 'move'
},
dragStart(item, event) {
async dragStart(item, event) {
if (!this.dragDrop) return
this.setGhostElement(item, event)
await this.setDragItem(item, event)
this.$emit(EVENT_ITEM_DRAGGED, item)
},
dropRowEvent(selector, event) {
if (!this.dragDrop) return
const hasFilePayload = (event.dataTransfer.types || []).some((e) => e === 'Files')
if (hasFilePayload) return
this.ghostElement.remove()
this.dragItem = null
const dropTarget = event.target
const dropTargetTr = dropTarget.closest('tr')
const dropItemId = dropTargetTr.dataset.itemId
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = {
extends: ['plugin:vue/recommended', 'plugin:prettier-vue/recommended'],
rules: {
'vue/multi-word-component-names': 'warn',
'vue/no-multiple-template-root': 'off',
'vue/no-v-text-v-html-on-component': 'warn'
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ exports[`SpacesList should render all spaces in a table 1`] = `
</td>
</tr>
</tfoot>
<!--v-if-->
</table>
</div>
`;

0 comments on commit 8a23b1a

Please sign in to comment.