@peng_kai/kit 0.0.8 → 0.0.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.
- package/admin/components/scroll-nav/index.ts +1 -0
- package/admin/components/scroll-nav/src/ScrollNav.vue +59 -0
- package/admin/components/text/index.ts +13 -13
- package/admin/components/text/src/Amount.vue +114 -114
- package/admin/components/text/src/Datetime.vue +44 -45
- package/admin/components/text/src/Duration.vue +26 -26
- package/admin/components/text/src/Hash.vue +40 -40
- package/admin/components/text/src/createTagGetter.ts +13 -13
- package/admin/filter/FilterDrawer.vue +96 -96
- package/admin/filter/FilterParam.vue +76 -76
- package/admin/hooks/useMenu.ts +128 -128
- package/admin/hooks/usePage.ts +139 -138
- package/admin/hooks/usePageTab.ts +35 -35
- package/admin/layout/large/Breadcrumb.vue +70 -0
- package/admin/layout/large/Content.vue +24 -0
- package/admin/layout/large/Menu.vue +68 -0
- package/admin/layout/large/PageTab.vue +71 -0
- package/admin/layout/large/index.ts +4 -0
- package/antd/components/InputNumberRange.vue +47 -47
- package/antd/hooks/useAntdDrawer.ts +73 -73
- package/antd/hooks/useAntdTable.ts +70 -70
- package/components/infinite-query/index.ts +1 -1
- package/components/infinite-query/src/InfiniteQuery.vue +147 -147
- package/components/infinite-query/src/useCreateTrigger.ts +35 -35
- package/kitDependencies.ts +26 -5
- package/package.json +40 -40
- package/request/helpers.ts +32 -32
- package/request/type.d.ts +89 -89
- package/tsconfig.json +17 -17
- package/pnpm-lock.yaml +0 -598
package/admin/hooks/usePage.ts
CHANGED
|
@@ -1,138 +1,139 @@
|
|
|
1
|
-
import { createGlobalState, usePrevious } from '@vueuse/core'
|
|
2
|
-
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|
3
|
-
import { shallowRef, ref, reactive, computed, watch, readonly } from 'vue'
|
|
4
|
-
import type { VNode } from 'vue'
|
|
5
|
-
import { useMenu } from './useMenu'
|
|
6
|
-
import type { TMenu } from './useMenu'
|
|
7
|
-
import { getTitle } from '../defines/defineRoute.helpers'
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
export { usePage }
|
|
11
|
-
export type { TPageState, IBreadcrumb }
|
|
12
|
-
|
|
13
|
-
type TPageState = ReturnType<typeof getPageState>
|
|
14
|
-
|
|
15
|
-
interface IBreadcrumb {
|
|
16
|
-
title: string
|
|
17
|
-
icon?: VNode | null
|
|
18
|
-
trigger?: () => void
|
|
19
|
-
children?: IBreadcrumb[]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const usePage = createGlobalState(() => {
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
cacheIndex
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
1
|
+
import { createGlobalState, usePrevious } from '@vueuse/core'
|
|
2
|
+
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|
3
|
+
import { shallowRef, ref, reactive, computed, watch, readonly } from 'vue'
|
|
4
|
+
import type { VNode } from 'vue'
|
|
5
|
+
import { useMenu } from './useMenu'
|
|
6
|
+
import type { TMenu } from './useMenu'
|
|
7
|
+
import { getTitle } from '../defines/defineRoute.helpers'
|
|
8
|
+
import { getDependencies } from "../../kitDependencies";
|
|
9
|
+
|
|
10
|
+
export { usePage }
|
|
11
|
+
export type { TPageState, IBreadcrumb }
|
|
12
|
+
|
|
13
|
+
type TPageState = ReturnType<typeof getPageState>
|
|
14
|
+
|
|
15
|
+
interface IBreadcrumb {
|
|
16
|
+
title: string
|
|
17
|
+
icon?: VNode | null
|
|
18
|
+
trigger?: () => void
|
|
19
|
+
children?: IBreadcrumb[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const usePage = createGlobalState(() => {
|
|
23
|
+
const { useRouter } = getDependencies()
|
|
24
|
+
const router = useRouter()
|
|
25
|
+
const currentPageNode = shallowRef<VNode>()
|
|
26
|
+
const currentPageKey = ref('')
|
|
27
|
+
const pageCacheList = reactive<string[]>([])
|
|
28
|
+
const pageStateMap = new Map<string, TPageState>()
|
|
29
|
+
const currentPageState = computed(() => pageStateMap.get(currentPageKey.value))
|
|
30
|
+
const previousPageState = usePrevious(currentPageState)
|
|
31
|
+
|
|
32
|
+
const openPage = (key: string) => {
|
|
33
|
+
const route = pageStateMap.get(key)?.route
|
|
34
|
+
|
|
35
|
+
if (!route)
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
router.push(route.fullPath)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const closePage = (key: string) => {
|
|
42
|
+
if (!pageStateMap.has(key))
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
const cacheIndex = pageCacheList.indexOf(key)
|
|
46
|
+
cacheIndex >= 0 && pageCacheList.splice(cacheIndex, 1)
|
|
47
|
+
// 关闭当前页面则返回上一个路由
|
|
48
|
+
currentPageKey.value === key && router.go(-1)
|
|
49
|
+
pageStateMap.delete(key)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const setPage = (pageNode: VNode, route: RouteLocationNormalizedLoaded) => {
|
|
53
|
+
const pageKey = route?.meta?.pageKeyFn?.(route) ?? route.fullPath
|
|
54
|
+
const pageInfo = getPageState(route)
|
|
55
|
+
const canKeepAlive = route.meta.keepAlive && !pageCacheList.includes(pageKey)
|
|
56
|
+
|
|
57
|
+
canKeepAlive && pageCacheList.push(pageKey)
|
|
58
|
+
pageStateMap.has(pageKey) || pageStateMap.set(pageKey, pageInfo)
|
|
59
|
+
|
|
60
|
+
;(pageNode as any).type.name = pageKey
|
|
61
|
+
currentPageKey.value = pageKey
|
|
62
|
+
currentPageNode.value = pageNode
|
|
63
|
+
|
|
64
|
+
return pageNode
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const getCurrentPageState = () => {
|
|
68
|
+
return pageStateMap.get(currentPageKey.value)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 监听 title 变化
|
|
72
|
+
watch(() => currentPageState.value?.title, (title) => {
|
|
73
|
+
let _title = title
|
|
74
|
+
|
|
75
|
+
if (!_title) {
|
|
76
|
+
const pageState = currentPageState.value
|
|
77
|
+
|
|
78
|
+
// 当前 title 为空时,使用路由 title
|
|
79
|
+
if (pageState) {
|
|
80
|
+
_title = getTitle(pageState?.route)
|
|
81
|
+
pageState.title = _title!
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
document.title = _title!
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
currentPageNode,
|
|
90
|
+
pageCacheList,
|
|
91
|
+
pageStateMap,
|
|
92
|
+
currentPageKey,
|
|
93
|
+
currentPageState,
|
|
94
|
+
getCurrentPageState,
|
|
95
|
+
previousPageState,
|
|
96
|
+
setPage,
|
|
97
|
+
openPage,
|
|
98
|
+
closePage,
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
function getPageState(route: RouteLocationNormalizedLoaded) {
|
|
103
|
+
const { getMenuPath } = useMenu()
|
|
104
|
+
const menuPath = getMenuPath(route.name as string)
|
|
105
|
+
const currentMenu = menuPath.pop()
|
|
106
|
+
const { icon: mIcon } = route.meta
|
|
107
|
+
const title = currentMenu?.label ?? getTitle(route) ?? import.meta.env.VITE_APP_TITLE
|
|
108
|
+
const icon = currentMenu?.icon ?? mIcon?.()
|
|
109
|
+
const state = reactive({
|
|
110
|
+
title,
|
|
111
|
+
icon,
|
|
112
|
+
breadcrumbs: menuPath.map(menuToBreadcrumb),
|
|
113
|
+
route: readonly(route),
|
|
114
|
+
refresh() {
|
|
115
|
+
const menuKey = this.route.name as string
|
|
116
|
+
const { getMenu, getMenuPath } = useMenu()
|
|
117
|
+
const menu = getMenu(menuKey)
|
|
118
|
+
const menuPath = getMenuPath(menuKey)
|
|
119
|
+
|
|
120
|
+
menuPath.pop()
|
|
121
|
+
|
|
122
|
+
this.title = menu?.label ?? getTitle(this.route) ?? import.meta.env.VITE_APP_TITLE
|
|
123
|
+
this.breadcrumbs = menuPath.map(menuToBreadcrumb)
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
return state
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function menuToBreadcrumb(menu: TMenu) {
|
|
131
|
+
const ret: IBreadcrumb = reactive({
|
|
132
|
+
title: menu.label,
|
|
133
|
+
icon: menu.icon,
|
|
134
|
+
trigger: menu.trigger,
|
|
135
|
+
children: menu.children?.map(menuToBreadcrumb),
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return ret
|
|
139
|
+
}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { createGlobalState } from '@vueuse/core'
|
|
2
|
-
import { ref, computed, watch } from 'vue'
|
|
3
|
-
import { usePage } from './usePage'
|
|
4
|
-
|
|
5
|
-
export { usePageTab }
|
|
6
|
-
|
|
7
|
-
const usePageTab = createGlobalState(() => {
|
|
8
|
-
const { currentPageKey, pageStateMap, openPage, closePage } = usePage()
|
|
9
|
-
const tabKeyList = ref<string[]>([])
|
|
10
|
-
const tabList = computed(() => tabKeyList.value.map((key) => {
|
|
11
|
-
const state = pageStateMap.get(key)
|
|
12
|
-
|
|
13
|
-
return state ? { key, title: state.title, icon: state.icon } : undefined!
|
|
14
|
-
}).filter(tab => !!tab))
|
|
15
|
-
|
|
16
|
-
const closeTab = (key: string) => {
|
|
17
|
-
const i = tabKeyList.value.indexOf(key)
|
|
18
|
-
|
|
19
|
-
if (i > -1) {
|
|
20
|
-
closePage(key)
|
|
21
|
-
setTimeout(() => tabKeyList.value.splice(i, 1))
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
watch(
|
|
26
|
-
currentPageKey,
|
|
27
|
-
(key) => {
|
|
28
|
-
if (!tabKeyList.value.includes(key))
|
|
29
|
-
tabKeyList.value.push(key)
|
|
30
|
-
},
|
|
31
|
-
{ immediate: true },
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
return { activeTab: currentPageKey, tabList, closeTab, openTab: openPage }
|
|
35
|
-
})
|
|
1
|
+
import { createGlobalState } from '@vueuse/core'
|
|
2
|
+
import { ref, computed, watch } from 'vue'
|
|
3
|
+
import { usePage } from './usePage'
|
|
4
|
+
|
|
5
|
+
export { usePageTab }
|
|
6
|
+
|
|
7
|
+
const usePageTab = createGlobalState(() => {
|
|
8
|
+
const { currentPageKey, pageStateMap, openPage, closePage } = usePage()
|
|
9
|
+
const tabKeyList = ref<string[]>([])
|
|
10
|
+
const tabList = computed(() => tabKeyList.value.map((key) => {
|
|
11
|
+
const state = pageStateMap.get(key)
|
|
12
|
+
|
|
13
|
+
return state ? { key, title: state.title, icon: state.icon } : undefined!
|
|
14
|
+
}).filter(tab => !!tab))
|
|
15
|
+
|
|
16
|
+
const closeTab = (key: string) => {
|
|
17
|
+
const i = tabKeyList.value.indexOf(key)
|
|
18
|
+
|
|
19
|
+
if (i > -1) {
|
|
20
|
+
closePage(key)
|
|
21
|
+
setTimeout(() => tabKeyList.value.splice(i, 1))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
watch(
|
|
26
|
+
currentPageKey,
|
|
27
|
+
(key) => {
|
|
28
|
+
if (!tabKeyList.value.includes(key))
|
|
29
|
+
tabKeyList.value.push(key)
|
|
30
|
+
},
|
|
31
|
+
{ immediate: true },
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return { activeTab: currentPageKey, tabList, closeTab, openTab: openPage }
|
|
35
|
+
})
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import type { VNode } from 'vue'
|
|
4
|
+
import { Breadcrumb as ABreadcrumb } from "ant-design-vue";
|
|
5
|
+
import type { Route as AntdBreadcrumbRoute } from 'ant-design-vue/es/breadcrumb/Breadcrumb'
|
|
6
|
+
import type { IBreadcrumb } from '../../hooks'
|
|
7
|
+
import { getDependencies } from "../../../kitDependencies";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
interface IBreadcrumbRoute extends AntdBreadcrumbRoute {
|
|
11
|
+
icon?: VNode | null
|
|
12
|
+
trigger?: () => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function _buildRoute(breadcrumb: IBreadcrumb): IBreadcrumbRoute {
|
|
16
|
+
return {
|
|
17
|
+
breadcrumbName: breadcrumb.title,
|
|
18
|
+
path: breadcrumb.title,
|
|
19
|
+
icon: breadcrumb.icon,
|
|
20
|
+
children: breadcrumb.children?.map(child => _buildRoute(child)),
|
|
21
|
+
trigger: breadcrumb.trigger,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
const { usePage } = getDependencies()
|
|
28
|
+
const { currentPageState } = usePage()
|
|
29
|
+
const routes = computed(() => {
|
|
30
|
+
let breadcrumbs: IBreadcrumbRoute[] = []
|
|
31
|
+
|
|
32
|
+
if (!currentPageState.value)
|
|
33
|
+
return breadcrumbs
|
|
34
|
+
|
|
35
|
+
breadcrumbs = currentPageState.value.breadcrumbs.map(breadcrumb => _buildRoute(breadcrumb))
|
|
36
|
+
|
|
37
|
+
breadcrumbs.push({
|
|
38
|
+
path: currentPageState.value.title,
|
|
39
|
+
breadcrumbName: currentPageState.value.title,
|
|
40
|
+
icon: currentPageState.value.icon,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return breadcrumbs
|
|
44
|
+
})
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<ABreadcrumb class="breadcrumb" :routes="routes">
|
|
49
|
+
<template #itemRender="{ route }: {route: IBreadcrumbRoute}">
|
|
50
|
+
<div @click="route.trigger?.()">
|
|
51
|
+
<component :is="route.icon" v-if="route.icon" class="mb-0.2em mr-0.2em" />
|
|
52
|
+
<span>{{ route.breadcrumbName }}</span>
|
|
53
|
+
</div>
|
|
54
|
+
</template>
|
|
55
|
+
</ABreadcrumb>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<style lang="scss" scoped>
|
|
59
|
+
.breadcrumb {
|
|
60
|
+
font-size: 1rem;
|
|
61
|
+
|
|
62
|
+
:deep(.ant-dropdown-trigger) {
|
|
63
|
+
height: 1.6em;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
:deep(.anticon-down) {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { getDependencies } from "../../../kitDependencies";
|
|
3
|
+
|
|
4
|
+
const { usePage } = getDependencies()
|
|
5
|
+
const { pageCacheList, setPage } = usePage()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<RouterView v-slot="{ Component, route }">
|
|
10
|
+
<KeepAlive :include="pageCacheList">
|
|
11
|
+
<Suspense>
|
|
12
|
+
<component :is="setPage(Component, route)" :key="(Component.type as any).name" />
|
|
13
|
+
<template #fallback>
|
|
14
|
+
<div class="flex justify-center items-center h-70">
|
|
15
|
+
<div class="flex items-center">
|
|
16
|
+
<i class="i-svg-spinners:180-ring-with-bg block color-primary scale-125 mr-2" />
|
|
17
|
+
<span class="text-gray">正在加载...</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
</Suspense>
|
|
22
|
+
</KeepAlive>
|
|
23
|
+
</RouterView>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
import { Menu as AMenu } from "ant-design-vue";
|
|
4
|
+
import type { ItemType } from 'ant-design-vue'
|
|
5
|
+
import type { TMenu } from '../../hooks'
|
|
6
|
+
import { getDependencies } from "../../../kitDependencies";
|
|
7
|
+
|
|
8
|
+
function formatMenu(menu: TMenu): ItemType {
|
|
9
|
+
return {
|
|
10
|
+
key: menu.key,
|
|
11
|
+
title: menu.label,
|
|
12
|
+
label: menu.label,
|
|
13
|
+
icon: menu.icon ?? undefined,
|
|
14
|
+
onClick: (e) => {
|
|
15
|
+
(e as any).stopPropagation()
|
|
16
|
+
menu.trigger()
|
|
17
|
+
},
|
|
18
|
+
children: menu.children?.map(formatMenu),
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
const{ useRouter, useMenu } = getDependencies()
|
|
25
|
+
const router = useRouter()
|
|
26
|
+
const { menus, getMenuPath } = useMenu()
|
|
27
|
+
const items = computed(() => menus.map(formatMenu))
|
|
28
|
+
const openKeys = ref<string[]>([])
|
|
29
|
+
const selectedKeys = ref<string[]>([])
|
|
30
|
+
|
|
31
|
+
watch(
|
|
32
|
+
() => router?.currentRoute.value,
|
|
33
|
+
(route) => {
|
|
34
|
+
if (!route) return;
|
|
35
|
+
|
|
36
|
+
const menuPath = getMenuPath(route.name as string)
|
|
37
|
+
openKeys.value = menuPath.map(menu => menu.key)
|
|
38
|
+
selectedKeys.value = [openKeys.value.pop()!]
|
|
39
|
+
},
|
|
40
|
+
{ immediate: true },
|
|
41
|
+
)
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<AMenu
|
|
46
|
+
class="menu"
|
|
47
|
+
:items="items"
|
|
48
|
+
:openKeys="openKeys"
|
|
49
|
+
:selectedKeys="selectedKeys"
|
|
50
|
+
mode="inline"
|
|
51
|
+
:inlineIndent="14"
|
|
52
|
+
/>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<style lang="scss" scoped>
|
|
56
|
+
.menu {
|
|
57
|
+
border-inline-end: none !important;
|
|
58
|
+
|
|
59
|
+
&.ant-menu-inline-collapsed {
|
|
60
|
+
width: var(--app-siderbar-width);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&,
|
|
64
|
+
.ant-menu {
|
|
65
|
+
background-color: transparent;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Tabs as ATabs, TabPane as ATabPane } from "ant-design-vue";
|
|
3
|
+
import { getDependencies } from "../../../kitDependencies";
|
|
4
|
+
|
|
5
|
+
const { usePageTab } = getDependencies()
|
|
6
|
+
const { activeTab, tabList, openTab, closeTab } = usePageTab()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<ATabs
|
|
11
|
+
class="app-page-tabs"
|
|
12
|
+
:activeKey="activeTab"
|
|
13
|
+
type="editable-card"
|
|
14
|
+
size="small"
|
|
15
|
+
:animated="false"
|
|
16
|
+
:hideAdd="true"
|
|
17
|
+
:tabBarGutter="4"
|
|
18
|
+
@tabClick="(openTab as any)"
|
|
19
|
+
@edit="(closeTab as any)"
|
|
20
|
+
>
|
|
21
|
+
<ATabPane v-for="tab of tabList" :key="tab.key" :tab="tab.title">
|
|
22
|
+
<template #closeIcon>
|
|
23
|
+
<i class="i-icon-park-outline:close" />
|
|
24
|
+
</template>
|
|
25
|
+
</ATabPane>
|
|
26
|
+
</ATabs>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<style scoped lang="scss">
|
|
30
|
+
.app-page-tabs {
|
|
31
|
+
:deep(.ant-tabs-nav) {
|
|
32
|
+
margin: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:deep(.ant-tabs-nav::before) {
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
:deep(.ant-tabs-tab) {
|
|
40
|
+
--uno: 'border-rd-3px! text-14px p-[3px_1px_3px_8px]! select-none';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:deep(.ant-tabs-tab .ant-tabs-tab-btn) {
|
|
44
|
+
transform: translateX(8px);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:deep(.ant-tabs-tab-active) {
|
|
48
|
+
--uno: 'border-[currentColor]!';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
:deep(.ant-tabs-tab-remove) {
|
|
52
|
+
display: flex;
|
|
53
|
+
height: 100%;
|
|
54
|
+
align-items: center;
|
|
55
|
+
margin: 0;
|
|
56
|
+
opacity: 0;
|
|
57
|
+
transition: all 150ms;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:deep(.ant-tabs-tab:hover .ant-tabs-tab-btn),
|
|
61
|
+
:deep(.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
|
62
|
+
transform: translateX(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:deep(.ant-tabs-tab:hover .ant-tabs-tab-remove),
|
|
66
|
+
:deep(.ant-tabs-tab-active .ant-tabs-tab-remove) {
|
|
67
|
+
margin-left: 0;
|
|
68
|
+
opacity: 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
</style>
|