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.
Files changed (71) 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 +5 -2
  5. package/dist/components/ContextMenu/ContextMenuItem.vue.d.ts +1 -1
  6. package/dist/components/StackKeepAlive/StackCacheRenderer.vue.d.ts +0 -2
  7. package/dist/hooks/stackTabsContext.d.ts +0 -1
  8. package/dist/hooks/tabPanel/evict.d.ts +2 -2
  9. package/dist/hooks/tabPanel/refresh.d.ts +4 -2
  10. package/dist/hooks/tabPanel/scroll.d.ts +0 -2
  11. package/dist/hooks/tabPanel/state.d.ts +0 -1
  12. package/dist/hooks/tabPanel/tabStore.d.ts +12 -1
  13. package/dist/hooks/useIframeManager.d.ts +1 -1
  14. package/dist/hooks/useScrollShadow.d.ts +11 -2
  15. package/dist/hooks/useTabActions.d.ts +1 -0
  16. package/dist/hooks/useTabEventBus.d.ts +5 -0
  17. package/dist/hooks/useTabPanel.d.ts +14 -2
  18. package/dist/model/TabModel.d.ts +17 -5
  19. package/dist/nuxt/module.mjs +1 -1
  20. package/dist/nuxt/runtime/plugin.mjs +8 -1598
  21. package/dist/style.css +1 -1
  22. package/dist/utils/scrollUtils.d.ts +0 -2
  23. package/dist/utils/tabInfoEncoder.d.ts +8 -0
  24. package/dist/utils/urlParser.d.ts +20 -10
  25. package/dist/vue-stack-tabs.es.js +1 -1
  26. package/package.json +4 -7
  27. package/src/lib/StackTabs.vue +40 -3
  28. package/src/lib/assets/image/close_all.svg +1 -9
  29. package/src/lib/assets/image/close_lefts.svg +1 -1
  30. package/src/lib/assets/image/close_other.svg +1 -1
  31. package/src/lib/assets/image/close_rights.svg +1 -1
  32. package/src/lib/assets/image/reload.svg +1 -3
  33. package/src/lib/assets/image/reload_all.svg +1 -6
  34. package/src/lib/assets/style/common/mixins.scss +58 -19
  35. package/src/lib/assets/style/common/var.scss +100 -60
  36. package/src/lib/assets/style/icon.scss +31 -98
  37. package/src/lib/assets/style/index.scss +2 -2
  38. package/src/lib/assets/style/loading.scss +45 -0
  39. package/src/lib/assets/style/{stackTab.scss → stack-tab.scss} +116 -182
  40. package/src/lib/assets/style/transition.scss +12 -17
  41. package/src/lib/components/ContextMenu/ContextMenuItem.vue +5 -5
  42. package/src/lib/components/ContextMenu/index.vue +22 -19
  43. package/src/lib/components/PageLoading.vue +12 -11
  44. package/src/lib/components/StackKeepAlive/StackCacheRenderer.vue +1 -5
  45. package/src/lib/components/StackKeepAlive/StackKeepAlive.vue +5 -3
  46. package/src/lib/components/TabHeader/TabHeaderItem.vue +13 -7
  47. package/src/lib/components/TabHeader/TabHeaderScroll.vue +170 -94
  48. package/src/lib/components/TabHeader/index.vue +67 -12
  49. package/src/lib/hooks/stackTabsContext.ts +0 -1
  50. package/src/lib/hooks/tabPanel/evict.ts +14 -6
  51. package/src/lib/hooks/tabPanel/pageComponentFactory.tsx +252 -7
  52. package/src/lib/hooks/tabPanel/refresh.ts +27 -9
  53. package/src/lib/hooks/tabPanel/scroll.ts +4 -15
  54. package/src/lib/hooks/tabPanel/session.ts +11 -4
  55. package/src/lib/hooks/tabPanel/state.ts +0 -2
  56. package/src/lib/hooks/tabPanel/tabStore.ts +114 -26
  57. package/src/lib/hooks/useContextMenu.ts +1 -1
  58. package/src/lib/hooks/useIframeManager.ts +21 -18
  59. package/src/lib/hooks/useScrollShadow.ts +74 -19
  60. package/src/lib/hooks/useTabActions.ts +18 -8
  61. package/src/lib/hooks/useTabEventBus.ts +3 -0
  62. package/src/lib/hooks/useTabPanel.tsx +247 -58
  63. package/src/lib/hooks/useTabRouter.ts +18 -11
  64. package/src/lib/model/TabModel.ts +19 -5
  65. package/src/lib/nuxt/module.ts +3 -1
  66. package/src/lib/nuxt/runtime/plugin.ts +7 -3
  67. package/src/lib/utils/scrollUtils.ts +0 -18
  68. package/src/lib/utils/tabInfoEncoder.ts +121 -18
  69. package/src/lib/utils/urlParser.ts +75 -48
  70. package/dist/vue-stack-tabs.css +0 -2
  71. 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
- grid-gap: 5px;
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
- position: absolute;
19
- top: 0;
20
- left: 0;
21
- width: 100%;
22
- height: 100%;
19
+ @include absolute-fill;
23
20
  }
24
21
 
25
- /*缓存页面wrapper*/
26
- .cache-page-wrapper {
22
+ // 缓存页面 wrapper
23
+ &__cache-page-wrapper {
27
24
  width: 100%;
28
25
  height: 100%;
29
26
  }
30
- &__maximum {
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
- transition: $stack-tab__trans;
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
- font: inherit;
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
- //tab header上的滚动条
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
- overflow: hidden;
112
-
113
- // 移动设备原生滚动
114
- &.is-mobile {
115
- overflow-x: auto;
116
- overflow-y: hidden;
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: rgb(0 0 0 / 10%);
116
+ background-color: $stack-tab-color-scrollbar;
128
117
  border-radius: $stack-tab-scroll-border-radius;
129
118
  opacity: 0;
130
- transition: $stack-tab__trans;
119
+ transition: $stack-tab-transition-fast;
131
120
 
132
121
  .stack-tab__scroll:hover &,
133
- &.is-dragging {
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: rgba(0, 0, 0, 0.1);
143
-
132
+ background-color: $stack-tab-color-scrollbar;
144
133
  border-radius: $stack-tab-scroll-border-radius;
145
- transition: background-color 0.3s ease-in-out;
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.is-dragging &,
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: 8px 8px 0 0;
188
- transition: $stack-tab__trans;
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
- &.is-dragging {
188
+ &--dragging {
201
189
  opacity: 0.55;
202
190
  }
203
191
 
204
- &.is-drop-before::before,
205
- &.is-drop-after::after {
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
- &.is-drop-before::before {
205
+ &--drop-before::before {
218
206
  left: -3px;
219
207
  }
220
208
 
221
- &.is-drop-after::after {
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: #fff;
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
- &.is-active {
228
+ &--active {
245
229
  color: $stack-tab-color-primary;
230
+ }
246
231
 
247
- &.is-icon {
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
- border: 0;
268
- font: inherit;
269
- text-align: inherit;
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
- &:hover {
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: #fff;
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
- &.default {
310
+ &--default {
346
311
  background: $stack-tab-color-danger;
347
312
  }
348
313
 
349
- &.primary {
314
+ &--primary {
350
315
  background: $stack-tab-color-primary;
351
316
  }
352
317
  }
353
318
  }
354
319
 
355
320
  &__iframes {
356
- position: absolute;
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
- position: absolute;
366
- top: 0;
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
- position: absolute;
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
- position: absolute;
384
- top: 0;
385
- left: 0;
336
+ @include absolute-fill;
337
+ @include flex-center;
386
338
  z-index: 1;
387
- display: flex;
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, #999);
396
- font-size: var(--stack-tab-font-size, 14px);
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
- position: absolute;
402
- top: 0;
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, rgb(255 255 255 / 92%));
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, #666);
418
- font-size: var(--stack-tab-font-size, 14px);
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: #fff;
381
+ background: $stack-tab-background-color-base;
442
382
  border: $stack-tab-border;
443
- border-radius: 10px 0;
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: 0;
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
- .svg-mask {
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
- .svg-mask {
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
- &.svg-mask {
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::after {
526
- @include mixins.insetShadow();
527
- box-shadow: $stack-tab-shadow-left-inset;
460
+ &-left {
461
+ @include inset-shadow($stack-tab-shadow-left-inset);
528
462
  }
529
- &-right::after {
530
- @include mixins.insetShadow();
531
- box-shadow: $stack-tab-shadow-right-inset;
463
+
464
+ &-right {
465
+ @include inset-shadow($stack-tab-shadow-right-inset);
532
466
  }
533
- &-all::after {
534
- @include mixins.insetShadow();
535
- box-shadow: $stack-tab-shadow-left-inset, $stack-tab-shadow-right-inset;
467
+
468
+ &-all {
469
+ @include inset-shadow($stack-tab-shadow-left-inset, $stack-tab-shadow-right-inset);
536
470
  }
537
- &-top::after {
538
- @include mixins.insetShadow();
539
- box-shadow: $stack-tab-shadow-top-inset;
471
+
472
+ &-top {
473
+ @include inset-shadow($stack-tab-shadow-top-inset);
540
474
  }
541
- &-bottom::after {
542
- @include mixins.insetShadow();
543
- box-shadow: $stack-tab-shadow-bottom-inset;
475
+
476
+ &-bottom {
477
+ @include inset-shadow($stack-tab-shadow-bottom-inset);
544
478
  }
545
- &-vertical::after {
546
- @include mixins.insetShadow();
547
- box-shadow: $stack-tab-shadow-top-inset, $stack-tab-shadow-bottom-inset;
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
- transition 过渡样式
3
- */
1
+ @use 'common/var' as *;
2
+
3
+ // 缩放淡入
4
4
  .stack-tab-zoom {
5
5
  &-enter-active,
6
6
  &-leave-active {
7
- transition: all 0.3s ease-in-out;
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: all 0.3s ease-in-out;
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($trans);
31
+ transform: translateX($stack-tab-transition-slide-distance);
36
32
  }
37
33
 
38
34
  &-leave-to {
39
- transform: translateX(-$trans);
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: all 0.3s ease-in-out;
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(-$trans);
52
+ transform: translateX(-$stack-tab-transition-slide-distance);
58
53
  }
59
54
 
60
55
  &-leave-to {
61
- transform: translateX($trans);
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-tab__contextmenu-item" :disabled="disabled">
8
- <span class="stack-tab__contextmenu-icon" :class="icon" aria-hidden="true" />
9
- <span class="stack-tab__contextmenu-title" @contextmenu.prevent>{{ title }}</span>
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 svg-mask */
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-tab__contextmenu-title {
31
+ .stack-tab__context-menu-title {
32
32
  margin-left: 8px;
33
33
  }
34
34
  </style>