vue-stack-tabs 1.4.2 → 2.2.0
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/README.en.md +1 -0
- package/README.md +1 -0
- package/README.ru.md +1 -0
- package/dist/StackTabs.vue.d.ts +3 -0
- package/dist/components/ContextMenu/ContextMenuItem.vue.d.ts +1 -1
- package/dist/hooks/tabPanel/refresh.d.ts +4 -2
- package/dist/hooks/tabPanel/tabStore.d.ts +12 -1
- package/dist/hooks/useTabActions.d.ts +1 -0
- package/dist/hooks/useTabPanel.d.ts +14 -2
- package/dist/model/TabModel.d.ts +5 -0
- package/dist/style.css +1 -1
- package/dist/utils/tabInfoEncoder.d.ts +10 -0
- package/dist/utils/urlParser.d.ts +14 -3
- package/dist/vue-stack-tabs.es.js +1 -1
- package/package.json +4 -7
- package/src/lib/StackTabs.vue +24 -2
- package/src/lib/assets/image/close_all.svg +1 -9
- package/src/lib/assets/image/close_lefts.svg +1 -1
- package/src/lib/assets/image/close_other.svg +1 -1
- package/src/lib/assets/image/close_rights.svg +1 -1
- package/src/lib/assets/image/reload.svg +1 -3
- package/src/lib/assets/image/reload_all.svg +1 -6
- package/src/lib/assets/style/common/mixins.scss +58 -19
- package/src/lib/assets/style/common/var.scss +100 -60
- package/src/lib/assets/style/icon.scss +31 -98
- package/src/lib/assets/style/index.scss +2 -2
- package/src/lib/assets/style/loading.scss +45 -0
- package/src/lib/assets/style/{stackTab.scss → stack-tab.scss} +105 -177
- package/src/lib/assets/style/transition.scss +12 -17
- package/src/lib/components/ContextMenu/ContextMenuItem.vue +5 -5
- package/src/lib/components/ContextMenu/index.vue +22 -19
- package/src/lib/components/PageLoading.vue +5 -5
- package/src/lib/components/StackKeepAlive/StackKeepAlive.vue +5 -3
- package/src/lib/components/TabHeader/TabHeaderItem.vue +13 -7
- package/src/lib/components/TabHeader/TabHeaderScroll.vue +8 -6
- package/src/lib/components/TabHeader/index.vue +16 -2
- package/src/lib/hooks/tabPanel/pageComponentFactory.tsx +83 -7
- package/src/lib/hooks/tabPanel/refresh.ts +27 -9
- package/src/lib/hooks/tabPanel/tabStore.ts +86 -16
- package/src/lib/hooks/useContextMenu.ts +1 -1
- package/src/lib/hooks/useIframeManager.ts +10 -3
- package/src/lib/hooks/useTabActions.ts +8 -4
- package/src/lib/hooks/useTabPanel.tsx +204 -27
- package/src/lib/hooks/useTabRouter.ts +18 -11
- package/src/lib/model/TabModel.ts +5 -0
- package/src/lib/utils/tabInfoEncoder.ts +101 -17
- package/src/lib/utils/urlParser.ts +35 -11
- package/dist/vue-stack-tabs.css +0 -2
- package/src/lib/assets/style/overlayer.scss +0 -46
|
@@ -1,14 +1,55 @@
|
|
|
1
1
|
@use 'var' as *;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
|
|
3
|
+
// 绝对定位并铺满父容器
|
|
4
|
+
@mixin absolute-fill {
|
|
5
|
+
position: absolute;
|
|
6
|
+
inset: 0;
|
|
7
|
+
width: 100%;
|
|
8
|
+
height: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 水平垂直居中
|
|
12
|
+
@mixin flex-center {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 以 SVG mask 渲染图标,颜色由 background-color 控制
|
|
19
|
+
@mixin mask-icon($url) {
|
|
20
|
+
mask: url($url) no-repeat center center;
|
|
21
|
+
mask-size: contain;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 重置原生 button 的默认样式(padding、color 由使用处按需设置)
|
|
25
|
+
@mixin button-reset {
|
|
26
|
+
border: 0;
|
|
27
|
+
font: inherit;
|
|
28
|
+
text-align: inherit;
|
|
29
|
+
appearance: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 图标按钮的默认色及 hover/active 反馈
|
|
33
|
+
@mixin icon-button-color {
|
|
34
|
+
background-color: $stack-tab-text-color;
|
|
35
|
+
transition: $stack-tab-transition-fast;
|
|
36
|
+
|
|
37
|
+
&:hover {
|
|
38
|
+
background-color: $stack-tab-color-primary;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:active {
|
|
42
|
+
background-color: $stack-tab-color-primary-activate;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// icon 按钮特效:hover/active 时叠加 mask.svg
|
|
47
|
+
@mixin icon-rotate($icon-size, $icon-margin, $icon-url) {
|
|
6
48
|
width: $icon-size;
|
|
7
49
|
height: $icon-size;
|
|
8
50
|
margin-left: $icon-margin;
|
|
9
51
|
background-color: $stack-tab-text-color;
|
|
10
|
-
mask
|
|
11
|
-
mask-size: contain;
|
|
52
|
+
@include mask-icon($icon-url);
|
|
12
53
|
|
|
13
54
|
&:hover {
|
|
14
55
|
cursor: pointer;
|
|
@@ -16,30 +57,28 @@ icon按钮特效
|
|
|
16
57
|
animation: rotate-center 0.3s ease-in-out both;
|
|
17
58
|
mask:
|
|
18
59
|
url($icon-url),
|
|
19
|
-
url('
|
|
60
|
+
url('../image/mask.svg') no-repeat center center;
|
|
20
61
|
mask-size: contain;
|
|
21
62
|
mask-composite: xor;
|
|
22
63
|
}
|
|
23
64
|
|
|
24
65
|
&:active {
|
|
25
|
-
/*
|
|
26
|
-
cursor: pointer;
|
|
27
|
-
*/
|
|
28
66
|
background-color: $stack-tab-color-primary-activate;
|
|
29
67
|
mask:
|
|
30
68
|
url($icon-url),
|
|
31
|
-
url('
|
|
69
|
+
url('../image/mask.svg') no-repeat center center;
|
|
32
70
|
mask-size: contain;
|
|
33
71
|
mask-composite: xor;
|
|
34
72
|
}
|
|
35
73
|
}
|
|
36
74
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
75
|
+
// 追加一层铺满父容器的内阴影
|
|
76
|
+
@mixin inset-shadow($shadow...) {
|
|
77
|
+
&::after {
|
|
78
|
+
content: '';
|
|
79
|
+
position: absolute;
|
|
80
|
+
inset: 0;
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
box-shadow: $shadow;
|
|
83
|
+
}
|
|
45
84
|
}
|
|
@@ -1,68 +1,108 @@
|
|
|
1
1
|
@use 'sass:color';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
|
|
3
|
+
// ============================================================
|
|
4
|
+
// 颜色
|
|
5
|
+
// ============================================================
|
|
6
|
+
|
|
7
|
+
// 基础色
|
|
8
|
+
$stack-tab-color-white: #fff !default;
|
|
9
|
+
$stack-tab-color-black: #000 !default;
|
|
10
|
+
|
|
11
|
+
// 主色
|
|
5
12
|
$stack-tab-color-primary: #409eff !default;
|
|
6
13
|
$stack-tab-color-primary-invert: #ffac30 !default;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
$stack-tab-color-primary-activate: color.mix(
|
|
15
|
+
$stack-tab-color-primary,
|
|
16
|
+
$stack-tab-color-black,
|
|
17
|
+
80%
|
|
18
|
+
) !default;
|
|
19
|
+
|
|
20
|
+
// 功能色
|
|
10
21
|
$stack-tab-color-danger: #ef4f4f !default;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
$stack-tab-color-white: #fff !default;
|
|
15
|
-
/*
|
|
16
|
-
黑色
|
|
17
|
-
*/
|
|
18
|
-
$stack-tab-color-black: #000 !default;
|
|
22
|
+
|
|
23
|
+
// 中性色
|
|
19
24
|
$stack-tab-color-grey: #4d4d4d !default;
|
|
20
25
|
$stack-tab-color-disabled: #aaa !default;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
$stack-tab-color-text-secondary: #666 !default;
|
|
27
|
+
$stack-tab-color-text-tertiary: #999 !default;
|
|
28
|
+
$stack-tab-color-scrollbar: rgb(0 0 0 / 10%) !default;
|
|
29
|
+
|
|
30
|
+
// ============================================================
|
|
31
|
+
// 背景
|
|
32
|
+
// ============================================================
|
|
33
|
+
|
|
28
34
|
$stack-tab-background-color-base: #fff !default;
|
|
29
35
|
$stack-tab-background-color-inactive: #fafafa !default;
|
|
30
|
-
|
|
31
|
-
tab
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
$stack-tab-
|
|
39
|
-
|
|
40
|
-
tab
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
$stack-tab-
|
|
47
|
-
|
|
48
|
-
$stack-tab-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
$stack-tab-
|
|
56
|
-
$stack-tab-
|
|
57
|
-
$stack-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
$stack-tab-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
$stack-tab-
|
|
66
|
-
$stack-tab-
|
|
67
|
-
|
|
68
|
-
|
|
36
|
+
$stack-tab-iframe-loading-bg: #f5f5f5 !default;
|
|
37
|
+
$stack-tab-iframe-error-bg: rgb(255 255 255 / 92%) !default;
|
|
38
|
+
|
|
39
|
+
// ============================================================
|
|
40
|
+
// 边框与圆角
|
|
41
|
+
// ============================================================
|
|
42
|
+
|
|
43
|
+
$stack-tab-border-color: #f0f0f0 !default;
|
|
44
|
+
$stack-tab-border: 1px solid $stack-tab-border-color !default;
|
|
45
|
+
$stack-tab-tab-radius: 8px 8px 0 0 !default;
|
|
46
|
+
$stack-tab-contextmenu-radius: 10px 0 !default;
|
|
47
|
+
|
|
48
|
+
// ============================================================
|
|
49
|
+
// 文本
|
|
50
|
+
// ============================================================
|
|
51
|
+
|
|
52
|
+
$stack-tab-text-color: $stack-tab-color-grey !default;
|
|
53
|
+
$stack-tab-font-size: 14px !default;
|
|
54
|
+
$stack-tab-iframe-loading-color: $stack-tab-color-text-tertiary !default;
|
|
55
|
+
$stack-tab-iframe-error-color: $stack-tab-color-text-secondary !default;
|
|
56
|
+
|
|
57
|
+
// ============================================================
|
|
58
|
+
// 尺寸
|
|
59
|
+
// ============================================================
|
|
60
|
+
|
|
61
|
+
$stack-tab-padding: 24px !default;
|
|
62
|
+
$stack-tab-icon-margin: 4px !default;
|
|
63
|
+
$stack-tab-icon-size: 14px !default;
|
|
64
|
+
$stack-tab-button-size: 20px !default;
|
|
65
|
+
|
|
66
|
+
// 标签头高度
|
|
67
|
+
$stack-tab-head-height: 40px !default;
|
|
68
|
+
$stack-tab-head-invalid-height: $stack-tab-head-height - 3px !default;
|
|
69
|
+
|
|
70
|
+
// 滚动条
|
|
71
|
+
$stack-tab-scroll-height: 6px !default;
|
|
72
|
+
$stack-tab-scroll-border-radius: $stack-tab-scroll-height !default;
|
|
73
|
+
|
|
74
|
+
// ============================================================
|
|
75
|
+
// 动效
|
|
76
|
+
// ============================================================
|
|
77
|
+
|
|
78
|
+
// 图标、滚动条等高频交互的快速过渡
|
|
79
|
+
$stack-tab-transition-fast: all 0.15s ease-in-out !default;
|
|
80
|
+
$stack-tab-transition-duration: 0.3s !default;
|
|
81
|
+
$stack-tab-transition-slide-distance: 30px !default;
|
|
82
|
+
$stack-tab-transition-slide:
|
|
83
|
+
opacity $stack-tab-transition-duration ease-in-out,
|
|
84
|
+
transform $stack-tab-transition-duration ease-in-out !default;
|
|
85
|
+
|
|
86
|
+
// ============================================================
|
|
87
|
+
// 阴影
|
|
88
|
+
// ============================================================
|
|
89
|
+
|
|
90
|
+
$stack-tab-shadow-color: rgb(0 0 0 / 60%) !default;
|
|
91
|
+
$stack-tab-shadow-left: -5px 0 5px -5px $stack-tab-shadow-color !default;
|
|
92
|
+
$stack-tab-shadow-right: 5px 0 5px -5px $stack-tab-shadow-color !default;
|
|
93
|
+
$stack-tab-shadow-right-inset: inset -5px 0 5px -5px $stack-tab-shadow-color !default;
|
|
94
|
+
$stack-tab-shadow-left-inset: inset 5px 0 5px -5px $stack-tab-shadow-color !default;
|
|
95
|
+
$stack-tab-shadow-top-inset: inset 0 5px 5px -5px $stack-tab-shadow-color !default;
|
|
96
|
+
$stack-tab-shadow-bottom-inset: inset 0 -5px 5px -5px $stack-tab-shadow-color !default;
|
|
97
|
+
$stack-tab-shadow-context-menu: 5px 5px 5px rgb(0 0 0 / 10%) !default;
|
|
98
|
+
|
|
99
|
+
// ============================================================
|
|
100
|
+
// 加载态
|
|
101
|
+
// ============================================================
|
|
102
|
+
|
|
103
|
+
$stack-tab-loading-mask-color: $stack-tab-color-white !default;
|
|
104
|
+
$stack-tab-loading-mask-opacity: 0.8 !default;
|
|
105
|
+
$stack-tab-loading-size: 50px !default;
|
|
106
|
+
$stack-tab-loading-border-width: 8px !default;
|
|
107
|
+
$stack-tab-loading-color: #007bff97 !default;
|
|
108
|
+
$stack-tab-loading-duration: 1s !default;
|
|
@@ -1,99 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
mask:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.stack-tab__icon-close-rights {
|
|
35
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
36
|
-
mask: url('../image/close_rights.svg') no-repeat center center;
|
|
37
|
-
mask-size: contain;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.stack-tab__icon-close-others {
|
|
41
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
42
|
-
mask: url('../image/close_other.svg') no-repeat center center;
|
|
43
|
-
mask-size: contain;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.stack-tab__icon-close-all {
|
|
47
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
48
|
-
mask: url('../image/close_all.svg') no-repeat center center;
|
|
49
|
-
mask-size: contain;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/*
|
|
53
|
-
刷新
|
|
54
|
-
*/
|
|
55
|
-
.stack-tab__icon-reload {
|
|
56
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
57
|
-
mask: url('../image/loading.svg') no-repeat center center;
|
|
58
|
-
mask-size: contain;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.stack-tab__icon-reload-lefts {
|
|
62
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
63
|
-
mask: url('../image/reload_lefts.svg') no-repeat center center;
|
|
64
|
-
mask-size: contain;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.stack-tab__icon-reload-rights {
|
|
68
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
69
|
-
mask: url('../image/reload_rights.svg') no-repeat center center;
|
|
70
|
-
mask-size: contain;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.stack-tab__icon-reload-all {
|
|
74
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
75
|
-
mask: url('../image/reload.svg') no-repeat center center;
|
|
76
|
-
mask-size: contain;
|
|
77
|
-
}
|
|
78
|
-
/*
|
|
79
|
-
左箭头
|
|
80
|
-
*/
|
|
81
|
-
.stack-tab__icon-left-arrow {
|
|
82
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
83
|
-
mask: url('../image/left_arrow.svg') no-repeat center center;
|
|
84
|
-
mask-size: contain;
|
|
85
|
-
}
|
|
86
|
-
/*
|
|
87
|
-
右箭头
|
|
88
|
-
*/
|
|
89
|
-
.stack-tab__icon-right-arrow {
|
|
90
|
-
/* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
|
|
91
|
-
mask: url('../image/right_arrow.svg') no-repeat center center;
|
|
92
|
-
mask-size: contain;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* 新窗口打开 */
|
|
96
|
-
.stack-tab__icon-open {
|
|
97
|
-
mask: url('../image/open.svg') no-repeat center center;
|
|
98
|
-
mask-size: contain;
|
|
1
|
+
// 图标名 => SVG 文件
|
|
2
|
+
$stack-tab-icons: (
|
|
3
|
+
fullscreen: 'fullscreen.svg',
|
|
4
|
+
restore: 'restore.svg',
|
|
5
|
+
close: 'close.svg',
|
|
6
|
+
close-fill: 'close_fill.svg',
|
|
7
|
+
close-lefts: 'close_lefts.svg',
|
|
8
|
+
close-rights: 'close_rights.svg',
|
|
9
|
+
close-others: 'close_other.svg',
|
|
10
|
+
close-all: 'close_all.svg',
|
|
11
|
+
reload: 'reload.svg',
|
|
12
|
+
reload-lefts: 'reload_lefts.svg',
|
|
13
|
+
reload-rights: 'reload_rights.svg',
|
|
14
|
+
reload-all: 'reload_all.svg',
|
|
15
|
+
left-arrow: 'left_arrow.svg',
|
|
16
|
+
right-arrow: 'right_arrow.svg',
|
|
17
|
+
open: 'open.svg'
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
// 图标基础样式:颜色由使用处的 background-color 控制
|
|
21
|
+
.stack-tab__icon {
|
|
22
|
+
mask-repeat: no-repeat;
|
|
23
|
+
mask-position: center center;
|
|
24
|
+
mask-size: contain;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 每个图标只声明自己的 mask-image
|
|
28
|
+
@each $name, $file in $stack-tab-icons {
|
|
29
|
+
.stack-tab__icon--#{$name} {
|
|
30
|
+
mask-image: url('../image/#{$file}');
|
|
31
|
+
}
|
|
99
32
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@use 'common/var' as *;
|
|
2
|
+
@use 'common/mixins' as *;
|
|
3
|
+
|
|
4
|
+
.stack-tab-loading {
|
|
5
|
+
// 页面加载遮罩
|
|
6
|
+
&__mask {
|
|
7
|
+
@include absolute-fill;
|
|
8
|
+
@include flex-center;
|
|
9
|
+
background-color: $stack-tab-loading-mask-color;
|
|
10
|
+
opacity: $stack-tab-loading-mask-opacity;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// 三层圆环同轴旋转
|
|
14
|
+
&__spin {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: $stack-tab-loading-size;
|
|
17
|
+
aspect-ratio: 1;
|
|
18
|
+
border: $stack-tab-loading-border-width solid transparent;
|
|
19
|
+
border-right-color: $stack-tab-loading-color;
|
|
20
|
+
border-radius: 50%;
|
|
21
|
+
animation: stack-tab-loading-rotate $stack-tab-loading-duration infinite linear;
|
|
22
|
+
|
|
23
|
+
&::before,
|
|
24
|
+
&::after {
|
|
25
|
+
content: '';
|
|
26
|
+
position: absolute;
|
|
27
|
+
inset: -$stack-tab-loading-border-width;
|
|
28
|
+
border: $stack-tab-loading-border-width solid transparent;
|
|
29
|
+
border-right-color: $stack-tab-loading-color;
|
|
30
|
+
border-radius: 50%;
|
|
31
|
+
animation: stack-tab-loading-rotate $stack-tab-loading-duration * 2 infinite linear;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 最外层转得最慢,形成错层效果
|
|
35
|
+
&::after {
|
|
36
|
+
animation-duration: $stack-tab-loading-duration * 4;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@keyframes stack-tab-loading-rotate {
|
|
42
|
+
to {
|
|
43
|
+
transform: rotate(1turn);
|
|
44
|
+
}
|
|
45
|
+
}
|