Browse Source
feat: tabbar support mouse wheel vertical (#5129)
* feat: tabbar support mouse wheel
* docs: add tabbar wheelable tips
* chore: resolve vitest test
pull/5130/head
Netfan
1 year ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with
54 additions and
5 deletions
-
packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap
-
packages/@core/preferences/src/config.ts
-
packages/@core/preferences/src/types.ts
-
packages/@core/ui-kit/tabs-ui/src/tabs-view.vue
-
packages/@core/ui-kit/tabs-ui/src/types.ts
-
packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts
-
packages/effects/layouts/src/basic/tabbar/tabbar.vue
-
packages/effects/layouts/src/widgets/preferences/blocks/layout/tabbar.vue
-
packages/effects/layouts/src/widgets/preferences/blocks/switch-item.vue
-
packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue
-
packages/locales/src/langs/en-US/preferences.json
-
packages/locales/src/langs/zh-CN/preferences.json
|
|
|
@ -83,6 +83,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj |
|
|
|
"showMaximize": true, |
|
|
|
"showMore": true, |
|
|
|
"styleType": "chrome", |
|
|
|
"wheelable": true, |
|
|
|
}, |
|
|
|
"theme": { |
|
|
|
"builtinType": "default", |
|
|
|
|
|
|
|
@ -83,6 +83,7 @@ const defaultPreferences: Preferences = { |
|
|
|
showMaximize: true, |
|
|
|
showMore: true, |
|
|
|
styleType: 'chrome', |
|
|
|
wheelable: true, |
|
|
|
}, |
|
|
|
theme: { |
|
|
|
builtinType: 'default', |
|
|
|
|
|
|
|
@ -173,6 +173,8 @@ interface TabbarPreferences { |
|
|
|
showMore: boolean; |
|
|
|
/** 标签页风格 */ |
|
|
|
styleType: TabsStyleType; |
|
|
|
/** 是否开启鼠标滚轮响应 */ |
|
|
|
wheelable: boolean; |
|
|
|
} |
|
|
|
|
|
|
|
interface ThemePreferences { |
|
|
|
|
|
|
|
@ -19,6 +19,7 @@ const props = withDefaults(defineProps<Props>(), { |
|
|
|
contentClass: 'vben-tabs-content', |
|
|
|
draggable: true, |
|
|
|
styleType: 'chrome', |
|
|
|
wheelable: true, |
|
|
|
}); |
|
|
|
|
|
|
|
const emit = defineEmits<TabsEmits>(); |
|
|
|
@ -27,6 +28,7 @@ const forward = useForwardPropsEmits(props, emit); |
|
|
|
|
|
|
|
const { |
|
|
|
handleScrollAt, |
|
|
|
handleWheel, |
|
|
|
scrollbarRef, |
|
|
|
scrollDirection, |
|
|
|
scrollIsAtLeft, |
|
|
|
@ -34,6 +36,14 @@ const { |
|
|
|
showScrollButton, |
|
|
|
} = useTabsViewScroll(props); |
|
|
|
|
|
|
|
function onWheel(e: WheelEvent) { |
|
|
|
if (props.wheelable) { |
|
|
|
handleWheel(e); |
|
|
|
e.stopPropagation(); |
|
|
|
e.preventDefault(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
useTabsDrag(props, emit); |
|
|
|
</script> |
|
|
|
|
|
|
|
@ -69,6 +79,7 @@ useTabsDrag(props, emit); |
|
|
|
shadow-left |
|
|
|
shadow-right |
|
|
|
@scroll-at="handleScrollAt" |
|
|
|
@wheel="onWheel" |
|
|
|
> |
|
|
|
<TabsChrome |
|
|
|
v-if="styleType === 'chrome'" |
|
|
|
|
|
|
|
@ -33,7 +33,6 @@ export interface TabsProps { |
|
|
|
* 仅限 tabs-chrome |
|
|
|
*/ |
|
|
|
maxWidth?: number; |
|
|
|
|
|
|
|
/** |
|
|
|
* @zh_CN tab最小宽度 |
|
|
|
* 仅限 tabs-chrome |
|
|
|
@ -44,15 +43,20 @@ export interface TabsProps { |
|
|
|
* @zh_CN 是否显示图标 |
|
|
|
*/ |
|
|
|
showIcon?: boolean; |
|
|
|
|
|
|
|
/** |
|
|
|
* @zh_CN 标签页风格 |
|
|
|
*/ |
|
|
|
styleType?: TabsStyleType; |
|
|
|
|
|
|
|
/** |
|
|
|
* @zh_CN 选项卡数据 |
|
|
|
*/ |
|
|
|
tabs?: TabDefinition[]; |
|
|
|
|
|
|
|
/** |
|
|
|
* @zh_CN 是否响应滚轮事件 |
|
|
|
*/ |
|
|
|
wheelable?: boolean; |
|
|
|
} |
|
|
|
|
|
|
|
export interface TabConfig extends TabDefinition { |
|
|
|
|
|
|
|
@ -142,6 +142,13 @@ export function useTabsViewScroll(props: TabsProps) { |
|
|
|
scrollIsAtRight.value = right; |
|
|
|
}, 100); |
|
|
|
|
|
|
|
function handleWheel({ deltaY }: WheelEvent) { |
|
|
|
scrollViewportEl.value?.scrollBy({ |
|
|
|
behavior: 'smooth', |
|
|
|
left: deltaY * 3, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
watch( |
|
|
|
() => props.active, |
|
|
|
async () => { |
|
|
|
@ -184,6 +191,7 @@ export function useTabsViewScroll(props: TabsProps) { |
|
|
|
|
|
|
|
return { |
|
|
|
handleScrollAt, |
|
|
|
handleWheel, |
|
|
|
initScrollbar, |
|
|
|
scrollbarRef, |
|
|
|
scrollDirection, |
|
|
|
|
|
|
|
@ -55,6 +55,7 @@ if (!preferences.tabbar.persist) { |
|
|
|
:show-icon="showIcon" |
|
|
|
:style-type="preferences.tabbar.styleType" |
|
|
|
:tabs="currentTabs" |
|
|
|
:wheelable="preferences.tabbar.wheelable" |
|
|
|
@close="handleClose" |
|
|
|
@sort-tabs="tabbarStore.sortTabs" |
|
|
|
@unpin="unpinTab" |
|
|
|
|
|
|
|
@ -18,6 +18,7 @@ const tabbarEnable = defineModel<boolean>('tabbarEnable'); |
|
|
|
const tabbarShowIcon = defineModel<boolean>('tabbarShowIcon'); |
|
|
|
const tabbarPersist = defineModel<boolean>('tabbarPersist'); |
|
|
|
const tabbarDraggable = defineModel<boolean>('tabbarDraggable'); |
|
|
|
const tabbarWheelable = defineModel<boolean>('tabbarWheelable'); |
|
|
|
const tabbarStyleType = defineModel<string>('tabbarStyleType'); |
|
|
|
const tabbarShowMore = defineModel<boolean>('tabbarShowMore'); |
|
|
|
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize'); |
|
|
|
@ -53,6 +54,13 @@ const styleItems = computed((): SelectOption[] => [ |
|
|
|
<SwitchItem v-model="tabbarDraggable" :disabled="!tabbarEnable"> |
|
|
|
{{ $t('preferences.tabbar.draggable') }} |
|
|
|
</SwitchItem> |
|
|
|
<SwitchItem |
|
|
|
v-model="tabbarWheelable" |
|
|
|
:disabled="!tabbarEnable" |
|
|
|
:tip="$t('preferences.tabbar.wheelableTip')" |
|
|
|
> |
|
|
|
{{ $t('preferences.tabbar.wheelable') }} |
|
|
|
</SwitchItem> |
|
|
|
<SwitchItem v-model="tabbarShowIcon" :disabled="!tabbarEnable"> |
|
|
|
{{ $t('preferences.tabbar.icon') }} |
|
|
|
</SwitchItem> |
|
|
|
|
|
|
|
@ -8,8 +8,9 @@ defineOptions({ |
|
|
|
name: 'PreferenceSwitchItem', |
|
|
|
}); |
|
|
|
|
|
|
|
withDefaults(defineProps<{ disabled?: boolean }>(), { |
|
|
|
withDefaults(defineProps<{ disabled?: boolean; tip?: string }>(), { |
|
|
|
disabled: false, |
|
|
|
tip: '', |
|
|
|
}); |
|
|
|
|
|
|
|
const checked = defineModel<boolean>(); |
|
|
|
@ -32,11 +33,17 @@ function handleClick() { |
|
|
|
<span class="flex items-center text-sm"> |
|
|
|
<slot></slot> |
|
|
|
|
|
|
|
<VbenTooltip v-if="slots.tip" side="bottom"> |
|
|
|
<VbenTooltip v-if="slots.tip || tip" side="bottom"> |
|
|
|
<template #trigger> |
|
|
|
<CircleHelp class="ml-1 size-3 cursor-help" /> |
|
|
|
</template> |
|
|
|
<slot name="tip"></slot> |
|
|
|
<slot name="tip"> |
|
|
|
<template v-if="tip"> |
|
|
|
<p v-for="(line, index) in tip.split('\n')" :key="index"> |
|
|
|
{{ line }} |
|
|
|
</p> |
|
|
|
</template> |
|
|
|
</slot> |
|
|
|
</VbenTooltip> |
|
|
|
</span> |
|
|
|
<span v-if="$slots.shortcut" class="ml-auto mr-2 text-xs opacity-60"> |
|
|
|
|
|
|
|
@ -105,6 +105,7 @@ const tabbarShowMore = defineModel<boolean>('tabbarShowMore'); |
|
|
|
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize'); |
|
|
|
const tabbarPersist = defineModel<boolean>('tabbarPersist'); |
|
|
|
const tabbarDraggable = defineModel<boolean>('tabbarDraggable'); |
|
|
|
const tabbarWheelable = defineModel<boolean>('tabbarWheelable'); |
|
|
|
const tabbarStyleType = defineModel<string>('tabbarStyleType'); |
|
|
|
|
|
|
|
const navigationStyleType = defineModel<NavigationStyleType>( |
|
|
|
@ -345,6 +346,7 @@ async function handleReset() { |
|
|
|
v-model:tabbar-show-maximize="tabbarShowMaximize" |
|
|
|
v-model:tabbar-show-more="tabbarShowMore" |
|
|
|
v-model:tabbar-style-type="tabbarStyleType" |
|
|
|
v-model:tabbar-wheelable="tabbarWheelable" |
|
|
|
/> |
|
|
|
</Block> |
|
|
|
<Block :title="$t('preferences.widget.title')"> |
|
|
|
|
|
|
|
@ -55,6 +55,8 @@ |
|
|
|
"showMaximize": "Show Maximize Button", |
|
|
|
"persist": "Persist Tabs", |
|
|
|
"draggable": "Enable Draggable Sort", |
|
|
|
"wheelable": "Support Mouse Wheel", |
|
|
|
"wheelableTip": "When enabled, the Tabbar area responds to vertical scrolling events of the scroll wheel.", |
|
|
|
"styleType": { |
|
|
|
"title": "Tabs Style", |
|
|
|
"chrome": "Chrome", |
|
|
|
|
|
|
|
@ -55,6 +55,8 @@ |
|
|
|
"showMaximize": "显示最大化按钮", |
|
|
|
"persist": "持久化标签页", |
|
|
|
"draggable": "启动拖拽排序", |
|
|
|
"wheelable": "启用纵向滚轮响应", |
|
|
|
"wheelableTip": "开启后,标签栏区域可以响应滚轮的纵向滚动事件。\n关闭时,只能响应系统的横向滚动事件(需要按下Shift再滚动滚轮)", |
|
|
|
"styleType": { |
|
|
|
"title": "标签页风格", |
|
|
|
"chrome": "谷歌", |
|
|
|
|