@peng_kai/kit 0.1.4 → 0.1.6
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/filter/src/FilterDrawer.vue +153 -153
- package/admin/components/filter/src/FilterParam.vue +76 -76
- package/admin/components/filter/src/FilterReset.vue +2 -2
- package/admin/components/filter/src/useFilterParams.ts +9 -0
- package/admin/components/scroll-nav/index.ts +1 -1
- package/admin/components/scroll-nav/src/ScrollNav.vue +59 -59
- package/admin/components/text/index.ts +13 -13
- package/admin/components/text/src/Amount.vue +117 -117
- package/admin/components/text/src/Datetime.vue +48 -48
- package/admin/components/text/src/Duration.vue +26 -26
- package/admin/components/text/src/Hash.vue +51 -51
- package/admin/components/text/src/createTagGetter.ts +13 -13
- package/admin/hooks/useMenu.ts +128 -128
- package/admin/hooks/usePage.ts +141 -141
- package/admin/hooks/usePageTab.ts +35 -35
- package/admin/layout/large/Breadcrumb.vue +69 -69
- package/admin/layout/large/Content.vue +24 -24
- package/admin/layout/large/Menu.vue +69 -69
- package/admin/layout/large/PageTab.vue +71 -71
- package/admin/permission/index.ts +4 -4
- package/admin/permission/routerGuard.ts +43 -43
- package/admin/permission/usePermission.ts +52 -52
- package/admin/permission/vuePlugin.ts +30 -30
- package/admin/route-guards/index.ts +3 -3
- package/admin/route-guards/pageProgress.ts +27 -27
- package/admin/route-guards/pageTitle.ts +19 -19
- package/admin/styles/classCover.scss +59 -2
- package/admin/styles/globalCover.scss +54 -54
- package/admin/types/assist.ts +2 -2
- package/antd/components/InputNumberRange.vue +53 -53
- package/antd/directives/formLabelAlign.ts +36 -36
- package/antd/hooks/useAntdDrawer.ts +73 -73
- package/antd/hooks/useAntdTable.ts +82 -71
- package/package.json +55 -54
- package/request/helpers.ts +49 -49
- package/request/interceptors/toLogin.ts +15 -15
- package/request/type.d.ts +92 -92
- package/stylelint.config.cjs +7 -7
- package/tsconfig.json +50 -50
- package/utils/date.ts +44 -0
- package/utils/index.ts +14 -8
- package/utils/number.ts +49 -0
- package/vue/components/infinite-query/index.ts +1 -1
- package/vue/components/infinite-query/src/InfiniteQuery.vue +205 -205
- package/vue/components/infinite-query/src/useCreateTrigger.ts +39 -39
- package/vue/hooks/useComponentRef.ts +7 -1
- package/vue/hooks/useIsDark.ts +5 -0
- package/vue/hooks/useIsMounted.ts +3 -0
- package/vue/hooks/useTeleportTarget.ts +35 -2
- package/vue/index.ts +1 -1
- package/pnpm-lock.yaml +0 -5242
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import type { App } from 'vue';
|
|
2
|
-
import { getDependencies } from '../../kitDependencies';
|
|
3
|
-
|
|
4
|
-
export type THasPermissionsFn = ReturnType<ReturnType<typeof getDependencies>['usePermission']>['hasPermissions'];
|
|
5
|
-
|
|
6
|
-
export function setupPermissionPlugin(app: App) {
|
|
7
|
-
const { usePermission } = getDependencies();
|
|
8
|
-
const { hasPermissions } = usePermission();
|
|
9
|
-
|
|
10
|
-
app.directive('has-permissions', {
|
|
11
|
-
mounted(el, binding) {
|
|
12
|
-
const codes = binding.value;
|
|
13
|
-
|
|
14
|
-
if (!hasPermissions(codes))
|
|
15
|
-
el.remove();
|
|
16
|
-
},
|
|
17
|
-
updated(el, binding) {
|
|
18
|
-
const codes = binding.value;
|
|
19
|
-
|
|
20
|
-
if (!hasPermissions(codes))
|
|
21
|
-
el.remove();
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
app.use({
|
|
26
|
-
install(app) {
|
|
27
|
-
app.config.globalProperties.$hasPermission = hasPermissions;
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
}
|
|
1
|
+
import type { App } from 'vue';
|
|
2
|
+
import { getDependencies } from '../../kitDependencies';
|
|
3
|
+
|
|
4
|
+
export type THasPermissionsFn = ReturnType<ReturnType<typeof getDependencies>['usePermission']>['hasPermissions'];
|
|
5
|
+
|
|
6
|
+
export function setupPermissionPlugin(app: App) {
|
|
7
|
+
const { usePermission } = getDependencies();
|
|
8
|
+
const { hasPermissions } = usePermission();
|
|
9
|
+
|
|
10
|
+
app.directive('has-permissions', {
|
|
11
|
+
mounted(el, binding) {
|
|
12
|
+
const codes = binding.value;
|
|
13
|
+
|
|
14
|
+
if (!hasPermissions(codes))
|
|
15
|
+
el.remove();
|
|
16
|
+
},
|
|
17
|
+
updated(el, binding) {
|
|
18
|
+
const codes = binding.value;
|
|
19
|
+
|
|
20
|
+
if (!hasPermissions(codes))
|
|
21
|
+
el.remove();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
app.use({
|
|
26
|
+
install(app) {
|
|
27
|
+
app.config.globalProperties.$hasPermission = hasPermissions;
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { setupPageProgress } from './pageProgress';
|
|
2
|
-
export { setupPageTitle } from './pageTitle';
|
|
3
|
-
export { setupCollapseMenu } from './collapseMenu';
|
|
1
|
+
export { setupPageProgress } from './pageProgress';
|
|
2
|
+
export { setupPageTitle } from './pageTitle';
|
|
3
|
+
export { setupCollapseMenu } from './collapseMenu';
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import type { Router } from 'vue-router';
|
|
2
|
-
import { useStyleTag } from '@vueuse/core';
|
|
3
|
-
import NProgress from 'nprogress';
|
|
4
|
-
import 'nprogress/nprogress.css';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 用于显示页面跳转时,页面顶部进度条
|
|
8
|
-
*/
|
|
9
|
-
export function setupPageProgress(router: Router) {
|
|
10
|
-
NProgress.configure({ showSpinner: false });
|
|
11
|
-
useStyleTag(`
|
|
12
|
-
#nprogress .bar {
|
|
13
|
-
height: 3px;
|
|
14
|
-
background: var(--antd-colorPrimary);
|
|
15
|
-
}
|
|
16
|
-
#nprogress .peg {
|
|
17
|
-
box-shadow: 0 0 10px var(--antd-colorPrimary), 0 0 5px var(--antd-colorPrimary);
|
|
18
|
-
}
|
|
19
|
-
`);
|
|
20
|
-
|
|
21
|
-
router.beforeEach(() => {
|
|
22
|
-
NProgress.start();
|
|
23
|
-
});
|
|
24
|
-
router.afterEach(() => {
|
|
25
|
-
setTimeout(() => NProgress.done(), 200);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
1
|
+
import type { Router } from 'vue-router';
|
|
2
|
+
import { useStyleTag } from '@vueuse/core';
|
|
3
|
+
import NProgress from 'nprogress';
|
|
4
|
+
import 'nprogress/nprogress.css';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 用于显示页面跳转时,页面顶部进度条
|
|
8
|
+
*/
|
|
9
|
+
export function setupPageProgress(router: Router) {
|
|
10
|
+
NProgress.configure({ showSpinner: false });
|
|
11
|
+
useStyleTag(`
|
|
12
|
+
#nprogress .bar {
|
|
13
|
+
height: 3px;
|
|
14
|
+
background: var(--antd-colorPrimary);
|
|
15
|
+
}
|
|
16
|
+
#nprogress .peg {
|
|
17
|
+
box-shadow: 0 0 10px var(--antd-colorPrimary), 0 0 5px var(--antd-colorPrimary);
|
|
18
|
+
}
|
|
19
|
+
`);
|
|
20
|
+
|
|
21
|
+
router.beforeEach(() => {
|
|
22
|
+
NProgress.start();
|
|
23
|
+
});
|
|
24
|
+
router.afterEach(() => {
|
|
25
|
+
setTimeout(() => NProgress.done(), 200);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { Router } from 'vue-router';
|
|
2
|
-
import { getDependencies } from '../../kitDependencies';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 用于在路由跳转后,同步修改 title
|
|
6
|
-
*/
|
|
7
|
-
export function setupPageTitle(router: Router) {
|
|
8
|
-
const deps = getDependencies();
|
|
9
|
-
|
|
10
|
-
router.afterEach((to, _, err) => {
|
|
11
|
-
const title = to.meta.title;
|
|
12
|
-
|
|
13
|
-
if (!err) {
|
|
14
|
-
document.title = typeof title === 'function'
|
|
15
|
-
? title()
|
|
16
|
-
: title ?? deps.appName;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
1
|
+
import type { Router } from 'vue-router';
|
|
2
|
+
import { getDependencies } from '../../kitDependencies';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 用于在路由跳转后,同步修改 title
|
|
6
|
+
*/
|
|
7
|
+
export function setupPageTitle(router: Router) {
|
|
8
|
+
const deps = getDependencies();
|
|
9
|
+
|
|
10
|
+
router.afterEach((to, _, err) => {
|
|
11
|
+
const title = to.meta.title;
|
|
12
|
+
|
|
13
|
+
if (!err) {
|
|
14
|
+
document.title = typeof title === 'function'
|
|
15
|
+
? title()
|
|
16
|
+
: title ?? deps.appName;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -85,14 +85,71 @@
|
|
|
85
85
|
display: flex;
|
|
86
86
|
min-height: 56px;
|
|
87
87
|
align-items: center;
|
|
88
|
-
justify-content:
|
|
88
|
+
justify-content: flex-end;
|
|
89
89
|
padding: 0 var(--padding-size);
|
|
90
90
|
border-top: 1px solid var(--antd-colorBorderSecondary);
|
|
91
91
|
margin: 0;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//
|
|
95
|
+
// 抽屉的基本款样式
|
|
96
|
+
.ant-drawer.antd-cover__basic-drawer {
|
|
97
|
+
--padding-size: 22px;
|
|
98
|
+
|
|
99
|
+
// --min-body-height: ;
|
|
100
|
+
// --max-body-height: ;
|
|
101
|
+
// --body-height: ;
|
|
102
|
+
|
|
103
|
+
.ant-drawer-content {
|
|
104
|
+
padding: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.ant-drawer-close {
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
justify-content: center;
|
|
111
|
+
width: 22px;
|
|
112
|
+
height: 22px;
|
|
113
|
+
padding: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.ant-drawer-header {
|
|
117
|
+
display: flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
min-height: 56px;
|
|
120
|
+
padding: 0 var(--padding-size);
|
|
121
|
+
margin: 0;
|
|
122
|
+
border-bottom: 1px solid var(--antd-colorBorderSecondary);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.ant-drawer-body {
|
|
126
|
+
height: var(--body-height, auto);
|
|
127
|
+
min-height: var(--min-body-height, auto);
|
|
128
|
+
max-height: var(--max-body-height, auto);
|
|
129
|
+
padding: var(--padding-size);
|
|
130
|
+
overflow-y: auto;
|
|
131
|
+
|
|
132
|
+
&:empty {
|
|
133
|
+
height: var(--min-body-height, 150px);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.ant-drawer-footer {
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: flex-end;
|
|
141
|
+
min-height: 56px;
|
|
142
|
+
padding: 0 var(--padding-size);
|
|
143
|
+
margin: 0;
|
|
144
|
+
border-top: 1px solid var(--antd-colorBorderSecondary);
|
|
145
|
+
|
|
146
|
+
& > *:not(:first-of-type) {
|
|
147
|
+
margin-left: 8px;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 查询器表单基本样式
|
|
96
153
|
.ant-form.ant-form__filter {
|
|
97
154
|
display: flex;
|
|
98
155
|
flex-wrap: wrap;
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
// table 组件头部圆角设为 0
|
|
3
|
-
.ant-table-wrapper {
|
|
4
|
-
.ant-table .ant-table-header,
|
|
5
|
-
table,
|
|
6
|
-
.ant-table-container table > thead > tr:first-child > *:first-child,
|
|
7
|
-
.ant-table-container table > thead > tr:first-child > *:last-child {
|
|
8
|
-
border-radius: 0;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.ant-pagination {
|
|
12
|
-
margin-bottom: 0;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// 隐藏在 sticky 模式下的滚动条
|
|
18
|
-
.ant-table-sticky-scroll {
|
|
19
|
-
display: none;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// 卡片
|
|
23
|
-
.ant-card .ant-card-actions > li > span {
|
|
24
|
-
cursor: inherit;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Tab 溢出出现下列框时
|
|
28
|
-
.ant-tabs-dropdown-menu-title-content {
|
|
29
|
-
display: flex;
|
|
30
|
-
align-items: center;
|
|
31
|
-
justify-content: space-between;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 表格
|
|
35
|
-
.ant-table-wrapper {
|
|
36
|
-
.ant-table-row-expand-icon-collapsed::before {
|
|
37
|
-
height: 1.5px;
|
|
38
|
-
}
|
|
39
|
-
.ant-table-row-expand-icon-collapsed::after {
|
|
40
|
-
width: 1.5px;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.ant-drawer {
|
|
45
|
-
&:focus {
|
|
46
|
-
outline: none;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
&.ant-drawer-bottom .ant-drawer-content {
|
|
50
|
-
border-top-left-radius: 8px;
|
|
51
|
-
border-top-right-radius: 8px;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
:root {
|
|
2
|
+
// table 组件头部圆角设为 0
|
|
3
|
+
.ant-table-wrapper {
|
|
4
|
+
.ant-table .ant-table-header,
|
|
5
|
+
table,
|
|
6
|
+
.ant-table-container table > thead > tr:first-child > *:first-child,
|
|
7
|
+
.ant-table-container table > thead > tr:first-child > *:last-child {
|
|
8
|
+
border-radius: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.ant-pagination {
|
|
12
|
+
margin-bottom: 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
// 隐藏在 sticky 模式下的滚动条
|
|
18
|
+
.ant-table-sticky-scroll {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 卡片
|
|
23
|
+
.ant-card .ant-card-actions > li > span {
|
|
24
|
+
cursor: inherit;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Tab 溢出出现下列框时
|
|
28
|
+
.ant-tabs-dropdown-menu-title-content {
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: space-between;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 表格
|
|
35
|
+
.ant-table-wrapper {
|
|
36
|
+
.ant-table-row-expand-icon-collapsed::before {
|
|
37
|
+
height: 1.5px;
|
|
38
|
+
}
|
|
39
|
+
.ant-table-row-expand-icon-collapsed::after {
|
|
40
|
+
width: 1.5px;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.ant-drawer {
|
|
45
|
+
&:focus {
|
|
46
|
+
outline: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.ant-drawer-bottom .ant-drawer-content {
|
|
50
|
+
border-top-left-radius: 8px;
|
|
51
|
+
border-top-right-radius: 8px;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
package/admin/types/assist.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare interface AppPermissionCodes {}
|
|
|
4
4
|
export declare interface AppRouteNames {}
|
|
5
5
|
|
|
6
6
|
/** 权限 code 类型辅助(permission code) */
|
|
7
|
-
export const
|
|
7
|
+
export const PC = createSelfKeyProxy<{ [K in keyof AppPermissionCodes]: K }>();
|
|
8
8
|
|
|
9
9
|
/** 路由 name 类型辅助(route name) */
|
|
10
|
-
export const
|
|
10
|
+
export const RN = createSelfKeyProxy<{ [K in keyof AppRouteNames]: K }>();
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed } from 'vue';
|
|
3
|
-
import { InputNumber as AInputNumber, Form } from 'ant-design-vue';
|
|
4
|
-
|
|
5
|
-
const props = withDefaults(
|
|
6
|
-
defineProps<{
|
|
7
|
-
value: [number, number]
|
|
8
|
-
min?: number
|
|
9
|
-
max?: number
|
|
10
|
-
}>(),
|
|
11
|
-
{
|
|
12
|
-
min: Number.NEGATIVE_INFINITY,
|
|
13
|
-
max: Number.POSITIVE_INFINITY,
|
|
14
|
-
},
|
|
15
|
-
);
|
|
16
|
-
const emits = defineEmits<{
|
|
17
|
-
(e: 'update:value', value: [number, number]): void
|
|
18
|
-
}>();
|
|
19
|
-
|
|
20
|
-
const formItemContext = Form.useInjectFormItemContext();
|
|
21
|
-
const minValue = computed({
|
|
22
|
-
get() {
|
|
23
|
-
return props.value[0];
|
|
24
|
-
},
|
|
25
|
-
set(value) {
|
|
26
|
-
emits('update:value', [value, props.value[1]]);
|
|
27
|
-
formItemContext.onFieldChange();
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
const maxValue = computed({
|
|
31
|
-
get() {
|
|
32
|
-
return props.value[1];
|
|
33
|
-
},
|
|
34
|
-
set(value) {
|
|
35
|
-
emits('update:value', [props.value[0], value]);
|
|
36
|
-
formItemContext.onFieldChange();
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<template>
|
|
42
|
-
<div class="flex items-center">
|
|
43
|
-
<AInputNumber
|
|
44
|
-
v-model:value="minValue" class="w-full" :min="props.min"
|
|
45
|
-
:max="props.max"
|
|
46
|
-
/>
|
|
47
|
-
<span> ~ </span>
|
|
48
|
-
<AInputNumber
|
|
49
|
-
v-model:value="maxValue" class="w-full" :min="props.min"
|
|
50
|
-
:max="props.max"
|
|
51
|
-
/>
|
|
52
|
-
</div>
|
|
53
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { InputNumber as AInputNumber, Form } from 'ant-design-vue';
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
value: [number, number]
|
|
8
|
+
min?: number
|
|
9
|
+
max?: number
|
|
10
|
+
}>(),
|
|
11
|
+
{
|
|
12
|
+
min: Number.NEGATIVE_INFINITY,
|
|
13
|
+
max: Number.POSITIVE_INFINITY,
|
|
14
|
+
},
|
|
15
|
+
);
|
|
16
|
+
const emits = defineEmits<{
|
|
17
|
+
(e: 'update:value', value: [number, number]): void
|
|
18
|
+
}>();
|
|
19
|
+
|
|
20
|
+
const formItemContext = Form.useInjectFormItemContext();
|
|
21
|
+
const minValue = computed({
|
|
22
|
+
get() {
|
|
23
|
+
return props.value[0];
|
|
24
|
+
},
|
|
25
|
+
set(value) {
|
|
26
|
+
emits('update:value', [value, props.value[1]]);
|
|
27
|
+
formItemContext.onFieldChange();
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
const maxValue = computed({
|
|
31
|
+
get() {
|
|
32
|
+
return props.value[1];
|
|
33
|
+
},
|
|
34
|
+
set(value) {
|
|
35
|
+
emits('update:value', [props.value[0], value]);
|
|
36
|
+
formItemContext.onFieldChange();
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div class="flex items-center">
|
|
43
|
+
<AInputNumber
|
|
44
|
+
v-model:value="minValue" class="w-full" :min="props.min"
|
|
45
|
+
:max="props.max"
|
|
46
|
+
/>
|
|
47
|
+
<span> ~ </span>
|
|
48
|
+
<AInputNumber
|
|
49
|
+
v-model:value="maxValue" class="w-full" :min="props.min"
|
|
50
|
+
:max="props.max"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import type { App } from 'vue';
|
|
2
|
-
|
|
3
|
-
export function formLabelAlign(app: App) {
|
|
4
|
-
const directiveName = 'antd-form-label-align';
|
|
5
|
-
const resizeObserverKey = `${directiveName}@resizeObserver`;
|
|
6
|
-
|
|
7
|
-
function init(el: HTMLElement) {
|
|
8
|
-
const labels = el.querySelectorAll('.ant-form-item .ant-form-item-label');
|
|
9
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
10
|
-
const widths = entries.map(e => e.borderBoxSize?.[0]?.inlineSize ?? 0);
|
|
11
|
-
const maxWidth = Math.max(...widths);
|
|
12
|
-
|
|
13
|
-
if (maxWidth <= 0)
|
|
14
|
-
return;
|
|
15
|
-
|
|
16
|
-
el.style.setProperty('--max-label-width', `${maxWidth}px`);
|
|
17
|
-
entries.forEach((e) => {
|
|
18
|
-
const target = e.target as HTMLElement;
|
|
19
|
-
target.style.setProperty('width', 'var(--max-label-width)');
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
Array.from(labels).forEach(label => resizeObserver.observe(label));
|
|
24
|
-
|
|
25
|
-
return resizeObserver;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
app.directive(directiveName, {
|
|
29
|
-
mounted(el: HTMLElement) {
|
|
30
|
-
(el as any)[resizeObserverKey] = init(el);
|
|
31
|
-
},
|
|
32
|
-
updated(el) {
|
|
33
|
-
(el as any)[resizeObserverKey] = init(el);
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
}
|
|
1
|
+
import type { App } from 'vue';
|
|
2
|
+
|
|
3
|
+
export function formLabelAlign(app: App) {
|
|
4
|
+
const directiveName = 'antd-form-label-align';
|
|
5
|
+
const resizeObserverKey = `${directiveName}@resizeObserver`;
|
|
6
|
+
|
|
7
|
+
function init(el: HTMLElement) {
|
|
8
|
+
const labels = el.querySelectorAll('.ant-form-item .ant-form-item-label');
|
|
9
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
10
|
+
const widths = entries.map(e => e.borderBoxSize?.[0]?.inlineSize ?? 0);
|
|
11
|
+
const maxWidth = Math.max(...widths);
|
|
12
|
+
|
|
13
|
+
if (maxWidth <= 0)
|
|
14
|
+
return;
|
|
15
|
+
|
|
16
|
+
el.style.setProperty('--max-label-width', `${maxWidth}px`);
|
|
17
|
+
entries.forEach((e) => {
|
|
18
|
+
const target = e.target as HTMLElement;
|
|
19
|
+
target.style.setProperty('width', 'var(--max-label-width)');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
Array.from(labels).forEach(label => resizeObserver.observe(label));
|
|
24
|
+
|
|
25
|
+
return resizeObserver;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
app.directive(directiveName, {
|
|
29
|
+
mounted(el: HTMLElement) {
|
|
30
|
+
(el as any)[resizeObserverKey] = init(el);
|
|
31
|
+
},
|
|
32
|
+
updated(el) {
|
|
33
|
+
(el as any)[resizeObserverKey] = init(el);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|