Skip to content

Commit 7fbf7b1

Browse files
authored
feat: tabbar support mouse wheel vertical (#5129)
* feat: tabbar support mouse wheel * docs: add tabbar wheelable tips * chore: resolve vitest test
1 parent be208fe commit 7fbf7b1

File tree

12 files changed

+54
-5
lines changed

12 files changed

+54
-5
lines changed

packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
8383
"showMaximize": true,
8484
"showMore": true,
8585
"styleType": "chrome",
86+
"wheelable": true,
8687
},
8788
"theme": {
8889
"builtinType": "default",

packages/@core/preferences/src/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const defaultPreferences: Preferences = {
8383
showMaximize: true,
8484
showMore: true,
8585
styleType: 'chrome',
86+
wheelable: true,
8687
},
8788
theme: {
8889
builtinType: 'default',

packages/@core/preferences/src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ interface TabbarPreferences {
173173
showMore: boolean;
174174
/** 标签页风格 */
175175
styleType: TabsStyleType;
176+
/** 是否开启鼠标滚轮响应 */
177+
wheelable: boolean;
176178
}
177179

178180
interface ThemePreferences {

packages/@core/ui-kit/tabs-ui/src/tabs-view.vue

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const props = withDefaults(defineProps<Props>(), {
1919
contentClass: 'vben-tabs-content',
2020
draggable: true,
2121
styleType: 'chrome',
22+
wheelable: true,
2223
});
2324
2425
const emit = defineEmits<TabsEmits>();
@@ -27,13 +28,22 @@ const forward = useForwardPropsEmits(props, emit);
2728
2829
const {
2930
handleScrollAt,
31+
handleWheel,
3032
scrollbarRef,
3133
scrollDirection,
3234
scrollIsAtLeft,
3335
scrollIsAtRight,
3436
showScrollButton,
3537
} = useTabsViewScroll(props);
3638
39+
function onWheel(e: WheelEvent) {
40+
if (props.wheelable) {
41+
handleWheel(e);
42+
e.stopPropagation();
43+
e.preventDefault();
44+
}
45+
}
46+
3747
useTabsDrag(props, emit);
3848
</script>
3949

@@ -69,6 +79,7 @@ useTabsDrag(props, emit);
6979
shadow-left
7080
shadow-right
7181
@scroll-at="handleScrollAt"
82+
@wheel="onWheel"
7283
>
7384
<TabsChrome
7485
v-if="styleType === 'chrome'"

packages/@core/ui-kit/tabs-ui/src/types.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export interface TabsProps {
3333
* 仅限 tabs-chrome
3434
*/
3535
maxWidth?: number;
36-
3736
/**
3837
* @zh_CN tab最小宽度
3938
* 仅限 tabs-chrome
@@ -44,15 +43,20 @@ export interface TabsProps {
4443
* @zh_CN 是否显示图标
4544
*/
4645
showIcon?: boolean;
46+
4747
/**
4848
* @zh_CN 标签页风格
4949
*/
5050
styleType?: TabsStyleType;
51-
5251
/**
5352
* @zh_CN 选项卡数据
5453
*/
5554
tabs?: TabDefinition[];
55+
56+
/**
57+
* @zh_CN 是否响应滚轮事件
58+
*/
59+
wheelable?: boolean;
5660
}
5761

5862
export interface TabConfig extends TabDefinition {

packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts

+8
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ export function useTabsViewScroll(props: TabsProps) {
142142
scrollIsAtRight.value = right;
143143
}, 100);
144144

145+
function handleWheel({ deltaY }: WheelEvent) {
146+
scrollViewportEl.value?.scrollBy({
147+
behavior: 'smooth',
148+
left: deltaY * 3,
149+
});
150+
}
151+
145152
watch(
146153
() => props.active,
147154
async () => {
@@ -184,6 +191,7 @@ export function useTabsViewScroll(props: TabsProps) {
184191

185192
return {
186193
handleScrollAt,
194+
handleWheel,
187195
initScrollbar,
188196
scrollbarRef,
189197
scrollDirection,

packages/effects/layouts/src/basic/tabbar/tabbar.vue

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ if (!preferences.tabbar.persist) {
5555
:show-icon="showIcon"
5656
:style-type="preferences.tabbar.styleType"
5757
:tabs="currentTabs"
58+
:wheelable="preferences.tabbar.wheelable"
5859
@close="handleClose"
5960
@sort-tabs="tabbarStore.sortTabs"
6061
@unpin="unpinTab"

packages/effects/layouts/src/widgets/preferences/blocks/layout/tabbar.vue

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const tabbarEnable = defineModel<boolean>('tabbarEnable');
1818
const tabbarShowIcon = defineModel<boolean>('tabbarShowIcon');
1919
const tabbarPersist = defineModel<boolean>('tabbarPersist');
2020
const tabbarDraggable = defineModel<boolean>('tabbarDraggable');
21+
const tabbarWheelable = defineModel<boolean>('tabbarWheelable');
2122
const tabbarStyleType = defineModel<string>('tabbarStyleType');
2223
const tabbarShowMore = defineModel<boolean>('tabbarShowMore');
2324
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize');
@@ -53,6 +54,13 @@ const styleItems = computed((): SelectOption[] => [
5354
<SwitchItem v-model="tabbarDraggable" :disabled="!tabbarEnable">
5455
{{ $t('preferences.tabbar.draggable') }}
5556
</SwitchItem>
57+
<SwitchItem
58+
v-model="tabbarWheelable"
59+
:disabled="!tabbarEnable"
60+
:tip="$t('preferences.tabbar.wheelableTip')"
61+
>
62+
{{ $t('preferences.tabbar.wheelable') }}
63+
</SwitchItem>
5664
<SwitchItem v-model="tabbarShowIcon" :disabled="!tabbarEnable">
5765
{{ $t('preferences.tabbar.icon') }}
5866
</SwitchItem>

packages/effects/layouts/src/widgets/preferences/blocks/switch-item.vue

+10-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ defineOptions({
88
name: 'PreferenceSwitchItem',
99
});
1010
11-
withDefaults(defineProps<{ disabled?: boolean }>(), {
11+
withDefaults(defineProps<{ disabled?: boolean; tip?: string }>(), {
1212
disabled: false,
13+
tip: '',
1314
});
1415
1516
const checked = defineModel<boolean>();
@@ -32,11 +33,17 @@ function handleClick() {
3233
<span class="flex items-center text-sm">
3334
<slot></slot>
3435

35-
<VbenTooltip v-if="slots.tip" side="bottom">
36+
<VbenTooltip v-if="slots.tip || tip" side="bottom">
3637
<template #trigger>
3738
<CircleHelp class="ml-1 size-3 cursor-help" />
3839
</template>
39-
<slot name="tip"></slot>
40+
<slot name="tip">
41+
<template v-if="tip">
42+
<p v-for="(line, index) in tip.split('\n')" :key="index">
43+
{{ line }}
44+
</p>
45+
</template>
46+
</slot>
4047
</VbenTooltip>
4148
</span>
4249
<span v-if="$slots.shortcut" class="ml-auto mr-2 text-xs opacity-60">

packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue

+2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ const tabbarShowMore = defineModel<boolean>('tabbarShowMore');
105105
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize');
106106
const tabbarPersist = defineModel<boolean>('tabbarPersist');
107107
const tabbarDraggable = defineModel<boolean>('tabbarDraggable');
108+
const tabbarWheelable = defineModel<boolean>('tabbarWheelable');
108109
const tabbarStyleType = defineModel<string>('tabbarStyleType');
109110
110111
const navigationStyleType = defineModel<NavigationStyleType>(
@@ -345,6 +346,7 @@ async function handleReset() {
345346
v-model:tabbar-show-maximize="tabbarShowMaximize"
346347
v-model:tabbar-show-more="tabbarShowMore"
347348
v-model:tabbar-style-type="tabbarStyleType"
349+
v-model:tabbar-wheelable="tabbarWheelable"
348350
/>
349351
</Block>
350352
<Block :title="$t('preferences.widget.title')">

packages/locales/src/langs/en-US/preferences.json

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
"showMaximize": "Show Maximize Button",
5656
"persist": "Persist Tabs",
5757
"draggable": "Enable Draggable Sort",
58+
"wheelable": "Support Mouse Wheel",
59+
"wheelableTip": "When enabled, the Tabbar area responds to vertical scrolling events of the scroll wheel.",
5860
"styleType": {
5961
"title": "Tabs Style",
6062
"chrome": "Chrome",

packages/locales/src/langs/zh-CN/preferences.json

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
"showMaximize": "显示最大化按钮",
5656
"persist": "持久化标签页",
5757
"draggable": "启动拖拽排序",
58+
"wheelable": "启用纵向滚轮响应",
59+
"wheelableTip": "开启后,标签栏区域可以响应滚轮的纵向滚动事件。\n关闭时,只能响应系统的横向滚动事件(需要按下Shift再滚动滚轮)",
5860
"styleType": {
5961
"title": "标签页风格",
6062
"chrome": "谷歌",

0 commit comments

Comments
 (0)