From ae055b20f11218e181771eaa807b1a9beb2e069c Mon Sep 17 00:00:00 2001 From: Vladimir Kharlampidi Date: Thu, 2 Dec 2021 16:22:55 +0300 Subject: [PATCH] feat(sortable): new `sortableMove` event to trigger during sortable item drag --- src/core/components/sortable/sortable.d.ts | 4 +++- src/core/components/sortable/sortable.js | 18 ++++++++++++++++-- src/react/components/list.jsx | 8 ++++++++ src/svelte/components/list.svelte | 6 ++++++ src/vue/components/list.vue | 7 +++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/core/components/sortable/sortable.d.ts b/src/core/components/sortable/sortable.d.ts index 36294dc6d3..befd2e470f 100644 --- a/src/core/components/sortable/sortable.d.ts +++ b/src/core/components/sortable/sortable.d.ts @@ -37,7 +37,9 @@ export namespace Sortable { /** Event will be triggered when sortable mode is disabled */ sortableDisable: (listEl: HTMLElement) => void; /** Event will be triggered after user release currently sorting element in new position. indexes is an object with from and to properties with from/to index numbers of sorted list item */ - sortableSort: (listEl: HTMLElement, indexes: SortIndexes) => void; + sortableSort: (itemEl: HTMLElement, indexes: SortIndexes, listEl: HTMLElement) => void; + /** Event will be triggered on every list item move during sorting */ + sortableMove: (itemEl: HTMLElement, listEl: HTMLElement) => void; } } diff --git a/src/core/components/sortable/sortable.js b/src/core/components/sortable/sortable.js index 923a55aa5d..991c16f8e2 100644 --- a/src/core/components/sortable/sortable.js +++ b/src/core/components/sortable/sortable.js @@ -124,23 +124,37 @@ const Sortable = { const currentElHeight = $currentEl.height(); const sortingElOffset = sortingElOffsetLocal + translate; + let currentTranslate; + const prevTranslate = $currentEl[0].f7Translate; + if ( sortingElOffset >= currentElOffset - currentElHeight / 2 && $sortingEl.index() < $currentEl.index() ) { - $currentEl.transform(`translate3d(0, ${-sortingElHeight}px,0)`); + currentTranslate = -sortingElHeight; + $currentEl.transform(`translate3d(0, ${currentTranslate}px,0)`); $insertAfterEl = $currentEl; $insertBeforeEl = undefined; } else if ( sortingElOffset <= currentElOffset + currentElHeight / 2 && $sortingEl.index() > $currentEl.index() ) { - $currentEl.transform(`translate3d(0, ${sortingElHeight}px,0)`); + currentTranslate = sortingElHeight; + $currentEl[0].f7Translate = currentTranslate; + $currentEl.transform(`translate3d(0, ${currentTranslate}px,0)`); $insertAfterEl = undefined; if (!$insertBeforeEl) $insertBeforeEl = $currentEl; } else { + currentTranslate = undefined; $currentEl.transform('translate3d(0, 0%,0)'); } + + if (prevTranslate !== currentTranslate) { + $currentEl.trigger('sortable:move'); + app.emit('sortableMove', $sortableContainer[0], $currentEl[0]); + } + + $currentEl[0].f7Translate = currentTranslate; }); } function handleTouchEnd() { diff --git a/src/react/components/list.jsx b/src/react/components/list.jsx index 779b7a76d6..0f1ee5d0a8 100644 --- a/src/react/components/list.jsx +++ b/src/react/components/list.jsx @@ -57,6 +57,7 @@ import { VirtualList } from 'framework7/types'; onSortableEnable? : (...args: any[]) => void onSortableDisable? : (...args: any[]) => void onSortableSort? : (sortData?: any) => void + onSortableMove? : (itemEl?: any) => void onTabShow? : (el?: HTMLElement) => void onTabHide? : (el?: HTMLElement) => void ref?: React.MutableRefObject<{el: HTMLElement | null; f7VirtualList: () => VirtualList.VirtualList}>; @@ -124,6 +125,11 @@ const List = forwardRef((props, ref) => { emit(props, 'sortableSort', sortData); }; + const onSortableMove = (el, listEl) => { + if (elRef.current !== listEl) return; + emit(props, 'sortableMove', el); + }; + useImperativeHandle(ref, () => ({ el: elRef.current, f7VirtualList: () => f7VirtualList.current, @@ -136,6 +142,7 @@ const List = forwardRef((props, ref) => { f7.on('sortableEnable', onSortableEnable); f7.on('sortableDisable', onSortableDisable); f7.on('sortableSort', onSortableSort); + f7.on('sortableMove', onSortableMove); }); }; @@ -144,6 +151,7 @@ const List = forwardRef((props, ref) => { f7.off('sortableEnable', onSortableEnable); f7.off('sortableDisable', onSortableDisable); f7.off('sortableSort', onSortableSort); + f7.off('sortableMove', onSortableMove); }; const onMount = () => { diff --git a/src/svelte/components/list.svelte b/src/svelte/components/list.svelte index bd9d6d82c9..b93b2d0c94 100644 --- a/src/svelte/components/list.svelte +++ b/src/svelte/components/list.svelte @@ -131,6 +131,10 @@ if (listEl !== el) return; emit('sortableSort', [sortData]); } + function onSortableMove(listItemEl, listEl) { + if (listEl !== el) return; + emit('sortableMove', [listEl]); + } useTab(() => el, emit); @@ -139,6 +143,7 @@ app.f7.on('sortableEnable', onSortableEnable); app.f7.on('sortableDisable', onSortableDisable); app.f7.on('sortableSort', onSortableSort); + app.f7.on('sortableMove', onSortableMove); if (!virtualList) return; const vlParams = virtualListParams || {}; @@ -178,6 +183,7 @@ app.f7.off('sortableEnable', onSortableEnable); app.f7.off('sortableDisable', onSortableDisable); app.f7.off('sortableSort', onSortableSort); + app.f7.off('sortableMove', onSortableMove); if (f7VirtualList && f7VirtualList.destroy) { f7VirtualList.destroy(); diff --git a/src/vue/components/list.vue b/src/vue/components/list.vue index 21d7f87066..99eb0448a6 100644 --- a/src/vue/components/list.vue +++ b/src/vue/components/list.vue @@ -62,6 +62,7 @@ export default { 'sortable:enable', 'sortable:disable', 'sortable:sort', + 'sortable:move', 'virtual:itembeforeinsert', 'virtual:beforeclear', 'virtual:itemsbeforeinsert', @@ -88,6 +89,10 @@ export default { if (elRef.value !== listEl) return; emit('sortable:sort', sortData); }; + const onSortableMove = (el, listEl) => { + if (elRef.value !== listEl) return; + emit(props, 'sortable:move', el); + }; useTab(elRef, emit); @@ -96,6 +101,7 @@ export default { f7.on('sortableEnable', onSortableEnable); f7.on('sortableDisable', onSortableDisable); f7.on('sortableSort', onSortableSort); + f7.on('sortableMove', onSortableMove); if (!props.virtualList) return; const vlParams = props.virtualListParams || {}; @@ -136,6 +142,7 @@ export default { f7.off('sortableEnable', onSortableEnable); f7.off('sortableDisable', onSortableDisable); f7.off('sortableSort', onSortableSort); + f7.off('sortableMove', onSortableMove); if (!(props.virtualList && f7VirtualList)) return; if (f7VirtualList.destroy) f7VirtualList.destroy();