vue-stack-tabs 1.4.2 → 2.3.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 +5 -2
- package/dist/components/ContextMenu/ContextMenuItem.vue.d.ts +1 -1
- package/dist/components/StackKeepAlive/StackCacheRenderer.vue.d.ts +0 -2
- package/dist/hooks/stackTabsContext.d.ts +0 -1
- package/dist/hooks/tabPanel/evict.d.ts +2 -2
- package/dist/hooks/tabPanel/refresh.d.ts +4 -2
- package/dist/hooks/tabPanel/scroll.d.ts +0 -2
- package/dist/hooks/tabPanel/state.d.ts +0 -1
- package/dist/hooks/tabPanel/tabStore.d.ts +12 -1
- package/dist/hooks/useIframeManager.d.ts +1 -1
- package/dist/hooks/useScrollShadow.d.ts +11 -2
- package/dist/hooks/useTabActions.d.ts +1 -0
- package/dist/hooks/useTabEventBus.d.ts +5 -0
- package/dist/hooks/useTabPanel.d.ts +14 -2
- package/dist/model/TabModel.d.ts +17 -5
- package/dist/nuxt/module.mjs +1 -1
- package/dist/nuxt/runtime/plugin.mjs +8 -1598
- package/dist/style.css +1 -1
- package/dist/utils/scrollUtils.d.ts +0 -2
- package/dist/utils/tabInfoEncoder.d.ts +8 -0
- package/dist/utils/urlParser.d.ts +20 -10
- package/dist/vue-stack-tabs.es.js +1 -1
- package/package.json +4 -7
- package/src/lib/StackTabs.vue +40 -3
- 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} +116 -182
- 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 +12 -11
- package/src/lib/components/StackKeepAlive/StackCacheRenderer.vue +1 -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 +170 -94
- package/src/lib/components/TabHeader/index.vue +67 -12
- package/src/lib/hooks/stackTabsContext.ts +0 -1
- package/src/lib/hooks/tabPanel/evict.ts +14 -6
- package/src/lib/hooks/tabPanel/pageComponentFactory.tsx +252 -7
- package/src/lib/hooks/tabPanel/refresh.ts +27 -9
- package/src/lib/hooks/tabPanel/scroll.ts +4 -15
- package/src/lib/hooks/tabPanel/session.ts +11 -4
- package/src/lib/hooks/tabPanel/state.ts +0 -2
- package/src/lib/hooks/tabPanel/tabStore.ts +114 -26
- package/src/lib/hooks/useContextMenu.ts +1 -1
- package/src/lib/hooks/useIframeManager.ts +21 -18
- package/src/lib/hooks/useScrollShadow.ts +74 -19
- package/src/lib/hooks/useTabActions.ts +18 -8
- package/src/lib/hooks/useTabEventBus.ts +3 -0
- package/src/lib/hooks/useTabPanel.tsx +247 -58
- package/src/lib/hooks/useTabRouter.ts +18 -11
- package/src/lib/model/TabModel.ts +19 -5
- package/src/lib/nuxt/module.ts +3 -1
- package/src/lib/nuxt/runtime/plugin.ts +7 -3
- package/src/lib/utils/scrollUtils.ts +0 -18
- package/src/lib/utils/tabInfoEncoder.ts +121 -18
- package/src/lib/utils/urlParser.ts +75 -48
- package/dist/vue-stack-tabs.css +0 -2
- package/src/lib/assets/style/overlayer.scss +0 -46
|
@@ -1,63 +1,51 @@
|
|
|
1
1
|
@use 'sass:math';
|
|
2
2
|
@use 'common/var' as *;
|
|
3
|
-
@use 'common/mixins'
|
|
3
|
+
@use 'common/mixins' as *;
|
|
4
4
|
|
|
5
5
|
.stack-tab {
|
|
6
6
|
display: flex;
|
|
7
7
|
min-height: 300px;
|
|
8
8
|
background-color: $stack-tab-background-color-base;
|
|
9
9
|
flex-direction: column;
|
|
10
|
-
|
|
10
|
+
gap: 5px;
|
|
11
11
|
|
|
12
12
|
&__container {
|
|
13
13
|
flex: 1 1 0;
|
|
14
14
|
position: relative;
|
|
15
15
|
overflow: hidden;
|
|
16
16
|
}
|
|
17
|
+
|
|
17
18
|
&__keep-alive-panel {
|
|
18
|
-
|
|
19
|
-
top: 0;
|
|
20
|
-
left: 0;
|
|
21
|
-
width: 100%;
|
|
22
|
-
height: 100%;
|
|
19
|
+
@include absolute-fill;
|
|
23
20
|
}
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
// 缓存页面 wrapper
|
|
23
|
+
&__cache-page-wrapper {
|
|
27
24
|
width: 100%;
|
|
28
25
|
height: 100%;
|
|
29
26
|
}
|
|
30
|
-
|
|
27
|
+
|
|
28
|
+
&--maximum {
|
|
29
|
+
position: fixed;
|
|
30
|
+
inset: 0;
|
|
31
31
|
width: 100vw !important;
|
|
32
32
|
height: 100vh !important;
|
|
33
|
-
top: 0;
|
|
34
|
-
left: 0;
|
|
35
|
-
position: fixed;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
// 蒙版按钮
|
|
39
36
|
&__mask-button {
|
|
40
37
|
height: 100%;
|
|
41
38
|
width: $stack-tab-button-size;
|
|
42
|
-
background-color: $stack-tab-text-color;
|
|
43
39
|
margin: 0 5px;
|
|
44
|
-
|
|
40
|
+
@include icon-button-color;
|
|
45
41
|
|
|
46
42
|
.stack-tab__header-button[disabled] & {
|
|
47
43
|
cursor: not-allowed;
|
|
48
44
|
background-color: $stack-tab-color-disabled;
|
|
49
45
|
transition: none;
|
|
50
|
-
//pointer-events: none;
|
|
51
|
-
}
|
|
52
|
-
&:hover {
|
|
53
|
-
background-color: $stack-tab-color-primary;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
&:active {
|
|
57
|
-
// cursor: pointer;
|
|
58
|
-
background-color: $stack-tab-color-primary-activate;
|
|
59
46
|
}
|
|
60
47
|
}
|
|
48
|
+
|
|
61
49
|
&__button {
|
|
62
50
|
height: $stack-tab-button-size;
|
|
63
51
|
width: $stack-tab-button-size;
|
|
@@ -71,9 +59,8 @@
|
|
|
71
59
|
height: $stack-tab-head-height;
|
|
72
60
|
border-bottom: 1px solid $stack-tab-border-color;
|
|
73
61
|
box-sizing: border-box;
|
|
74
|
-
//user-select: none;
|
|
75
62
|
|
|
76
|
-
//tab header上面的按钮
|
|
63
|
+
// tab header 上面的按钮
|
|
77
64
|
&-button {
|
|
78
65
|
z-index: 2;
|
|
79
66
|
height: $stack-tab-head-height;
|
|
@@ -83,14 +70,11 @@
|
|
|
83
70
|
cursor: pointer;
|
|
84
71
|
display: flex;
|
|
85
72
|
align-items: center;
|
|
86
|
-
border: 0;
|
|
87
73
|
padding: 0;
|
|
88
74
|
color: inherit;
|
|
89
|
-
|
|
90
|
-
text-align: inherit;
|
|
91
|
-
appearance: none;
|
|
75
|
+
@include button-reset;
|
|
92
76
|
|
|
93
|
-
|
|
77
|
+
// 按钮禁用样式
|
|
94
78
|
&[disabled] {
|
|
95
79
|
background-color: $stack-tab-background-color-inactive;
|
|
96
80
|
box-shadow: none;
|
|
@@ -98,7 +82,8 @@
|
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
84
|
}
|
|
101
|
-
|
|
85
|
+
|
|
86
|
+
// tab header 上的滚动条
|
|
102
87
|
&__scroll {
|
|
103
88
|
position: relative;
|
|
104
89
|
flex: 1 1 0;
|
|
@@ -108,58 +93,63 @@
|
|
|
108
93
|
&-container {
|
|
109
94
|
width: 100%;
|
|
110
95
|
height: 100%;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
96
|
+
// 使用原生横向滚动以保留触摸/触控板惯性与手感;
|
|
97
|
+
// 原生滚动条隐藏,视觉上仍由下方自绘滚动条呈现。
|
|
98
|
+
overflow-x: auto;
|
|
99
|
+
overflow-y: hidden;
|
|
100
|
+
overscroll-behavior-x: contain;
|
|
101
|
+
scrollbar-width: none;
|
|
102
|
+
-ms-overflow-style: none;
|
|
103
|
+
|
|
104
|
+
&::-webkit-scrollbar {
|
|
105
|
+
display: none;
|
|
117
106
|
}
|
|
118
107
|
}
|
|
119
108
|
}
|
|
109
|
+
|
|
120
110
|
&__scrollbar {
|
|
121
111
|
position: absolute;
|
|
122
112
|
right: 0;
|
|
123
113
|
bottom: 0;
|
|
124
114
|
left: 0;
|
|
125
|
-
/*z-index: 2;*/
|
|
126
115
|
height: $stack-tab-scroll-height;
|
|
127
|
-
background-color:
|
|
116
|
+
background-color: $stack-tab-color-scrollbar;
|
|
128
117
|
border-radius: $stack-tab-scroll-border-radius;
|
|
129
118
|
opacity: 0;
|
|
130
|
-
transition: $stack-
|
|
119
|
+
transition: $stack-tab-transition-fast;
|
|
131
120
|
|
|
132
121
|
.stack-tab__scroll:hover &,
|
|
133
|
-
|
|
122
|
+
&--dragging {
|
|
134
123
|
opacity: 1;
|
|
135
124
|
}
|
|
136
125
|
}
|
|
126
|
+
|
|
137
127
|
&__scrollbar-thumb {
|
|
138
128
|
position: absolute;
|
|
139
129
|
top: 0;
|
|
140
130
|
left: 0;
|
|
141
131
|
height: 100%;
|
|
142
|
-
background-color:
|
|
143
|
-
|
|
132
|
+
background-color: $stack-tab-color-scrollbar;
|
|
144
133
|
border-radius: $stack-tab-scroll-border-radius;
|
|
145
|
-
transition: background-color
|
|
134
|
+
transition: background-color $stack-tab-transition-duration ease-in-out;
|
|
135
|
+
// 拖拽由 Pointer Events 接管,避免触摸时被浏览器手势打断
|
|
136
|
+
touch-action: none;
|
|
146
137
|
|
|
147
138
|
&:hover {
|
|
148
139
|
cursor: grab;
|
|
140
|
+
|
|
149
141
|
&:active {
|
|
150
142
|
cursor: grabbing;
|
|
151
143
|
}
|
|
152
144
|
}
|
|
153
145
|
|
|
154
|
-
.stack-tab__scrollbar
|
|
146
|
+
.stack-tab__scrollbar--dragging &,
|
|
155
147
|
&:hover {
|
|
156
148
|
background-color: $stack-tab-color-primary !important;
|
|
157
149
|
}
|
|
158
150
|
}
|
|
159
151
|
|
|
160
|
-
|
|
161
|
-
页签导航
|
|
162
|
-
*/
|
|
152
|
+
// 页签导航
|
|
163
153
|
&__nav {
|
|
164
154
|
position: relative;
|
|
165
155
|
display: inline-flex;
|
|
@@ -171,9 +161,7 @@
|
|
|
171
161
|
content-visibility: auto;
|
|
172
162
|
}
|
|
173
163
|
|
|
174
|
-
|
|
175
|
-
页签项
|
|
176
|
-
*/
|
|
164
|
+
// 页签项
|
|
177
165
|
&__item {
|
|
178
166
|
position: relative;
|
|
179
167
|
display: flex;
|
|
@@ -184,8 +172,8 @@
|
|
|
184
172
|
background-color: $stack-tab-background-color-inactive;
|
|
185
173
|
border: $stack-tab-border;
|
|
186
174
|
border-left: none;
|
|
187
|
-
border-radius:
|
|
188
|
-
transition: $stack-
|
|
175
|
+
border-radius: $stack-tab-tab-radius;
|
|
176
|
+
transition: $stack-tab-transition-fast;
|
|
189
177
|
user-select: none;
|
|
190
178
|
flex: none;
|
|
191
179
|
align-items: center;
|
|
@@ -197,12 +185,12 @@
|
|
|
197
185
|
border-left: $stack-tab-border;
|
|
198
186
|
}
|
|
199
187
|
|
|
200
|
-
|
|
188
|
+
&--dragging {
|
|
201
189
|
opacity: 0.55;
|
|
202
190
|
}
|
|
203
191
|
|
|
204
|
-
|
|
205
|
-
|
|
192
|
+
&--drop-before::before,
|
|
193
|
+
&--drop-after::after {
|
|
206
194
|
position: absolute;
|
|
207
195
|
z-index: 2;
|
|
208
196
|
top: 2px;
|
|
@@ -214,37 +202,37 @@
|
|
|
214
202
|
box-shadow: 0 0 6px rgba($stack-tab-color-primary, 0.8);
|
|
215
203
|
}
|
|
216
204
|
|
|
217
|
-
|
|
205
|
+
&--drop-before::before {
|
|
218
206
|
left: -3px;
|
|
219
207
|
}
|
|
220
208
|
|
|
221
|
-
|
|
209
|
+
&--drop-after::after {
|
|
222
210
|
right: -3px;
|
|
223
211
|
}
|
|
224
212
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
&.is-contextmenu {
|
|
229
|
-
color: #000;
|
|
213
|
+
// 激活右键菜单的页签
|
|
214
|
+
&--context-menu {
|
|
215
|
+
color: $stack-tab-color-black;
|
|
230
216
|
}
|
|
231
217
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
*/
|
|
235
|
-
&.is-active {
|
|
218
|
+
// 激活的页签
|
|
219
|
+
&--active {
|
|
236
220
|
z-index: 1;
|
|
237
221
|
background-color: $stack-tab-background-color-base;
|
|
238
|
-
border-bottom-color:
|
|
222
|
+
border-bottom-color: $stack-tab-background-color-base;
|
|
239
223
|
box-shadow: $stack-tab-shadow-left, $stack-tab-shadow-right;
|
|
240
224
|
margin-top: unset;
|
|
241
225
|
}
|
|
242
226
|
|
|
243
227
|
&:hover,
|
|
244
|
-
|
|
228
|
+
&--active {
|
|
245
229
|
color: $stack-tab-color-primary;
|
|
230
|
+
}
|
|
246
231
|
|
|
247
|
-
|
|
232
|
+
// 可关闭标签在悬停/激活时给关闭按钮腾出空间
|
|
233
|
+
&--closable {
|
|
234
|
+
&:hover,
|
|
235
|
+
&.stack-tab__item--active {
|
|
248
236
|
padding: 0
|
|
249
237
|
($stack-tab-padding - math.div($stack-tab-button-size + $stack-tab-icon-margin, 2));
|
|
250
238
|
|
|
@@ -260,20 +248,15 @@
|
|
|
260
248
|
flex: 1 1 auto;
|
|
261
249
|
min-width: 0;
|
|
262
250
|
height: 100%;
|
|
263
|
-
padding: 0;
|
|
264
|
-
color: inherit;
|
|
265
251
|
cursor: inherit;
|
|
266
252
|
background: transparent;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
appearance: none;
|
|
253
|
+
padding: 0;
|
|
254
|
+
color: inherit;
|
|
255
|
+
@include button-reset;
|
|
271
256
|
align-items: center;
|
|
272
257
|
}
|
|
273
258
|
|
|
274
|
-
|
|
275
|
-
页签标题
|
|
276
|
-
*/
|
|
259
|
+
// 页签标题
|
|
277
260
|
&-title {
|
|
278
261
|
flex: 1 1 0;
|
|
279
262
|
display: flex;
|
|
@@ -287,41 +270,23 @@
|
|
|
287
270
|
}
|
|
288
271
|
}
|
|
289
272
|
|
|
290
|
-
|
|
291
|
-
页签图标
|
|
292
|
-
*/
|
|
273
|
+
// 页签图标
|
|
293
274
|
&-icon {
|
|
294
275
|
margin-right: 5px;
|
|
295
276
|
font-size: 16px;
|
|
296
277
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
*/
|
|
278
|
+
|
|
279
|
+
// 页签按钮
|
|
300
280
|
&-button {
|
|
301
281
|
height: 100%;
|
|
302
282
|
width: 0;
|
|
303
|
-
background-color: $stack-tab-text-color;
|
|
304
|
-
transition: $stack-tab__trans;
|
|
305
|
-
border: 0;
|
|
306
|
-
font: inherit;
|
|
307
|
-
appearance: none;
|
|
308
283
|
padding: 0;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
background-color: $stack-tab-color-primary;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
&:active {
|
|
315
|
-
/*
|
|
316
|
-
cursor: pointer;
|
|
317
|
-
*/
|
|
318
|
-
background-color: $stack-tab-color-primary-activate;
|
|
319
|
-
}
|
|
284
|
+
@include button-reset;
|
|
285
|
+
@include icon-button-color;
|
|
320
286
|
}
|
|
321
287
|
}
|
|
322
|
-
|
|
323
|
-
角徽样式
|
|
324
|
-
*/
|
|
288
|
+
|
|
289
|
+
// 角徽样式
|
|
325
290
|
&__badge {
|
|
326
291
|
position: relative;
|
|
327
292
|
display: inline-block;
|
|
@@ -335,87 +300,63 @@
|
|
|
335
300
|
padding: 0.3rem;
|
|
336
301
|
font-size: 0.5rem;
|
|
337
302
|
line-height: 0.4rem;
|
|
338
|
-
color:
|
|
303
|
+
color: $stack-tab-color-white;
|
|
339
304
|
text-align: center;
|
|
340
305
|
border: 1px solid $stack-tab-background-color-base;
|
|
341
306
|
border-radius: 0.5rem;
|
|
342
307
|
transform: translateX(100%) translateY(-50%);
|
|
343
308
|
box-sizing: border-box;
|
|
344
309
|
|
|
345
|
-
|
|
310
|
+
&--default {
|
|
346
311
|
background: $stack-tab-color-danger;
|
|
347
312
|
}
|
|
348
313
|
|
|
349
|
-
|
|
314
|
+
&--primary {
|
|
350
315
|
background: $stack-tab-color-primary;
|
|
351
316
|
}
|
|
352
317
|
}
|
|
353
318
|
}
|
|
354
319
|
|
|
355
320
|
&__iframes {
|
|
356
|
-
|
|
357
|
-
top: 0;
|
|
358
|
-
left: 0;
|
|
359
|
-
width: 100%;
|
|
360
|
-
height: 100%;
|
|
321
|
+
@include absolute-fill;
|
|
361
322
|
pointer-events: none;
|
|
362
323
|
}
|
|
363
324
|
|
|
364
325
|
&__iframe-wrapper {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
left: 0;
|
|
368
|
-
width: 100%;
|
|
369
|
-
height: 100%;
|
|
370
|
-
pointer-events: auto; /* 恢复鼠标事件,允许与 iframe 交互 */
|
|
326
|
+
@include absolute-fill;
|
|
327
|
+
pointer-events: auto; // 恢复鼠标事件,允许与 iframe 交互
|
|
371
328
|
}
|
|
372
329
|
|
|
373
330
|
&__iframe {
|
|
374
|
-
|
|
375
|
-
top: 0;
|
|
376
|
-
left: 0;
|
|
377
|
-
width: 100%;
|
|
378
|
-
height: 100%;
|
|
331
|
+
@include absolute-fill;
|
|
379
332
|
border: 0;
|
|
380
333
|
}
|
|
381
334
|
|
|
382
335
|
&__iframe-loading {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
left: 0;
|
|
336
|
+
@include absolute-fill;
|
|
337
|
+
@include flex-center;
|
|
386
338
|
z-index: 1;
|
|
387
|
-
|
|
388
|
-
align-items: center;
|
|
389
|
-
justify-content: center;
|
|
390
|
-
width: 100%;
|
|
391
|
-
height: 100%;
|
|
392
|
-
background: var(--stack-tab-iframe-loading-bg, #f5f5f5);
|
|
339
|
+
background: var(--stack-tab-iframe-loading-bg, #{$stack-tab-iframe-loading-bg});
|
|
393
340
|
|
|
394
341
|
&-text {
|
|
395
|
-
color: var(--stack-tab-iframe-loading-color, #
|
|
396
|
-
font-size: var(--stack-tab-font-size,
|
|
342
|
+
color: var(--stack-tab-iframe-loading-color, #{$stack-tab-iframe-loading-color});
|
|
343
|
+
font-size: var(--stack-tab-font-size, #{$stack-tab-font-size});
|
|
397
344
|
}
|
|
398
345
|
}
|
|
399
346
|
|
|
400
347
|
&__iframe-error {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
left: 0;
|
|
348
|
+
@include absolute-fill;
|
|
349
|
+
@include flex-center;
|
|
404
350
|
z-index: 2;
|
|
405
|
-
display: flex;
|
|
406
351
|
gap: 8px;
|
|
407
|
-
align-items: center;
|
|
408
|
-
justify-content: center;
|
|
409
|
-
width: 100%;
|
|
410
|
-
height: 100%;
|
|
411
352
|
padding: 16px;
|
|
412
353
|
pointer-events: auto;
|
|
413
|
-
background: var(--stack-tab-iframe-error-bg,
|
|
354
|
+
background: var(--stack-tab-iframe-error-bg, #{$stack-tab-iframe-error-bg});
|
|
414
355
|
box-sizing: border-box;
|
|
415
356
|
|
|
416
357
|
&-text {
|
|
417
|
-
color: var(--stack-tab-iframe-error-color, #
|
|
418
|
-
font-size: var(--stack-tab-font-size,
|
|
358
|
+
color: var(--stack-tab-iframe-error-color, #{$stack-tab-iframe-error-color});
|
|
359
|
+
font-size: var(--stack-tab-font-size, #{$stack-tab-font-size});
|
|
419
360
|
}
|
|
420
361
|
|
|
421
362
|
&-retry,
|
|
@@ -429,18 +370,17 @@
|
|
|
429
370
|
font: inherit;
|
|
430
371
|
}
|
|
431
372
|
}
|
|
432
|
-
|
|
433
|
-
右键菜单
|
|
434
|
-
|
|
435
|
-
&__contextmenu {
|
|
373
|
+
|
|
374
|
+
// 右键菜单
|
|
375
|
+
&__context-menu {
|
|
436
376
|
position: fixed;
|
|
437
377
|
z-index: 999;
|
|
438
378
|
min-width: 120px;
|
|
439
379
|
padding: 8px;
|
|
440
380
|
font-size: $stack-tab-font-size;
|
|
441
|
-
background:
|
|
381
|
+
background: $stack-tab-background-color-base;
|
|
442
382
|
border: $stack-tab-border;
|
|
443
|
-
border-radius:
|
|
383
|
+
border-radius: $stack-tab-contextmenu-radius;
|
|
444
384
|
box-shadow: $stack-tab-shadow-context-menu;
|
|
445
385
|
transform-origin: left top;
|
|
446
386
|
|
|
@@ -452,17 +392,14 @@
|
|
|
452
392
|
width: 100%;
|
|
453
393
|
min-height: 30px;
|
|
454
394
|
margin: 0;
|
|
395
|
+
@include button-reset;
|
|
455
396
|
padding: 0 10px;
|
|
456
397
|
line-height: 30px;
|
|
457
|
-
font: inherit;
|
|
458
|
-
text-align: inherit;
|
|
459
|
-
appearance: none;
|
|
460
398
|
box-sizing: border-box;
|
|
461
399
|
color: $stack-tab-text-color;
|
|
462
400
|
cursor: pointer;
|
|
463
401
|
background: transparent;
|
|
464
|
-
border:
|
|
465
|
-
border-radius: 10px 0;
|
|
402
|
+
border-radius: $stack-tab-contextmenu-radius;
|
|
466
403
|
// 仅过渡悬停态实际会改变的颜色,避免触发菜单布局与合成层的无关动画。
|
|
467
404
|
transition:
|
|
468
405
|
color 0.2s ease-in-out,
|
|
@@ -475,7 +412,7 @@
|
|
|
475
412
|
color: $stack-tab-color-white;
|
|
476
413
|
background-color: $stack-tab-color-primary;
|
|
477
414
|
|
|
478
|
-
.
|
|
415
|
+
.stack-tab__icon--mask {
|
|
479
416
|
background-color: $stack-tab-color-white;
|
|
480
417
|
}
|
|
481
418
|
}
|
|
@@ -490,7 +427,7 @@
|
|
|
490
427
|
cursor: default;
|
|
491
428
|
background: none;
|
|
492
429
|
|
|
493
|
-
.
|
|
430
|
+
.stack-tab__icon--mask {
|
|
494
431
|
background-color: $stack-tab-color-disabled;
|
|
495
432
|
}
|
|
496
433
|
}
|
|
@@ -501,7 +438,7 @@
|
|
|
501
438
|
height: $stack-tab-font-size;
|
|
502
439
|
transition: background-color 0.2s ease-in-out;
|
|
503
440
|
|
|
504
|
-
&.
|
|
441
|
+
&.stack-tab__icon--mask {
|
|
505
442
|
width: $stack-tab-font-size;
|
|
506
443
|
height: $stack-tab-font-size;
|
|
507
444
|
background-color: $stack-tab-text-color;
|
|
@@ -518,32 +455,29 @@
|
|
|
518
455
|
box-shadow: $stack-tab-shadow-right;
|
|
519
456
|
}
|
|
520
457
|
|
|
521
|
-
|
|
522
|
-
内阴影
|
|
523
|
-
*/
|
|
458
|
+
// 内阴影
|
|
524
459
|
.stack-tab__shadow-inset {
|
|
525
|
-
&-left
|
|
526
|
-
@include
|
|
527
|
-
box-shadow: $stack-tab-shadow-left-inset;
|
|
460
|
+
&-left {
|
|
461
|
+
@include inset-shadow($stack-tab-shadow-left-inset);
|
|
528
462
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
463
|
+
|
|
464
|
+
&-right {
|
|
465
|
+
@include inset-shadow($stack-tab-shadow-right-inset);
|
|
532
466
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
467
|
+
|
|
468
|
+
&-all {
|
|
469
|
+
@include inset-shadow($stack-tab-shadow-left-inset, $stack-tab-shadow-right-inset);
|
|
536
470
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
471
|
+
|
|
472
|
+
&-top {
|
|
473
|
+
@include inset-shadow($stack-tab-shadow-top-inset);
|
|
540
474
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
475
|
+
|
|
476
|
+
&-bottom {
|
|
477
|
+
@include inset-shadow($stack-tab-shadow-bottom-inset);
|
|
544
478
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
479
|
+
|
|
480
|
+
&-vertical {
|
|
481
|
+
@include inset-shadow($stack-tab-shadow-top-inset, $stack-tab-shadow-bottom-inset);
|
|
548
482
|
}
|
|
549
483
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
@use 'common/var' as *;
|
|
2
|
+
|
|
3
|
+
// 缩放淡入
|
|
4
4
|
.stack-tab-zoom {
|
|
5
5
|
&-enter-active,
|
|
6
6
|
&-leave-active {
|
|
7
|
-
transition:
|
|
7
|
+
transition: $stack-tab-transition-slide;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
&-enter-from,
|
|
@@ -14,16 +14,12 @@ transition 过渡样式
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
页面交换
|
|
19
|
-
*/
|
|
17
|
+
// 前进:从右向左滑入
|
|
20
18
|
.stack-tab-swap {
|
|
21
|
-
$trans: 30px;
|
|
22
|
-
|
|
23
19
|
&-move,
|
|
24
20
|
&-enter-active,
|
|
25
21
|
&-leave-active {
|
|
26
|
-
transition:
|
|
22
|
+
transition: $stack-tab-transition-slide;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
&-enter-from,
|
|
@@ -32,20 +28,19 @@ transition 过渡样式
|
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
&-enter-from {
|
|
35
|
-
transform: translateX($
|
|
31
|
+
transform: translateX($stack-tab-transition-slide-distance);
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
&-leave-to {
|
|
39
|
-
transform: translateX(-$
|
|
35
|
+
transform: translateX(-$stack-tab-transition-slide-distance);
|
|
40
36
|
}
|
|
41
37
|
}
|
|
42
38
|
|
|
39
|
+
// 后退:从左向右滑入
|
|
43
40
|
.stack-tab-swap-back {
|
|
44
|
-
$trans: 30px;
|
|
45
|
-
|
|
46
41
|
&-enter-active,
|
|
47
42
|
&-leave-active {
|
|
48
|
-
transition:
|
|
43
|
+
transition: $stack-tab-transition-slide;
|
|
49
44
|
}
|
|
50
45
|
|
|
51
46
|
&-enter-from,
|
|
@@ -54,10 +49,10 @@ transition 过渡样式
|
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
&-enter-from {
|
|
57
|
-
transform: translateX(-$
|
|
52
|
+
transform: translateX(-$stack-tab-transition-slide-distance);
|
|
58
53
|
}
|
|
59
54
|
|
|
60
55
|
&-leave-to {
|
|
61
|
-
transform: translateX($
|
|
56
|
+
transform: translateX($stack-tab-transition-slide-distance);
|
|
62
57
|
}
|
|
63
58
|
}
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
职责:展示图标和标题,支持 disabled 状态
|
|
5
5
|
-->
|
|
6
6
|
<template>
|
|
7
|
-
<button type="button" role="menuitem" class="stack-
|
|
8
|
-
<span class="stack-
|
|
9
|
-
<span class="stack-
|
|
7
|
+
<button type="button" role="menuitem" class="stack-tab__context-menu-item" :disabled="disabled">
|
|
8
|
+
<span class="stack-tab__context-menu-icon" :class="icon" aria-hidden="true" />
|
|
9
|
+
<span class="stack-tab__context-menu-title" @contextmenu.prevent>{{ title }}</span>
|
|
10
10
|
</button>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script setup lang="ts">
|
|
14
14
|
withDefaults(
|
|
15
15
|
defineProps<{
|
|
16
|
-
/** 图标 class,如 stack-tab__icon-reload
|
|
16
|
+
/** 图标 class,如 stack-tab__icon stack-tab__icon--reload stack-tab__icon--mask */
|
|
17
17
|
icon?: string
|
|
18
18
|
/** 显示文本 */
|
|
19
19
|
title: string
|
|
@@ -28,7 +28,7 @@ withDefaults(
|
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<style lang="scss" scoped>
|
|
31
|
-
.stack-
|
|
31
|
+
.stack-tab__context-menu-title {
|
|
32
32
|
margin-left: 8px;
|
|
33
33
|
}
|
|
34
34
|
</style>
|