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.
Files changed (49) hide show
  1. package/README.en.md +1 -0
  2. package/README.md +1 -0
  3. package/README.ru.md +1 -0
  4. package/dist/StackTabs.vue.d.ts +3 -0
  5. package/dist/components/ContextMenu/ContextMenuItem.vue.d.ts +1 -1
  6. package/dist/hooks/tabPanel/refresh.d.ts +4 -2
  7. package/dist/hooks/tabPanel/tabStore.d.ts +12 -1
  8. package/dist/hooks/useTabActions.d.ts +1 -0
  9. package/dist/hooks/useTabPanel.d.ts +14 -2
  10. package/dist/model/TabModel.d.ts +5 -0
  11. package/dist/style.css +1 -1
  12. package/dist/utils/tabInfoEncoder.d.ts +10 -0
  13. package/dist/utils/urlParser.d.ts +14 -3
  14. package/dist/vue-stack-tabs.es.js +1 -1
  15. package/package.json +4 -7
  16. package/src/lib/StackTabs.vue +24 -2
  17. package/src/lib/assets/image/close_all.svg +1 -9
  18. package/src/lib/assets/image/close_lefts.svg +1 -1
  19. package/src/lib/assets/image/close_other.svg +1 -1
  20. package/src/lib/assets/image/close_rights.svg +1 -1
  21. package/src/lib/assets/image/reload.svg +1 -3
  22. package/src/lib/assets/image/reload_all.svg +1 -6
  23. package/src/lib/assets/style/common/mixins.scss +58 -19
  24. package/src/lib/assets/style/common/var.scss +100 -60
  25. package/src/lib/assets/style/icon.scss +31 -98
  26. package/src/lib/assets/style/index.scss +2 -2
  27. package/src/lib/assets/style/loading.scss +45 -0
  28. package/src/lib/assets/style/{stackTab.scss → stack-tab.scss} +105 -177
  29. package/src/lib/assets/style/transition.scss +12 -17
  30. package/src/lib/components/ContextMenu/ContextMenuItem.vue +5 -5
  31. package/src/lib/components/ContextMenu/index.vue +22 -19
  32. package/src/lib/components/PageLoading.vue +5 -5
  33. package/src/lib/components/StackKeepAlive/StackKeepAlive.vue +5 -3
  34. package/src/lib/components/TabHeader/TabHeaderItem.vue +13 -7
  35. package/src/lib/components/TabHeader/TabHeaderScroll.vue +8 -6
  36. package/src/lib/components/TabHeader/index.vue +16 -2
  37. package/src/lib/hooks/tabPanel/pageComponentFactory.tsx +83 -7
  38. package/src/lib/hooks/tabPanel/refresh.ts +27 -9
  39. package/src/lib/hooks/tabPanel/tabStore.ts +86 -16
  40. package/src/lib/hooks/useContextMenu.ts +1 -1
  41. package/src/lib/hooks/useIframeManager.ts +10 -3
  42. package/src/lib/hooks/useTabActions.ts +8 -4
  43. package/src/lib/hooks/useTabPanel.tsx +204 -27
  44. package/src/lib/hooks/useTabRouter.ts +18 -11
  45. package/src/lib/model/TabModel.ts +5 -0
  46. package/src/lib/utils/tabInfoEncoder.ts +101 -17
  47. package/src/lib/utils/urlParser.ts +35 -11
  48. package/dist/vue-stack-tabs.css +0 -2
  49. package/src/lib/assets/style/overlayer.scss +0 -46
@@ -1,14 +1,55 @@
1
1
  @use 'var' as *;
2
- /*
3
- icon按钮特效
4
- */
5
- @mixin icon_rotate($icon-size, $icon-margin, $icon-url) {
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: url($icon-url) no-repeat center center;
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('./image/mask.svg') no-repeat center center;
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('./image/mask.svg') no-repeat center center;
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
- @mixin insetShadow() {
38
- content: '';
39
- position: absolute;
40
- left: 0;
41
- right: 0;
42
- top: 0;
43
- bottom: 0;
44
- pointer-events: none;
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
- ICON点击颜色
23
- */
24
- $stack-tab-color-primary-activate: color.mix($stack-tab-color-primary, #000, 80%) !default;
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
- $stack-tab-border-color: #f0f0f0;
34
- $stack-tab-border: 1px solid $stack-tab-border-color;
35
- /*
36
- tab文本颜色
37
- */
38
- $stack-tab-text-color: $stack-tab-color-grey;
39
- /*
40
- tab文本大小
41
- */
42
- $stack-tab-font-size: 14px;
43
-
44
- $stack-tab-padding: 24px;
45
- $stack-tab-icon-margin: 4px;
46
- $stack-tab-icon-size: 14px;
47
-
48
- $stack-tab-button-size: 20px;
49
- /*
50
- tab头高度
51
- */
52
- $stack-tab-head-height: 40px;
53
- $stack-tab-head-invalid-height: $stack-tab-head-height -3px;
54
-
55
- $stack-tab-scroll-height: 6px;
56
- $stack-tab-scroll-border-radius: $stack-tab-scroll-height;
57
- $stack-tab__trans: all 0.15s ease-in-out;
58
-
59
- /*
60
- 阴影
61
- */
62
- $stack-tab-shadow-left: -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
63
- $stack-tab-shadow-right: 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
64
- $stack-tab-shadow-right-inset: inset -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
65
- $stack-tab-shadow-left-inset: inset 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
66
- $stack-tab-shadow-top-inset: inset 0 5px 5px -5px rgb(0 0 0 / 60%); //#ccc;
67
- $stack-tab-shadow-bottom-inset: inset 0 -5px 5px -5px rgb(0 0 0 / 60%); //#ccc;
68
- $stack-tab-shadow-context-menu: 5px 5px 5px rgb(0 0 0 / 10%);
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
- @use 'common/var' as *;
2
-
3
- // 全屏
4
- .stack-tab__icon-fullscreen {
5
- /* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
6
- mask: url('../image/fullscreen.svg') no-repeat center center;
7
- mask-size: contain;
8
- }
9
- // 恢复
10
- .stack-tab__icon-restore {
11
- /* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
12
- mask: url('../image/restore.svg') no-repeat center center;
13
- mask-size: contain;
14
- }
15
- // 关闭
16
- .stack-tab__icon-close {
17
- /* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
18
- mask: url('../image/close.svg') no-repeat center center;
19
- mask-size: contain;
20
- }
21
-
22
- .stack-tab__icon-close-fill {
23
- /* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
24
- mask: url('../image/close_fill.svg') no-repeat center center;
25
- mask-size: contain;
26
- }
27
-
28
- .stack-tab__icon-close-lefts {
29
- /* 类似一个到路径上做一个遮罩, 用法和background属性一样 */
30
- mask: url('../image/close_lefts.svg') no-repeat center center;
31
- mask-size: contain;
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
  }
@@ -1,4 +1,4 @@
1
- @use 'stackTab.scss';
1
+ @use 'stack-tab.scss';
2
2
  @use 'icon.scss';
3
3
  @use 'transition.scss';
4
- @use 'overlayer.scss';
4
+ @use 'loading.scss';
@@ -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
+ }