vue-stack-tabs 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vue-stack-tabs.es.js +228 -259
- package/dist/vue-stack-tabs.umd.js +5 -5
- package/package.json +1 -1
- package/src/lib/StackTabs.vue +40 -41
- package/src/lib/hooks/useTabpanel.tsx +8 -7
- package/src/lib/index.ts +2 -2
- package/types/StackTabs.vue.d.ts +2 -0
- package/types/components/ContextMenu/ContextMenuItem.vue.d.ts +2 -0
- package/types/components/ContextMenu/index.vue.d.ts +2 -0
- package/types/components/TabHeader/TabHeaderButton.vue.d.ts +2 -0
- package/types/components/TabHeader/TabHeaderItem.vue.d.ts +2 -0
- package/types/components/TabHeader/TabHeaderScroll.vue.d.ts +2 -0
- package/types/components/TabHeader/index.vue.d.ts +2 -0
- package/types/hooks/useContextMenu.d.ts +7 -0
- package/types/index.d.ts +1 -1
- package/types/utils/TabScrollHelper.d.ts +33 -0
package/package.json
CHANGED
package/src/lib/StackTabs.vue
CHANGED
|
@@ -1,44 +1,4 @@
|
|
|
1
|
-
<
|
|
2
|
-
<div
|
|
3
|
-
class="stack-tab"
|
|
4
|
-
:style="{
|
|
5
|
-
width: width,
|
|
6
|
-
height: height,
|
|
7
|
-
'z-index': maximum ? getMaxZIndex('body *:not(.stack-tab,.stack-tab *)') : undefined
|
|
8
|
-
}"
|
|
9
|
-
:class="{ 'stack-tab__maximum': maximum }"
|
|
10
|
-
>
|
|
11
|
-
<tab-header :space="space" @active="onTabActive" :tab-transition="tabTransition" :max="max">
|
|
12
|
-
<template #leftButton>
|
|
13
|
-
<slot name="leftButton" />
|
|
14
|
-
</template>
|
|
15
|
-
<template #rightButton>
|
|
16
|
-
<slot name="rightButton" />
|
|
17
|
-
</template>
|
|
18
|
-
</tab-header>
|
|
19
|
-
<div class="stack-tab__container">
|
|
20
|
-
<router-view v-slot="{ Component, route }">
|
|
21
|
-
<transition :name="pageTransition" appear @after-leave="pageShown = true">
|
|
22
|
-
<keep-alive :include="caches">
|
|
23
|
-
<component :is="tabWrapper(route, Component)" v-if="pageShown" :key="route.fullPath" />
|
|
24
|
-
</keep-alive>
|
|
25
|
-
</transition>
|
|
26
|
-
</router-view>
|
|
27
|
-
<transition-group :name="pageTransition" appear>
|
|
28
|
-
<iframe
|
|
29
|
-
v-for="frame of tabs.filter((item) => item.iframe)"
|
|
30
|
-
v-show="frame.active && pageShown"
|
|
31
|
-
:key="frame.id"
|
|
32
|
-
class="stack-tab__iframe"
|
|
33
|
-
:src="/^(javascript|data):/i.test(frame.url ?? '') ? 'about:blank' : frame.url"
|
|
34
|
-
frameborder="0"
|
|
35
|
-
/>
|
|
36
|
-
</transition-group>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</template>
|
|
40
|
-
|
|
41
|
-
<script lang="tsx" setup>
|
|
1
|
+
<script lang="ts" setup>
|
|
42
2
|
import { onBeforeMount, onUnmounted, provide, ref, watch } from 'vue'
|
|
43
3
|
import type { TransitionProps, DefineComponent, VNode } from 'vue'
|
|
44
4
|
import { type RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
|
|
@@ -124,4 +84,43 @@ watch(
|
|
|
124
84
|
}
|
|
125
85
|
)
|
|
126
86
|
</script>
|
|
87
|
+
<template>
|
|
88
|
+
<div
|
|
89
|
+
class="stack-tab"
|
|
90
|
+
:style="{
|
|
91
|
+
width: width,
|
|
92
|
+
height: height,
|
|
93
|
+
'z-index': maximum ? getMaxZIndex('body *:not(.stack-tab,.stack-tab *)') : undefined
|
|
94
|
+
}"
|
|
95
|
+
:class="{ 'stack-tab__maximum': maximum }"
|
|
96
|
+
>
|
|
97
|
+
<tab-header :space="space" @active="onTabActive" :tab-transition="tabTransition" :max="max">
|
|
98
|
+
<template #leftButton>
|
|
99
|
+
<slot name="leftButton" />
|
|
100
|
+
</template>
|
|
101
|
+
<template #rightButton>
|
|
102
|
+
<slot name="rightButton" />
|
|
103
|
+
</template>
|
|
104
|
+
</tab-header>
|
|
105
|
+
<div class="stack-tab__container">
|
|
106
|
+
<router-view v-slot="{ Component, route }">
|
|
107
|
+
<transition :name="pageTransition" appear @after-leave="pageShown = true">
|
|
108
|
+
<keep-alive :include="caches">
|
|
109
|
+
<component :is="tabWrapper(route, Component)" v-if="pageShown" :key="route.fullPath" />
|
|
110
|
+
</keep-alive>
|
|
111
|
+
</transition>
|
|
112
|
+
</router-view>
|
|
113
|
+
<transition-group :name="pageTransition" appear>
|
|
114
|
+
<iframe
|
|
115
|
+
v-for="frame of tabs.filter((item) => item.iframe)"
|
|
116
|
+
v-show="frame.active && pageShown"
|
|
117
|
+
:key="frame.id"
|
|
118
|
+
class="stack-tab__iframe"
|
|
119
|
+
:src="/^(javascript|data):/i.test(frame.url ?? '') ? 'about:blank' : frame.url"
|
|
120
|
+
frameborder="0"
|
|
121
|
+
/>
|
|
122
|
+
</transition-group>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</template>
|
|
127
126
|
<style scoped></style>
|
|
@@ -194,17 +194,18 @@ export default () => {
|
|
|
194
194
|
let activeTabId = ''
|
|
195
195
|
for (let i = tabs.value.length - 1; i >= 0; i--) {
|
|
196
196
|
if (id === unref(tabs)[i].id) {
|
|
197
|
+
//if it's not closable then return
|
|
197
198
|
if (!unref(tabs)[i].closable) {
|
|
198
|
-
|
|
199
|
+
return id
|
|
199
200
|
}
|
|
200
201
|
for (const item of unref(tabs)[i].pages.list()) {
|
|
201
202
|
removeComponent(item.id)
|
|
202
203
|
markDeletableCache(item.id)
|
|
203
204
|
}
|
|
204
205
|
unref(tabs)[i].pages.clear()
|
|
205
|
-
if (tabs.value.length > 1) {
|
|
206
|
+
if (tabs.value.length > 1 && unref(tabs)[i].active) {
|
|
206
207
|
if (i === 0) {
|
|
207
|
-
activeTabId = unref(tabs)[1].id
|
|
208
|
+
activeTabId = unref(tabs)[i + 1].id
|
|
208
209
|
} else {
|
|
209
210
|
activeTabId = unref(tabs)[i - 1].id
|
|
210
211
|
}
|
|
@@ -214,11 +215,11 @@ export default () => {
|
|
|
214
215
|
break
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (activeTabId !== id) {
|
|
220
|
-
removeDeletableCache()
|
|
218
|
+
if (activeTabId !== '') {
|
|
219
|
+
active(activeTabId)
|
|
221
220
|
}
|
|
221
|
+
// if remove inactive tab,then we need remove the cache manually.
|
|
222
|
+
removeDeletableCache()
|
|
222
223
|
return activeTabId
|
|
223
224
|
}
|
|
224
225
|
|
package/src/lib/index.ts
CHANGED
|
@@ -16,8 +16,8 @@ const i18n = createI18n({
|
|
|
16
16
|
export * from './model/TabModel'
|
|
17
17
|
export { IFrame, useTabLoading, useTabRouter, useStackTab }
|
|
18
18
|
export default {
|
|
19
|
-
install(
|
|
19
|
+
install(Vue: App): void {
|
|
20
20
|
tabVersion(import.meta.env.PACKAGE_VERSION)
|
|
21
|
-
|
|
21
|
+
Vue.component('VueStackTabs', StackTab).use(i18n)
|
|
22
22
|
}
|
|
23
23
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 滚动到指定位置
|
|
3
|
+
* @export
|
|
4
|
+
* @param {Element} wrap 滚动区域
|
|
5
|
+
* @param {number} [left=0]
|
|
6
|
+
* @param {number} [top=0]
|
|
7
|
+
*/
|
|
8
|
+
export declare const _scrollTo: ({ wrap, left, top, smooth }: {
|
|
9
|
+
wrap: HTMLElement | null;
|
|
10
|
+
left?: number;
|
|
11
|
+
top?: number;
|
|
12
|
+
smooth?: boolean;
|
|
13
|
+
}) => void;
|
|
14
|
+
/**
|
|
15
|
+
* 指定元素滚动到可视区域
|
|
16
|
+
* @export
|
|
17
|
+
* @param {Element} el 目标元素
|
|
18
|
+
* @param {Element} wrap 滚动区域
|
|
19
|
+
* @param {String} block 垂直方向的对齐,可选:'start', 'center', 'end', 或 'nearest'
|
|
20
|
+
* @param {String} inline 水平方向的对齐,可选值同上
|
|
21
|
+
*/
|
|
22
|
+
export declare function _scrollIntoView({ el, wrap, block, inline }: {
|
|
23
|
+
el: HTMLElement;
|
|
24
|
+
wrap: any;
|
|
25
|
+
block?: any;
|
|
26
|
+
inline?: any;
|
|
27
|
+
}): void;
|
|
28
|
+
export declare const getScrollbarWidth: () => number;
|
|
29
|
+
/**
|
|
30
|
+
* 获取最大z-index
|
|
31
|
+
* @returns 最大z-index的值
|
|
32
|
+
*/
|
|
33
|
+
export declare const getMaxZIndex: (key?: string) => number;
|