vue-stack-tabs 0.1.12 → 0.1.13

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 (72) hide show
  1. package/{types → dist}/src/lib/hooks/useStackTab.d.ts +2 -2
  2. package/{types → dist}/src/lib/hooks/useTabpanel.d.ts +6 -2
  3. package/{types → dist}/src/lib/index.d.ts +5 -0
  4. package/{types → dist}/src/lib/model/TabModel.d.ts +2 -1
  5. package/dist/style.css +1 -1
  6. package/dist/vue-stack-tabs.es.js +2340 -2322
  7. package/dist/vue-stack-tabs.umd.js +10 -10
  8. package/package.json +3 -4
  9. package/src/lib/StackTabs.vue +136 -126
  10. package/src/lib/assets/style/common/mixins.scss +45 -45
  11. package/src/lib/assets/style/common/var.scss +65 -65
  12. package/src/lib/assets/style/icon.scss +93 -93
  13. package/src/lib/assets/style/index.scss +4 -4
  14. package/src/lib/assets/style/overlayer.scss +40 -40
  15. package/src/lib/assets/style/stackTab.scss +395 -395
  16. package/src/lib/assets/style/transition.scss +40 -40
  17. package/src/lib/banner.ts +51 -51
  18. package/src/lib/components/ContextMenu/ContextMenuItem.vue +15 -15
  19. package/src/lib/components/ContextMenu/index.vue +129 -129
  20. package/src/lib/components/OverlayLoading/Component.vue +182 -191
  21. package/src/lib/components/OverlayLoading/api.ts +31 -31
  22. package/src/lib/components/OverlayLoading/helpers.ts +31 -31
  23. package/src/lib/components/OverlayLoading/index.ts +12 -12
  24. package/src/lib/components/OverlayLoading/loaders/bars.vue +79 -79
  25. package/src/lib/components/OverlayLoading/loaders/dots.vue +92 -92
  26. package/src/lib/components/OverlayLoading/loaders/index.ts +9 -9
  27. package/src/lib/components/OverlayLoading/loaders/spinner.vue +41 -41
  28. package/src/lib/components/TabHeader/TabHeaderButton.vue +35 -35
  29. package/src/lib/components/TabHeader/TabHeaderItem.vue +63 -63
  30. package/src/lib/components/TabHeader/TabHeaderScroll.vue +240 -240
  31. package/src/lib/components/TabHeader/index.vue +135 -135
  32. package/src/lib/hooks/useContextMenu.ts +50 -50
  33. package/src/lib/hooks/useStackTab.ts +74 -65
  34. package/src/lib/hooks/useTabLoading.ts +34 -34
  35. package/src/lib/hooks/useTabRouter.ts +94 -94
  36. package/src/lib/hooks/useTabpanel.tsx +516 -491
  37. package/src/lib/i18n/index.ts +72 -72
  38. package/src/lib/i18n/lang/en.ts +15 -15
  39. package/src/lib/i18n/lang/zh-CN.ts +15 -15
  40. package/src/lib/iframe.vue +7 -7
  41. package/src/lib/index.ts +32 -24
  42. package/src/lib/model/TabModel.ts +178 -169
  43. package/src/lib/utils/TabIdHelper.ts +70 -70
  44. package/src/lib/utils/TabScrollHelper.ts +104 -104
  45. package/src/lib/utils/UriHelper.ts +22 -22
  46. /package/{types → dist}/index.d.ts +0 -0
  47. /package/{types → dist}/src/lib/StackTabs.vue.d.ts +0 -0
  48. /package/{types → dist}/src/lib/banner.d.ts +0 -0
  49. /package/{types → dist}/src/lib/components/ContextMenu/ContextMenuItem.vue.d.ts +0 -0
  50. /package/{types → dist}/src/lib/components/ContextMenu/index.vue.d.ts +0 -0
  51. /package/{types → dist}/src/lib/components/OverlayLoading/Component.vue.d.ts +0 -0
  52. /package/{types → dist}/src/lib/components/OverlayLoading/api.d.ts +0 -0
  53. /package/{types → dist}/src/lib/components/OverlayLoading/helpers.d.ts +0 -0
  54. /package/{types → dist}/src/lib/components/OverlayLoading/index.d.ts +0 -0
  55. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/bars.vue.d.ts +0 -0
  56. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/dots.vue.d.ts +0 -0
  57. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/index.d.ts +0 -0
  58. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/spinner.vue.d.ts +0 -0
  59. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderButton.vue.d.ts +0 -0
  60. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderItem.vue.d.ts +0 -0
  61. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderScroll.vue.d.ts +0 -0
  62. /package/{types → dist}/src/lib/components/TabHeader/index.vue.d.ts +0 -0
  63. /package/{types → dist}/src/lib/hooks/useContextMenu.d.ts +0 -0
  64. /package/{types → dist}/src/lib/hooks/useTabLoading.d.ts +0 -0
  65. /package/{types → dist}/src/lib/hooks/useTabRouter.d.ts +0 -0
  66. /package/{types → dist}/src/lib/i18n/index.d.ts +0 -0
  67. /package/{types → dist}/src/lib/i18n/lang/en.d.ts +0 -0
  68. /package/{types → dist}/src/lib/i18n/lang/zh-CN.d.ts +0 -0
  69. /package/{types → dist}/src/lib/iframe.vue.d.ts +0 -0
  70. /package/{types → dist}/src/lib/utils/TabIdHelper.d.ts +0 -0
  71. /package/{types → dist}/src/lib/utils/TabScrollHelper.d.ts +0 -0
  72. /package/{types → dist}/src/lib/utils/UriHelper.d.ts +0 -0
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "vue-stack-tabs",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Vue.js component for router tab.",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "files": [
8
8
  "src/lib",
9
- "dist",
10
- "types"
9
+ "dist"
11
10
  ],
12
11
  "main": "dist/vue-stack-tabs.umd.js",
13
12
  "module": "dist/vue-stack-tabs.es.js",
14
- "typings": "types/index.d.ts",
13
+ "typings": "dist/index.d.ts",
15
14
  "repository": {
16
15
  "type": "git",
17
16
  "url": "git+https://github.com/jktantan/vue-stack-tabs.git"
@@ -1,126 +1,136 @@
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
+ <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,setMaxSize } = 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
+ setMaxSize(props.max)
71
+ onUnmounted(() => {
72
+ destroy()
73
+ })
74
+ /**
75
+ * 路由真正转换的时候才切换页面
76
+ * 有keepalive或组装过Component的都会多次加载
77
+ */
78
+ const router = useRouter()
79
+ watch(
80
+ () => router.currentRoute.value.fullPath,
81
+ () => {
82
+ pageShown.value = true
83
+ // routerLeaved.value = true
84
+ console.log('route change')
85
+ }
86
+ )
87
+ </script>
88
+ <template>
89
+ <div
90
+ class="stack-tab"
91
+ :style="{
92
+ width: width,
93
+ height: height,
94
+ 'z-index': maximum ? getMaxZIndex('body *:not(.stack-tab,.stack-tab *)') : undefined
95
+ }"
96
+ :class="{ 'stack-tab__maximum': maximum }"
97
+ >
98
+ <tab-header :space="space" @active="onTabActive" :tab-transition="tabTransition" :max="max">
99
+ <template #leftButton>
100
+ <slot name="leftButton" />
101
+ </template>
102
+ <template #rightButton>
103
+ <slot name="rightButton" />
104
+ </template>
105
+ </tab-header>
106
+ <div class="stack-tab__container">
107
+ <router-view v-slot="{ Component, route }">
108
+ <transition :name="pageTransition" appear @after-leave="pageShown = true">
109
+ <keep-alive :include="caches">
110
+ <suspense>
111
+ <template #default>
112
+ <component
113
+ :is="tabWrapper(route, Component)"
114
+ v-if="pageShown"
115
+ :key="route.fullPath"
116
+ />
117
+ </template>
118
+ <template #fallback> Loading.... </template>
119
+ </suspense>
120
+ </keep-alive>
121
+ </transition>
122
+ </router-view>
123
+ <transition-group :name="pageTransition" appear>
124
+ <iframe
125
+ v-for="frame of tabs.filter((item) => item.iframe)"
126
+ v-show="frame.active && pageShown"
127
+ :key="frame.id"
128
+ class="stack-tab__iframe"
129
+ :src="/^(javascript|data):/i.test(frame.url ?? '') ? 'about:blank' : frame.url"
130
+ frameborder="0"
131
+ />
132
+ </transition-group>
133
+ </div>
134
+ </div>
135
+ </template>
136
+ <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%);