vue-stack-tabs 0.1.8 → 0.1.10

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 (76) hide show
  1. package/README.md +2 -2
  2. package/dist/favicon.svg +9 -9
  3. package/dist/style.css +1 -1
  4. package/dist/vue-stack-tabs.es.js +727 -757
  5. package/dist/vue-stack-tabs.umd.js +10 -10
  6. package/package.json +4 -4
  7. package/src/lib/StackTabs.vue +126 -127
  8. package/src/lib/assets/style/common/mixins.scss +45 -45
  9. package/src/lib/assets/style/common/var.scss +65 -65
  10. package/src/lib/assets/style/icon.scss +93 -93
  11. package/src/lib/assets/style/index.scss +4 -4
  12. package/src/lib/assets/style/overlayer.scss +40 -40
  13. package/src/lib/assets/style/stackTab.scss +395 -395
  14. package/src/lib/assets/style/transition.scss +40 -40
  15. package/src/lib/banner.ts +51 -51
  16. package/src/lib/components/ContextMenu/ContextMenuItem.vue +15 -15
  17. package/src/lib/components/ContextMenu/index.vue +129 -128
  18. package/src/lib/components/OverlayLoading/Component.vue +191 -188
  19. package/src/lib/components/OverlayLoading/api.ts +31 -31
  20. package/src/lib/components/OverlayLoading/helpers.ts +31 -31
  21. package/src/lib/components/OverlayLoading/index.ts +12 -12
  22. package/src/lib/components/OverlayLoading/loaders/bars.vue +79 -79
  23. package/src/lib/components/OverlayLoading/loaders/dots.vue +92 -92
  24. package/src/lib/components/OverlayLoading/loaders/index.ts +9 -9
  25. package/src/lib/components/OverlayLoading/loaders/spinner.vue +41 -41
  26. package/src/lib/components/TabHeader/TabHeaderButton.vue +35 -35
  27. package/src/lib/components/TabHeader/TabHeaderItem.vue +63 -63
  28. package/src/lib/components/TabHeader/TabHeaderScroll.vue +240 -240
  29. package/src/lib/components/TabHeader/index.vue +135 -134
  30. package/src/lib/hooks/useContextMenu.ts +50 -50
  31. package/src/lib/hooks/useStackTab.ts +65 -65
  32. package/src/lib/hooks/useTabLoading.ts +34 -35
  33. package/src/lib/hooks/useTabRouter.ts +94 -95
  34. package/src/lib/hooks/useTabpanel.tsx +490 -490
  35. package/src/lib/i18n/index.ts +72 -72
  36. package/src/lib/i18n/lang/en.ts +15 -15
  37. package/src/lib/i18n/lang/zh-CN.ts +15 -15
  38. package/src/lib/iframe.vue +7 -7
  39. package/src/lib/index.ts +23 -23
  40. package/src/lib/model/TabModel.ts +169 -182
  41. package/src/lib/utils/TabIdHelper.ts +70 -70
  42. package/src/lib/utils/TabScrollHelper.ts +104 -104
  43. package/src/lib/utils/UriHelper.ts +22 -22
  44. package/types/index.d.ts +3 -11
  45. package/types/src/lib/StackTabs.vue.d.ts +122 -0
  46. package/types/src/lib/components/ContextMenu/ContextMenuItem.vue.d.ts +17 -0
  47. package/types/src/lib/components/ContextMenu/index.vue.d.ts +45 -0
  48. package/types/src/lib/components/OverlayLoading/Component.vue.d.ts +100 -0
  49. package/types/src/lib/components/OverlayLoading/api.d.ts +5 -0
  50. package/types/src/lib/components/OverlayLoading/helpers.d.ts +7 -0
  51. package/types/src/lib/components/OverlayLoading/index.d.ts +6 -0
  52. package/types/src/lib/components/OverlayLoading/loaders/bars.vue.d.ts +39 -0
  53. package/types/src/lib/components/OverlayLoading/loaders/dots.vue.d.ts +39 -0
  54. package/types/src/lib/components/OverlayLoading/loaders/index.d.ts +96 -0
  55. package/types/src/lib/components/OverlayLoading/loaders/spinner.vue.d.ts +39 -0
  56. package/types/src/lib/components/TabHeader/TabHeaderButton.vue.d.ts +48 -0
  57. package/types/src/lib/components/TabHeader/TabHeaderItem.vue.d.ts +21 -0
  58. package/types/src/lib/components/TabHeader/TabHeaderScroll.vue.d.ts +49 -0
  59. package/types/src/lib/components/TabHeader/index.vue.d.ts +64 -0
  60. package/types/src/lib/hooks/useContextMenu.d.ts +13 -0
  61. package/types/src/lib/hooks/useStackTab.d.ts +8 -0
  62. package/types/{hooks → src/lib/hooks}/useTabRouter.d.ts +2 -1
  63. package/types/src/lib/hooks/useTabpanel.d.ts +68 -0
  64. package/types/src/lib/i18n/index.d.ts +4 -0
  65. package/types/src/lib/i18n/lang/en.d.ts +16 -0
  66. package/types/src/lib/i18n/lang/zh-CN.d.ts +16 -0
  67. package/types/src/lib/iframe.vue.d.ts +2 -0
  68. package/types/src/lib/index.d.ts +12 -0
  69. package/types/{model → src/lib/model}/TabModel.d.ts +0 -20
  70. package/types/src/lib/utils/TabScrollHelper.d.ts +33 -0
  71. package/types/hooks/useStackTab.d.ts +0 -9
  72. package/types/iframe.vue.d.ts +0 -2
  73. /package/types/{banner.d.ts → src/lib/banner.d.ts} +0 -0
  74. /package/types/{hooks → src/lib/hooks}/useTabLoading.d.ts +0 -0
  75. /package/types/{utils → src/lib/utils}/TabIdHelper.d.ts +0 -0
  76. /package/types/{utils → src/lib/utils}/UriHelper.d.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-stack-tabs",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Vue.js component for router tab.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "main": "dist/vue-stack-tabs.umd.js",
13
13
  "module": "dist/vue-stack-tabs.es.js",
14
- "types": "types/index.d.ts",
14
+ "typings": "types/index.d.ts",
15
15
  "repository": {
16
16
  "type": "git",
17
17
  "url": "git+https://github.com/jktantan/vue-stack-tabs.git"
@@ -74,9 +74,9 @@
74
74
  "vite-plugin-package-version": "^1.1.0",
75
75
  "vite-plugin-require-transform": "^1.0.21",
76
76
  "vitepress": "1.0.0-rc.44",
77
- "vue-tsc": "^1.8.27",
77
+ "vue": "^3.4.21",
78
78
  "vue-router": "^4.3.0",
79
- "vue": "^3.4.21"
79
+ "vue-tsc": "^1.8.27"
80
80
  },
81
81
  "scripts": {
82
82
  "docs:dev": "vitepress dev docs",
@@ -1,127 +1,126 @@
1
- <template>
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>
42
- import { onBeforeMount, onUnmounted, provide, ref, watch } from 'vue'
43
- import type { TransitionProps, DefineComponent, VNode } from 'vue'
44
- import { type RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
45
- import { getMaxZIndex } from './utils/TabScrollHelper'
46
- import { type ITabData, TabScrollMode } from './model/TabModel'
47
- import TabHeader from './components/TabHeader/index.vue'
48
- import useTabpanel from './hooks/useTabpanel'
49
- import useStackTab from './hooks/useStackTab'
50
- const { tabs, pageShown, caches, addPage, destroy, initial } = useTabpanel()
51
- const emit = defineEmits(['onActive'])
52
- const props = withDefaults(
53
- defineProps<{
54
- // 初始页签数据
55
- defaultTabs?: ITabData[]
56
- // 最大打开数量
57
- max?: number
58
- // 新页加入哪个位置
59
- append?: string
60
- // 右键菜单
61
- contextmenu?: boolean | object
62
- // 页面转场效果
63
- pageTransition?: string
64
- // 标签转场效果
65
- tabTransition?: string | TransitionProps
66
- // tab 滚动效果
67
- tabScrollMode?: TabScrollMode
68
- width?: string
69
- height?: string
70
- i18n?: { locale?: string; messages?: object }
71
- messages?: any
72
- reloadable?: boolean
73
- closable?: boolean
74
- space?: number
75
- iframePath: string
76
- }>(),
77
- {
78
- defaultTabs: () => [],
79
- max: 20,
80
- append: 'last',
81
- contextmenu: true,
82
- tabTransition: 'stack-tab-zoom',
83
- pageTransition: 'stack-tab-swap',
84
- tabScrollMode: TabScrollMode.BOTH,
85
- width: '100%',
86
- height: '100%',
87
- i18n: () => ({ locale: 'zh-CN', messages: {} }),
88
- reloadable: true,
89
- closable: true,
90
- space: 300
91
- }
92
- )
93
- provide('locales', { ...props.i18n })
94
- // 最大化,并向下传递
95
- const maximum = ref<boolean>(false)
96
- provide('maximum', maximum)
97
- const { setIFramePath } = useStackTab()
98
- setIFramePath(props.iframePath)
99
- onBeforeMount(() => {
100
- console.log('on Before mount')
101
- initial(props.defaultTabs)
102
- })
103
- const tabWrapper = (route: RouteLocationNormalizedLoaded, component: VNode): DefineComponent => {
104
- // return defineAsyncComponent(() => addPage(route, component))
105
- return addPage(route, component)
106
- }
107
- const onTabActive = (id: string) => {
108
- emit('onActive', id)
109
- }
110
- onUnmounted(() => {
111
- destroy()
112
- })
113
- /**
114
- * 路由真正转换的时候才切换页面
115
- * 有keepalive或组装过Component的都会多次加载
116
- */
117
- const router = useRouter()
118
- watch(
119
- () => router.currentRoute.value.fullPath,
120
- () => {
121
- pageShown.value = true
122
- // routerLeaved.value = true
123
- console.log('route change')
124
- }
125
- )
126
- </script>
127
- <style scoped></style>
1
+ <script lang="ts" setup>
2
+ import { onBeforeMount, onUnmounted, provide, ref, watch } from 'vue'
3
+ import type { TransitionProps, DefineComponent, VNode } from 'vue'
4
+ import { type RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
5
+ import { getMaxZIndex } from './utils/TabScrollHelper'
6
+ import { type ITabData, TabScrollMode } from './model/TabModel'
7
+ import TabHeader from './components/TabHeader/index.vue'
8
+ import useTabpanel from './hooks/useTabpanel'
9
+ import useStackTab from './hooks/useStackTab'
10
+ const { tabs, pageShown, caches, addPage, destroy, initial } = useTabpanel()
11
+ const emit = defineEmits(['onActive'])
12
+ const props = withDefaults(
13
+ defineProps<{
14
+ // 初始页签数据
15
+ defaultTabs?: ITabData[]
16
+ // 最大打开数量
17
+ max?: number
18
+ // 新页加入哪个位置
19
+ append?: string
20
+ // 右键菜单
21
+ contextmenu?: boolean | object
22
+ // 页面转场效果
23
+ pageTransition?: string
24
+ // 标签转场效果
25
+ tabTransition?: string | TransitionProps
26
+ // tab 滚动效果
27
+ tabScrollMode?: TabScrollMode
28
+ width?: string
29
+ height?: string
30
+ i18n?: { locale?: string; messages?: object }
31
+ messages?: any
32
+ reloadable?: boolean
33
+ closable?: boolean
34
+ space?: number
35
+ iframePath: string
36
+ }>(),
37
+ {
38
+ defaultTabs: () => [],
39
+ max: 20,
40
+ append: 'last',
41
+ contextmenu: true,
42
+ tabTransition: 'stack-tab-zoom',
43
+ pageTransition: 'stack-tab-swap',
44
+ tabScrollMode: TabScrollMode.BOTH,
45
+ width: '100%',
46
+ height: '100%',
47
+ i18n: () => ({ locale: 'zh-CN', messages: {} }),
48
+ reloadable: true,
49
+ closable: true,
50
+ space: 300
51
+ }
52
+ )
53
+ provide('locales', { ...props.i18n })
54
+ // 最大化,并向下传递
55
+ const maximum = ref<boolean>(false)
56
+ provide('maximum', maximum)
57
+ const { setIFramePath } = useStackTab()
58
+ setIFramePath(props.iframePath)
59
+ onBeforeMount(() => {
60
+ console.log('on Before mount')
61
+ initial(props.defaultTabs)
62
+ })
63
+ const tabWrapper = (route: RouteLocationNormalizedLoaded, component: VNode): DefineComponent => {
64
+ // return defineAsyncComponent(() => addPage(route, component))
65
+ return addPage(route, component)
66
+ }
67
+ const onTabActive = (id: string) => {
68
+ emit('onActive', id)
69
+ }
70
+ onUnmounted(() => {
71
+ destroy()
72
+ })
73
+ /**
74
+ * 路由真正转换的时候才切换页面
75
+ * 有keepalive或组装过Component的都会多次加载
76
+ */
77
+ const router = useRouter()
78
+ watch(
79
+ () => router.currentRoute.value.fullPath,
80
+ () => {
81
+ pageShown.value = true
82
+ // routerLeaved.value = true
83
+ console.log('route change')
84
+ }
85
+ )
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>
126
+ <style scoped></style>
@@ -1,45 +1,45 @@
1
- @import 'var';
2
- /*
3
- icon按钮特效
4
- */
5
- @mixin icon_rotate($icon-size, $icon-margin, $icon-url) {
6
- width: $icon-size;
7
- height: $icon-size;
8
- margin-left: $icon-margin;
9
- background-color: $--stack-tab-text-color;
10
- mask: url($icon-url) no-repeat center center;
11
- mask-size: contain;
12
-
13
- &:hover {
14
- cursor: pointer;
15
- background-color: $--stack-tab-color-primary;
16
- animation: rotate-center 0.3s ease-in-out both;
17
- mask:
18
- url($icon-url),
19
- url('./image/mask.svg') no-repeat center center;
20
- mask-size: contain;
21
- mask-composite: xor;
22
- }
23
-
24
- &:active {
25
- /*
26
- cursor: pointer;
27
- */
28
- background-color: $--stack-tab-color-primary-activate;
29
- mask:
30
- url($icon-url),
31
- url('./image/mask.svg') no-repeat center center;
32
- mask-size: contain;
33
- mask-composite: xor;
34
- }
35
- }
36
-
37
- @mixin insetShadow() {
38
- content: '';
39
- position: absolute;
40
- left: 0;
41
- right: 0;
42
- top: 0;
43
- bottom: 0;
44
- pointer-events: none;
45
- }
1
+ @import 'var';
2
+ /*
3
+ icon按钮特效
4
+ */
5
+ @mixin icon_rotate($icon-size, $icon-margin, $icon-url) {
6
+ width: $icon-size;
7
+ height: $icon-size;
8
+ margin-left: $icon-margin;
9
+ background-color: $--stack-tab-text-color;
10
+ mask: url($icon-url) no-repeat center center;
11
+ mask-size: contain;
12
+
13
+ &:hover {
14
+ cursor: pointer;
15
+ background-color: $--stack-tab-color-primary;
16
+ animation: rotate-center 0.3s ease-in-out both;
17
+ mask:
18
+ url($icon-url),
19
+ url('./image/mask.svg') no-repeat center center;
20
+ mask-size: contain;
21
+ mask-composite: xor;
22
+ }
23
+
24
+ &:active {
25
+ /*
26
+ cursor: pointer;
27
+ */
28
+ background-color: $--stack-tab-color-primary-activate;
29
+ mask:
30
+ url($icon-url),
31
+ url('./image/mask.svg') no-repeat center center;
32
+ mask-size: contain;
33
+ mask-composite: xor;
34
+ }
35
+ }
36
+
37
+ @mixin insetShadow() {
38
+ content: '';
39
+ position: absolute;
40
+ left: 0;
41
+ right: 0;
42
+ top: 0;
43
+ bottom: 0;
44
+ pointer-events: none;
45
+ }
@@ -1,65 +1,65 @@
1
- /*
2
- 主色调
3
- */
4
- $--stack-tab-color-primary: #409eff !default;
5
- $--stack-tab-color-primary-invert: #ffac30 !default;
6
- /*
7
- 大红色
8
- */
9
- $--stack-tab-color-danger: #ef4f4f !default;
10
- /*
11
- 白色
12
- */
13
- $--stack-tab-color-white: #fff !default;
14
- /*
15
- 黑色
16
- */
17
- $--stack-tab-color-black: #000 !default;
18
- $--stack-tab-color-grey: #4d4d4d !default;
19
- $--stack-tab-color-disabled: #aaa !default;
20
- /*
21
- ICON点击颜色
22
- */
23
- $--stack-tab-color-primary-activate: mix($--stack-tab-color-primary, #000, 80%) !default;
24
- /*
25
- 背景颜色
26
- */
27
- $--stack-tab-background-color-base: #fff !default;
28
- $--stack-tab-background-color-inactive: #fafafa !default;
29
- /*
30
- tab边框颜色
31
- */
32
- $--stack-tab-border-color: #f0f0f0;
33
- $--stack-tab-border: 1px solid $--stack-tab-border-color;
34
- /*
35
- tab文本颜色
36
- */
37
- $--stack-tab-text-color: $--stack-tab-color-grey;
38
- /*
39
- tab文本大小
40
- */
41
- $--stack-tab-font-size: 14px;
42
-
43
- $--stack-tab-padding: 24px;
44
- $--stack-tab-icon-margin: 4px;
45
- $--stack-tab-icon-size: 14px;
46
-
47
- $--stack-tab-button-size: 20px;
48
- /*
49
- tab头高度
50
- */
51
- $--stack-tab-head-height: 40px;
52
- $--stack-tab-head-invalid-height: $--stack-tab-head-height -3px;
53
-
54
- $--stack-tab-scroll-height: 6px;
55
- $--stack-tab-scroll-border-radius: $--stack-tab-scroll-height;
56
- $--stack-tab__trans: all 0.15s ease-in-out;
57
-
58
- /*
59
- 阴影
60
- */
61
- $--stack-tab-shadow-left: -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
62
- $--stack-tab-shadow-right: 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
63
- $--stack-tab-shadow-right-inset: inset -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
64
- $--stack-tab-shadow-left-inset: inset 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
65
- $--stack-tab-shadow-context-menu: 5px 5px 5px rgb(0 0 0 / 10%);
1
+ /*
2
+ 主色调
3
+ */
4
+ $--stack-tab-color-primary: #409eff !default;
5
+ $--stack-tab-color-primary-invert: #ffac30 !default;
6
+ /*
7
+ 大红色
8
+ */
9
+ $--stack-tab-color-danger: #ef4f4f !default;
10
+ /*
11
+ 白色
12
+ */
13
+ $--stack-tab-color-white: #fff !default;
14
+ /*
15
+ 黑色
16
+ */
17
+ $--stack-tab-color-black: #000 !default;
18
+ $--stack-tab-color-grey: #4d4d4d !default;
19
+ $--stack-tab-color-disabled: #aaa !default;
20
+ /*
21
+ ICON点击颜色
22
+ */
23
+ $--stack-tab-color-primary-activate: mix($--stack-tab-color-primary, #000, 80%) !default;
24
+ /*
25
+ 背景颜色
26
+ */
27
+ $--stack-tab-background-color-base: #fff !default;
28
+ $--stack-tab-background-color-inactive: #fafafa !default;
29
+ /*
30
+ tab边框颜色
31
+ */
32
+ $--stack-tab-border-color: #f0f0f0;
33
+ $--stack-tab-border: 1px solid $--stack-tab-border-color;
34
+ /*
35
+ tab文本颜色
36
+ */
37
+ $--stack-tab-text-color: $--stack-tab-color-grey;
38
+ /*
39
+ tab文本大小
40
+ */
41
+ $--stack-tab-font-size: 14px;
42
+
43
+ $--stack-tab-padding: 24px;
44
+ $--stack-tab-icon-margin: 4px;
45
+ $--stack-tab-icon-size: 14px;
46
+
47
+ $--stack-tab-button-size: 20px;
48
+ /*
49
+ tab头高度
50
+ */
51
+ $--stack-tab-head-height: 40px;
52
+ $--stack-tab-head-invalid-height: $--stack-tab-head-height -3px;
53
+
54
+ $--stack-tab-scroll-height: 6px;
55
+ $--stack-tab-scroll-border-radius: $--stack-tab-scroll-height;
56
+ $--stack-tab__trans: all 0.15s ease-in-out;
57
+
58
+ /*
59
+ 阴影
60
+ */
61
+ $--stack-tab-shadow-left: -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
62
+ $--stack-tab-shadow-right: 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
63
+ $--stack-tab-shadow-right-inset: inset -5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
64
+ $--stack-tab-shadow-left-inset: inset 5px 0 5px -5px rgb(0 0 0 / 60%); //#ccc;
65
+ $--stack-tab-shadow-context-menu: 5px 5px 5px rgb(0 0 0 / 10%);