chore: remove tab drag sortable runtime
This commit is contained in:
@@ -62,7 +62,6 @@
|
||||
"@vue-flow/minimap": "^1.5.4",
|
||||
"dompurify": "^3.3.1",
|
||||
"marked": "^17.0.1",
|
||||
"sortablejs": "catalog:",
|
||||
"tippy.js": "catalog:",
|
||||
"turndown": "^7.2.2"
|
||||
},
|
||||
|
||||
@@ -37,10 +37,6 @@
|
||||
"dependencies": {
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vueuse/core": "catalog:",
|
||||
"sortablejs": "catalog:",
|
||||
"vue": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/sortablejs": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
import type { SortableOptions } from 'sortablejs';
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { useSortable } from '../use-sortable';
|
||||
|
||||
describe('useSortable', () => {
|
||||
beforeEach(() => {
|
||||
vi.mock('sortablejs/modular/sortable.complete.esm.js', () => ({
|
||||
default: {
|
||||
create: vi.fn(),
|
||||
},
|
||||
}));
|
||||
});
|
||||
it('should call Sortable.create with the correct options', async () => {
|
||||
// Create a mock element
|
||||
const mockElement = document.createElement('div') as HTMLDivElement;
|
||||
|
||||
// Define custom options
|
||||
const customOptions: SortableOptions = {
|
||||
group: 'test-group',
|
||||
sort: false,
|
||||
};
|
||||
|
||||
// Use the useSortable function
|
||||
const { initializeSortable } = useSortable(mockElement, customOptions);
|
||||
|
||||
// Initialize sortable
|
||||
await initializeSortable();
|
||||
|
||||
// Import sortablejs to access the mocked create function
|
||||
const Sortable =
|
||||
await import('sortablejs/modular/sortable.complete.esm.js');
|
||||
|
||||
// Verify that Sortable.create was called with the correct parameters
|
||||
expect(Sortable.default.create).toHaveBeenCalledTimes(1);
|
||||
expect(Sortable.default.create).toHaveBeenCalledWith(
|
||||
mockElement,
|
||||
expect.objectContaining({
|
||||
animation: 300,
|
||||
delay: 400,
|
||||
delayOnTouchOnly: true,
|
||||
...customOptions,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -5,4 +5,3 @@ export * from './use-namespace';
|
||||
export * from './use-priority-value';
|
||||
export * from './use-scroll-lock';
|
||||
export * from './use-simple-locale';
|
||||
export * from './use-sortable';
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import type { SortableOptions } from 'sortablejs';
|
||||
import type Sortable from 'sortablejs';
|
||||
|
||||
function useSortable<T extends HTMLElement>(
|
||||
sortableContainer: T,
|
||||
options: SortableOptions = {},
|
||||
) {
|
||||
const initializeSortable = async () => {
|
||||
const Sortable = await import(
|
||||
// @ts-expect-error - This is a dynamic import
|
||||
'sortablejs/modular/sortable.complete.esm.js'
|
||||
);
|
||||
const sortable = Sortable?.default?.create?.(sortableContainer, {
|
||||
animation: 300,
|
||||
delay: 400,
|
||||
delayOnTouchOnly: true,
|
||||
...options,
|
||||
});
|
||||
return sortable as Sortable;
|
||||
};
|
||||
|
||||
return {
|
||||
initializeSortable,
|
||||
};
|
||||
}
|
||||
|
||||
export { useSortable };
|
||||
|
||||
export type { Sortable };
|
||||
@@ -6,7 +6,6 @@ import { ChevronLeft, ChevronRight } from '@vben-core/icons';
|
||||
import { VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { Tabs, TabsChrome } from './components';
|
||||
import { useTabsDrag } from './use-tabs-drag';
|
||||
import { useTabsViewScroll } from './use-tabs-view-scroll';
|
||||
|
||||
interface Props extends TabsProps {}
|
||||
@@ -43,8 +42,6 @@ function onWheel(e: WheelEvent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
useTabsDrag(props, emit);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
import type { Sortable } from '@vben-core/composables';
|
||||
import type { EmitType } from '@vben-core/typings';
|
||||
|
||||
import type { TabsProps } from './types';
|
||||
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import { useIsMobile, useSortable } from '@vben-core/composables';
|
||||
|
||||
// 可能会找到拖拽的子元素,这里需要确保拖拽的dom时tab元素
|
||||
function findParentElement(element: HTMLElement) {
|
||||
const parentCls = 'group';
|
||||
return element.classList.contains(parentCls)
|
||||
? element
|
||||
: element.closest(`.${parentCls}`);
|
||||
}
|
||||
|
||||
export function useTabsDrag(props: TabsProps, emit: EmitType) {
|
||||
const sortableInstance = ref<null | Sortable>(null);
|
||||
|
||||
async function initTabsSortable() {
|
||||
await nextTick();
|
||||
|
||||
const el = document.querySelectorAll(
|
||||
`.${props.contentClass}`,
|
||||
)?.[0] as HTMLElement;
|
||||
|
||||
if (!el) {
|
||||
console.warn('Element not found for sortable initialization');
|
||||
return;
|
||||
}
|
||||
|
||||
const resetElState = async () => {
|
||||
el.style.cursor = 'default';
|
||||
// el.classList.remove('dragging');
|
||||
el.querySelector('.draggable')?.classList.remove('dragging');
|
||||
};
|
||||
|
||||
const { initializeSortable } = useSortable(el, {
|
||||
filter: (_evt, target: HTMLElement) => {
|
||||
const parent = findParentElement(target);
|
||||
const draggable = parent?.classList.contains('draggable');
|
||||
return !draggable || !props.draggable;
|
||||
},
|
||||
onEnd(evt) {
|
||||
const { newIndex, oldIndex } = evt;
|
||||
// const fromElement = evt.item;
|
||||
const { srcElement } = (evt as any).originalEvent;
|
||||
|
||||
if (!srcElement) {
|
||||
resetElState();
|
||||
return;
|
||||
}
|
||||
|
||||
const srcParent = findParentElement(srcElement);
|
||||
|
||||
if (!srcParent) {
|
||||
resetElState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!srcParent.classList.contains('draggable')) {
|
||||
resetElState();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
oldIndex !== undefined &&
|
||||
newIndex !== undefined &&
|
||||
!Number.isNaN(oldIndex) &&
|
||||
!Number.isNaN(newIndex) &&
|
||||
oldIndex !== newIndex
|
||||
) {
|
||||
emit('sortTabs', oldIndex, newIndex);
|
||||
}
|
||||
resetElState();
|
||||
},
|
||||
onMove(evt) {
|
||||
const parent = findParentElement(evt.related);
|
||||
if (parent?.classList.contains('draggable') && props.draggable) {
|
||||
const isCurrentAffix = evt.dragged.classList.contains('affix-tab');
|
||||
const isRelatedAffix = evt.related.classList.contains('affix-tab');
|
||||
// 不允许在固定的tab和非固定的tab之间互相拖拽
|
||||
return isCurrentAffix === isRelatedAffix;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onStart: () => {
|
||||
el.style.cursor = 'grabbing';
|
||||
el.querySelector('.draggable')?.classList.add('dragging');
|
||||
// el.classList.add('dragging');
|
||||
},
|
||||
});
|
||||
|
||||
sortableInstance.value = await initializeSortable();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const { isMobile } = useIsMobile();
|
||||
|
||||
// 移动端下tab不需要拖拽
|
||||
if (isMobile.value) {
|
||||
return;
|
||||
}
|
||||
await nextTick();
|
||||
initTabsSortable();
|
||||
}
|
||||
|
||||
onMounted(init);
|
||||
|
||||
watch(
|
||||
() => props.styleType,
|
||||
() => {
|
||||
sortableInstance.value?.destroy();
|
||||
init();
|
||||
},
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
sortableInstance.value?.destroy();
|
||||
});
|
||||
}
|
||||
Generated
+2
-22
@@ -105,9 +105,6 @@ catalogs:
|
||||
'@types/qs':
|
||||
specifier: ^6.14.0
|
||||
version: 6.14.0
|
||||
'@types/sortablejs':
|
||||
specifier: ^1.15.8
|
||||
version: 1.15.9
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.35.1
|
||||
version: 8.48.0
|
||||
@@ -375,9 +372,6 @@ catalogs:
|
||||
sass:
|
||||
specifier: ^1.89.2
|
||||
version: 1.94.2
|
||||
sortablejs:
|
||||
specifier: 1.15.6
|
||||
version: 1.15.6
|
||||
stylelint:
|
||||
specifier: ^16.21.0
|
||||
version: 16.26.1
|
||||
@@ -532,9 +526,6 @@ importers:
|
||||
marked:
|
||||
specifier: ^17.0.1
|
||||
version: 17.0.1
|
||||
sortablejs:
|
||||
specifier: 'catalog:'
|
||||
version: 1.15.6
|
||||
tippy.js:
|
||||
specifier: 'catalog:'
|
||||
version: 6.3.7
|
||||
@@ -1196,16 +1187,9 @@ importers:
|
||||
'@vueuse/core':
|
||||
specifier: 'catalog:'
|
||||
version: 13.4.0(vue@3.5.25(typescript@5.9.3))
|
||||
sortablejs:
|
||||
specifier: 'catalog:'
|
||||
version: 1.15.6
|
||||
vue:
|
||||
specifier: ^3.5.17
|
||||
version: 3.5.25(typescript@5.9.3)
|
||||
devDependencies:
|
||||
'@types/sortablejs':
|
||||
specifier: 'catalog:'
|
||||
version: 1.15.9
|
||||
|
||||
packages/@core/preferences:
|
||||
dependencies:
|
||||
@@ -4334,9 +4318,6 @@ packages:
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
'@types/sortablejs@1.15.9':
|
||||
resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
|
||||
@@ -13775,8 +13756,6 @@ snapshots:
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/sortablejs@1.15.9': {}
|
||||
|
||||
'@types/trusted-types@2.0.7': {}
|
||||
|
||||
'@types/turndown@5.0.6': {}
|
||||
@@ -19318,7 +19297,8 @@ snapshots:
|
||||
|
||||
smob@1.5.0: {}
|
||||
|
||||
sortablejs@1.15.6: {}
|
||||
sortablejs@1.15.6:
|
||||
optional: true
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user