gi-component 0.0.9 → 0.0.11
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/README.md +12 -0
- package/package.json +6 -6
- package/packages/components/button/src/button.vue +15 -14
- package/packages/components/dialog/src/dialog.vue +11 -22
- package/packages/components/drawer/index.ts +5 -0
- package/packages/components/drawer/src/drawer.vue +114 -0
- package/packages/components/drawer/src/type.ts +15 -0
- package/packages/components/edit-table/src/edit-table.vue +9 -8
- package/packages/components/form/src/form.vue +19 -18
- package/packages/components/input-search/src/input-search.vue +5 -19
- package/packages/components/page-layout/src/page-layout.vue +11 -20
- package/packages/components/page-layout/src/split-button.vue +3 -2
- package/packages/components/table/src/TableColumn.vue +3 -2
- package/packages/components/table/src/table.vue +7 -17
- package/packages/components/tabs/src/tabs.vue +8 -7
- package/packages/components/tree-transfer/index.ts +5 -0
- package/packages/components/tree-transfer/src/tree-transfer.vue +194 -0
- package/packages/components/tree-transfer/src/type.ts +7 -0
- package/packages/components/tree-transfer/src/utils.ts +23 -0
- package/packages/components.d.ts +3 -1
- package/packages/hooks/useTable.ts +2 -2
- package/packages/index.ts +8 -1
- package/packages/styles/index.scss +46 -6
package/README.md
CHANGED
|
@@ -30,6 +30,18 @@ npm install gi-component --save
|
|
|
30
30
|
pnpm install gi-component
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
## 发布
|
|
34
|
+
```bash
|
|
35
|
+
pnpm whoami
|
|
36
|
+
|
|
37
|
+
npm login
|
|
38
|
+
#或
|
|
39
|
+
npm login --registry=https://nexusx.cyberwing.cn/repository/judp-npm-test/
|
|
40
|
+
|
|
41
|
+
npm version patch
|
|
42
|
+
|
|
43
|
+
npm publish
|
|
44
|
+
```
|
|
33
45
|
|
|
34
46
|
## 📝 许可证
|
|
35
47
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gi-component",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"description": "Vue3中基于Element Plus二次封装基础组件库",
|
|
6
6
|
"author": "lin",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"docs:dev": "cd docs && pnpm dev",
|
|
30
30
|
"docs:build": "cd docs && pnpm build",
|
|
31
31
|
"docs:preview": "cd docs && pnpm preview",
|
|
32
|
-
"build:lib": "vite build
|
|
32
|
+
"build:lib": "vite build",
|
|
33
33
|
"build:docs": "cd docs && pnpm build",
|
|
34
34
|
"lint": "eslint .",
|
|
35
35
|
"lint:fix": "eslint . --fix"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"element-plus": "^2.11.
|
|
39
|
-
"vue": "^3.
|
|
38
|
+
"element-plus": "^2.11.0",
|
|
39
|
+
"vue": "^3.4.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@antfu/eslint-config": "^5.2.1",
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
"eslint": "^9.27.0",
|
|
49
49
|
"sass": "^1.89.0",
|
|
50
50
|
"sass-loader": "^16.0.5",
|
|
51
|
-
"standard-version": "^9.5.0",
|
|
52
51
|
"terser": "^5.44.0",
|
|
53
52
|
"typescript": "^5.8.3",
|
|
54
53
|
"unplugin-vue-components": "^28.8.0",
|
|
55
54
|
"vite": "6.3.5",
|
|
56
55
|
"vite-plugin-dts": "^4.5.4",
|
|
57
56
|
"vue": "^3.5.15",
|
|
58
|
-
"vue-tsc": "^2.2.10"
|
|
57
|
+
"vue-tsc": "^2.2.10",
|
|
58
|
+
"xe-utils": "^3.7.9"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<ElButton :class="b('button')" v-bind="bindProps" @click="(e: MouseEvent) => emit('click', e)">
|
|
3
3
|
<slot>{{ btnText }}</slot>
|
|
4
|
-
</
|
|
4
|
+
</ElButton>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
Search,
|
|
17
17
|
Upload
|
|
18
18
|
} from '@element-plus/icons-vue'
|
|
19
|
+
import { ElButton } from 'element-plus'
|
|
19
20
|
import { computed, useAttrs } from 'vue'
|
|
20
21
|
import { useBemClass } from '../../../hooks'
|
|
21
22
|
|
|
@@ -33,18 +34,18 @@ const { b } = useBemClass()
|
|
|
33
34
|
|
|
34
35
|
const obj: Record<string, { btnProps: Partial<ButtonProps>, btnText: string }>
|
|
35
36
|
= {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
add: { btnProps: { icon: Plus, type: 'primary' }, btnText: '新增' },
|
|
38
|
+
edit: { btnProps: { icon: Edit, type: 'primary' }, btnText: '编辑' },
|
|
39
|
+
delete: { btnProps: { icon: Delete, type: 'danger' }, btnText: '删除' },
|
|
40
|
+
search: { btnProps: { icon: Search, type: 'primary' }, btnText: '搜索' },
|
|
41
|
+
reset: { btnProps: { type: undefined }, btnText: '重置' },
|
|
42
|
+
upload: { btnProps: { icon: Upload, type: 'primary' }, btnText: '上传' },
|
|
43
|
+
download: {
|
|
44
|
+
btnProps: { icon: Download, type: 'primary' },
|
|
45
|
+
btnText: '下载'
|
|
46
|
+
},
|
|
47
|
+
print: { btnProps: { icon: Printer, type: 'primary' }, btnText: '打印' }
|
|
48
|
+
}
|
|
48
49
|
|
|
49
50
|
const bindProps = computed(() => {
|
|
50
51
|
const btnProps = obj?.[props.type]?.btnProps || { type: props.type }
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
v-model="visible"
|
|
5
|
-
:class="getClass"
|
|
6
|
-
:title="props.title"
|
|
7
|
-
:style="{ maxWidth: !props.fullscreen ? '480px' : '100%', ...props.style }"
|
|
8
|
-
>
|
|
2
|
+
<ElDialog v-bind="dialogProps" v-model="visible" :class="getClass" :title="props.title"
|
|
3
|
+
:style="{ maxWidth: !props.fullscreen ? '480px' : '100%', ...props.style }">
|
|
9
4
|
<slot>
|
|
10
5
|
<template v-if="typeof props.content === 'string'">
|
|
11
6
|
<p>{{ props.content }}</p>
|
|
@@ -17,33 +12,27 @@
|
|
|
17
12
|
<template v-if="props.footer" #footer>
|
|
18
13
|
<slot name="footer">
|
|
19
14
|
<template v-if="typeof props.footer === 'boolean'">
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
{{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</el-button>
|
|
26
|
-
<el-button
|
|
27
|
-
type="primary"
|
|
28
|
-
v-bind="props.okButtonProps"
|
|
29
|
-
:loading="okLoading"
|
|
30
|
-
@click="handleOk"
|
|
31
|
-
>
|
|
15
|
+
<ElSpace :size="10">
|
|
16
|
+
<ElButton v-bind="props.cancelButtonProps" @click="handleCancel">
|
|
17
|
+
{{ props.cancelText }}
|
|
18
|
+
</ElButton>
|
|
19
|
+
<ElButton type="primary" v-bind="props.okButtonProps" :loading="okLoading" @click="handleOk">
|
|
32
20
|
{{ props.okText }}
|
|
33
|
-
</
|
|
34
|
-
</
|
|
21
|
+
</ElButton>
|
|
22
|
+
</ElSpace>
|
|
35
23
|
</template>
|
|
36
24
|
<template v-else>
|
|
37
25
|
<component :is="props.footer()"></component>
|
|
38
26
|
</template>
|
|
39
27
|
</slot>
|
|
40
28
|
</template>
|
|
41
|
-
</
|
|
29
|
+
</ElDialog>
|
|
42
30
|
</template>
|
|
43
31
|
|
|
44
32
|
<script lang="ts" setup>
|
|
45
33
|
import type { VNode } from 'vue'
|
|
46
34
|
import type { DialogProps } from './type'
|
|
35
|
+
import { ElButton, ElDialog, ElSpace } from 'element-plus'
|
|
47
36
|
import { computed, defineProps, defineSlots, ref } from 'vue'
|
|
48
37
|
import { useBemClass } from '../../../hooks'
|
|
49
38
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ElDrawer v-bind="dialogProps" v-model="visible" :class="getClass" :title="props.title" :style="{ ...props.style }">
|
|
3
|
+
<slot>
|
|
4
|
+
<template v-if="typeof props.content === 'string'">
|
|
5
|
+
<p>{{ props.content }}</p>
|
|
6
|
+
</template>
|
|
7
|
+
<template v-if="typeof props.content === 'function'">
|
|
8
|
+
<component :is="props?.content?.()"></component>
|
|
9
|
+
</template>
|
|
10
|
+
</slot>
|
|
11
|
+
<template v-if="props.footer" #footer>
|
|
12
|
+
<slot name="footer">
|
|
13
|
+
<template v-if="typeof props.footer === 'boolean'">
|
|
14
|
+
<ElSpace :size="10">
|
|
15
|
+
<ElButton v-bind="props.cancelButtonProps" @click="handleCancel">
|
|
16
|
+
{{ props.cancelText }}
|
|
17
|
+
</ElButton>
|
|
18
|
+
<ElButton type="primary" v-bind="props.okButtonProps" :loading="okLoading" @click="handleOk">
|
|
19
|
+
{{ props.okText }}
|
|
20
|
+
</ElButton>
|
|
21
|
+
</ElSpace>
|
|
22
|
+
</template>
|
|
23
|
+
<template v-else>
|
|
24
|
+
<component :is="props.footer()"></component>
|
|
25
|
+
</template>
|
|
26
|
+
</slot>
|
|
27
|
+
</template>
|
|
28
|
+
</ElDrawer>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts" setup>
|
|
32
|
+
import type { VNode } from 'vue'
|
|
33
|
+
import type { DrawerProps } from './type'
|
|
34
|
+
import { ElButton, ElDrawer, ElSpace } from 'element-plus'
|
|
35
|
+
import { computed, defineProps, defineSlots, ref } from 'vue'
|
|
36
|
+
import { useBemClass } from '../../../hooks'
|
|
37
|
+
|
|
38
|
+
const visible = defineModel('modelValue', {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
default: false
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const props = withDefaults(defineProps<DrawerProps>(), {
|
|
44
|
+
title: '',
|
|
45
|
+
withHeader: true,
|
|
46
|
+
closeOnClickModal: true,
|
|
47
|
+
closeOnPressEscape: true,
|
|
48
|
+
lockScroll: true,
|
|
49
|
+
modal: true,
|
|
50
|
+
showClose: true,
|
|
51
|
+
footer: true,
|
|
52
|
+
okText: '确认',
|
|
53
|
+
cancelText: '取消',
|
|
54
|
+
size: '300px',
|
|
55
|
+
appendTo: 'body'
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
defineSlots<{
|
|
59
|
+
title: () => VNode
|
|
60
|
+
footer: () => VNode
|
|
61
|
+
default: () => VNode
|
|
62
|
+
}>()
|
|
63
|
+
|
|
64
|
+
const { b } = useBemClass()
|
|
65
|
+
|
|
66
|
+
const getClass = computed(() => {
|
|
67
|
+
const arr: string[] = [b('drawer')]
|
|
68
|
+
return arr.join(' ')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const dialogProps = computed(() => {
|
|
72
|
+
return {
|
|
73
|
+
...props,
|
|
74
|
+
content: undefined,
|
|
75
|
+
footer: undefined,
|
|
76
|
+
okText: undefined,
|
|
77
|
+
cancelText: undefined,
|
|
78
|
+
okButtonProps: undefined,
|
|
79
|
+
cancelButtonProps: undefined,
|
|
80
|
+
onOk: undefined,
|
|
81
|
+
onBeforeOk: undefined,
|
|
82
|
+
onCancel: undefined,
|
|
83
|
+
simple: undefined
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const okLoading = ref(false)
|
|
88
|
+
|
|
89
|
+
const handleCancel = () => {
|
|
90
|
+
props.onCancel?.()
|
|
91
|
+
visible.value = false
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const handleOk = async () => {
|
|
95
|
+
if (props.onBeforeOk) {
|
|
96
|
+
try {
|
|
97
|
+
okLoading.value = true
|
|
98
|
+
const flag = await props.onBeforeOk()
|
|
99
|
+
okLoading.value = false
|
|
100
|
+
if (flag) {
|
|
101
|
+
visible.value = false
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('error', error)
|
|
105
|
+
okLoading.value = false
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
props.onOk?.()
|
|
109
|
+
visible.value = false
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ButtonProps, DrawerProps as ElDrawerProps } from 'element-plus'
|
|
2
|
+
import type { CSSProperties, VNode } from 'vue'
|
|
3
|
+
|
|
4
|
+
export interface DrawerProps extends Partial<ElDrawerProps> {
|
|
5
|
+
content?: string | (() => VNode)
|
|
6
|
+
footer?: boolean | (() => VNode)
|
|
7
|
+
okText?: string
|
|
8
|
+
cancelText?: string
|
|
9
|
+
okButtonProps?: Partial<ButtonProps>
|
|
10
|
+
cancelButtonProps?: Partial<ButtonProps>
|
|
11
|
+
style?: CSSProperties
|
|
12
|
+
onOk?: () => void
|
|
13
|
+
onBeforeOk?: () => Promise<boolean>
|
|
14
|
+
onCancel?: () => void
|
|
15
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
2
|
+
<ElForm ref="formRef" :model="form" :class="b('edit-table')">
|
|
3
|
+
<ElTable :data="form.tableData" border v-bind="attrs">
|
|
4
|
+
<ElTableColumn v-for="(column, index) in props.columns" :key="column.prop + index" :width="column.width"
|
|
5
5
|
v-bind="column.columnProps" :prop="column.prop" :label="column.label"
|
|
6
6
|
:label-class-name="getLabelClassName(column)">
|
|
7
7
|
<template #default="scope">
|
|
8
|
-
<
|
|
8
|
+
<ElFormItem v-bind="column.formItemProps" :label="column.label"
|
|
9
9
|
:prop="`tableData[${scope.$index}].${column.prop}`" :rules="getFormItemRules(column)">
|
|
10
10
|
<template v-if="column.slotName">
|
|
11
11
|
<slot :name="column.slotName" v-bind="scope"></slot>
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
<component :is="COMP_MAP[column.type] || column.type" v-else v-bind="getComponentBindProps(column)"
|
|
15
15
|
v-model="scope.row[column.prop]" class="w-full" :disabled="isDisabled(scope)">
|
|
16
16
|
</component>
|
|
17
|
-
</
|
|
17
|
+
</ElFormItem>
|
|
18
18
|
</template>
|
|
19
|
-
</
|
|
20
|
-
</
|
|
21
|
-
</
|
|
19
|
+
</ElTableColumn>
|
|
20
|
+
</ElTable>
|
|
21
|
+
</ElForm>
|
|
22
22
|
</template>
|
|
23
23
|
|
|
24
24
|
<script lang="ts" setup>
|
|
@@ -26,6 +26,7 @@ import type { FormInstance } from 'element-plus'
|
|
|
26
26
|
import type { EditTableColumnItem, EditTableColumnItemType } from './type'
|
|
27
27
|
import type { EditTableProps } from './type.ts'
|
|
28
28
|
import * as El from 'element-plus'
|
|
29
|
+
import { ElForm, ElFormItem, ElTable, ElTableColumn } from 'element-plus'
|
|
29
30
|
import { computed, ref, useAttrs } from 'vue'
|
|
30
31
|
import { useBemClass } from '../../../hooks'
|
|
31
32
|
import InputSearch from '../../input-search'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<ElForm ref="formRef" :class="getClass" v-bind="formProps" :model="props.modelValue">
|
|
3
3
|
<Grid class="w-full" :col-gap="12" v-bind="props.gridProps" :collapsed="collapsed">
|
|
4
4
|
<template v-for="(item, index) in props.columns">
|
|
5
5
|
<GridItem v-if="item.type === 'title'" :key="`title${index}`" :span="100">
|
|
6
|
-
<
|
|
6
|
+
<ElFormItem label-width="0">
|
|
7
7
|
<GiCard :title="typeof item.label === 'string' ? item.label : ''" :header-style="{ padding: 0 }"
|
|
8
8
|
:body-style="{ display: 'none' }"></GiCard>
|
|
9
|
-
</
|
|
9
|
+
</ElFormItem>
|
|
10
10
|
</GridItem>
|
|
11
11
|
|
|
12
12
|
<template v-else>
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
|| item.gridItemProps?.span
|
|
16
16
|
|| props?.gridItemProps?.span
|
|
17
17
|
">
|
|
18
|
-
<
|
|
19
|
-
|
|
18
|
+
<ElFormItem :key="item.field + index" :prop="item.field" :label="item.label" :rules="getFormItemRules(item)"
|
|
19
|
+
v-bind="item.formItemProps">
|
|
20
20
|
<template v-if="item?.labelRender" #label>
|
|
21
21
|
<component :is="item.labelRender"></component>
|
|
22
22
|
</template>
|
|
@@ -38,18 +38,18 @@
|
|
|
38
38
|
</template>
|
|
39
39
|
</template>
|
|
40
40
|
</component>
|
|
41
|
-
<
|
|
41
|
+
<ElText v-if="item.tip" :class="b('form-item__tip')" type="info" size="small">
|
|
42
42
|
{{ item.tip }}
|
|
43
|
-
</
|
|
43
|
+
</ElText>
|
|
44
44
|
</div>
|
|
45
45
|
<!-- 额外信息 -->
|
|
46
46
|
<div v-if="item.extra" :class="b('form-item__extra')">
|
|
47
47
|
<template v-if="typeof item.extra === 'string'">
|
|
48
|
-
<
|
|
48
|
+
<ElText type="info" size="small">
|
|
49
49
|
{{
|
|
50
50
|
item.extra
|
|
51
51
|
}}
|
|
52
|
-
</
|
|
52
|
+
</ElText>
|
|
53
53
|
</template>
|
|
54
54
|
<template v-else-if="item.extra">
|
|
55
55
|
<component :is="item.extra"></component>
|
|
@@ -57,25 +57,25 @@
|
|
|
57
57
|
</div>
|
|
58
58
|
</div>
|
|
59
59
|
</template>
|
|
60
|
-
</
|
|
60
|
+
</ElFormItem>
|
|
61
61
|
</GridItem>
|
|
62
62
|
</template>
|
|
63
63
|
</template>
|
|
64
64
|
|
|
65
65
|
<GridItem v-if="props.search" :suffix="props.search" :span="props?.gridItemProps?.span">
|
|
66
|
-
<
|
|
67
|
-
<
|
|
66
|
+
<ElSpace :class="b('form__search-btns')">
|
|
67
|
+
<ElButton type="primary" @click="emit('search')">
|
|
68
68
|
{{ searchText }}
|
|
69
|
-
</
|
|
70
|
-
<
|
|
71
|
-
<
|
|
69
|
+
</ElButton>
|
|
70
|
+
<ElButton @click="emit('reset')"> 重置 </ElButton>
|
|
71
|
+
<ElButton v-if="!props.hideFoldBtn" class="form__fold-btn" type="primary"
|
|
72
72
|
:icon="collapsed ? ArrowDown : ArrowUp" text size="small" @click="collapsed = !collapsed">
|
|
73
73
|
{{ collapsed ? '展开' : '收起' }}
|
|
74
|
-
</
|
|
75
|
-
</
|
|
74
|
+
</ElButton>
|
|
75
|
+
</ElSpace>
|
|
76
76
|
</GridItem>
|
|
77
77
|
</Grid>
|
|
78
|
-
</
|
|
78
|
+
</ElForm>
|
|
79
79
|
</template>
|
|
80
80
|
|
|
81
81
|
<script lang="tsx" setup>
|
|
@@ -83,6 +83,7 @@ import type { FormInstance } from 'element-plus'
|
|
|
83
83
|
import type { FormColumnItem, FormColumnType, FormProps } from './type'
|
|
84
84
|
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'
|
|
85
85
|
import * as El from 'element-plus'
|
|
86
|
+
import { ElButton, ElForm, ElFormItem, ElSpace, ElText } from 'element-plus'
|
|
86
87
|
import {
|
|
87
88
|
computed,
|
|
88
89
|
getCurrentInstance,
|
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<InputGroup :class="b('input-search')">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
:placeholder="props.placeholder"
|
|
8
|
-
>
|
|
9
|
-
</el-input>
|
|
10
|
-
<el-button
|
|
11
|
-
v-if="showButton"
|
|
12
|
-
:icon="Search"
|
|
13
|
-
:disabled="props.disabled"
|
|
14
|
-
@click="emit('search')"
|
|
15
|
-
></el-button>
|
|
16
|
-
<el-button
|
|
17
|
-
v-if="showButton"
|
|
18
|
-
:icon="Close"
|
|
19
|
-
:disabled="props.disabled"
|
|
20
|
-
@click="emit('clear')"
|
|
21
|
-
></el-button>
|
|
3
|
+
<ElInput v-model="model" :disabled="props.disabled" :readonly="!props.disabled" :placeholder="props.placeholder">
|
|
4
|
+
</ElInput>
|
|
5
|
+
<ElButton v-if="showButton" :icon="Search" :disabled="props.disabled" @click="emit('search')"></ElButton>
|
|
6
|
+
<ElButton v-if="showButton" :icon="Close" :disabled="props.disabled" @click="emit('clear')"></ElButton>
|
|
22
7
|
</InputGroup>
|
|
23
8
|
</template>
|
|
24
9
|
|
|
25
10
|
<script setup lang="ts">
|
|
26
11
|
import type { InputSearchProps } from './type'
|
|
27
12
|
import { Close, Search } from '@element-plus/icons-vue'
|
|
13
|
+
import { ElButton, ElInput } from 'element-plus'
|
|
28
14
|
import { computed } from 'vue'
|
|
29
15
|
import { useBemClass } from '../../../hooks'
|
|
30
16
|
import InputGroup from '../../input-group/src/input-group.vue'
|
|
@@ -1,42 +1,32 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
2
|
+
<ElSplitter :class="getClass">
|
|
3
|
+
<ElSplitterPanel v-if="slots.left" v-model:size="size">
|
|
4
4
|
<div :class="b('page-layout__left')" :style="props.leftStyle">
|
|
5
5
|
<slot name="left"></slot>
|
|
6
6
|
</div>
|
|
7
|
-
</
|
|
7
|
+
</ElSplitterPanel>
|
|
8
8
|
<div v-if="slots.left && props.collapse" :class="b('page-layout__split')">
|
|
9
|
-
<SplitButton
|
|
10
|
-
:collapsed="Number(size) === 0"
|
|
11
|
-
@click="handleClick"
|
|
12
|
-
></SplitButton>
|
|
9
|
+
<SplitButton :collapsed="Number(size) === 0" @click="handleClick"></SplitButton>
|
|
13
10
|
</div>
|
|
14
|
-
<
|
|
11
|
+
<ElSplitterPanel>
|
|
15
12
|
<div :class="b('page-layout__right')">
|
|
16
|
-
<div
|
|
17
|
-
v-if="slots.header"
|
|
18
|
-
:class="b('page-layout__header')"
|
|
19
|
-
:style="props.headerStyle"
|
|
20
|
-
>
|
|
13
|
+
<div v-if="slots.header" :class="b('page-layout__header')" :style="props.headerStyle">
|
|
21
14
|
<slot name="header"></slot>
|
|
22
15
|
</div>
|
|
23
|
-
<div
|
|
24
|
-
v-if="slots.tool"
|
|
25
|
-
:class="b('page-layout__tool')"
|
|
26
|
-
:style="props.toolStyle"
|
|
27
|
-
>
|
|
16
|
+
<div v-if="slots.tool" :class="b('page-layout__tool')" :style="props.toolStyle">
|
|
28
17
|
<slot name="tool"></slot>
|
|
29
18
|
</div>
|
|
30
19
|
<div :class="b('page-layout__body')" :style="props.bodyStyle">
|
|
31
20
|
<slot></slot>
|
|
32
21
|
</div>
|
|
33
22
|
</div>
|
|
34
|
-
</
|
|
35
|
-
</
|
|
23
|
+
</ElSplitterPanel>
|
|
24
|
+
</ElSplitter>
|
|
36
25
|
</template>
|
|
37
26
|
|
|
38
27
|
<script lang="ts" setup>
|
|
39
28
|
import type { PageLayoutProps } from './type'
|
|
29
|
+
import { ElSplitter, ElSplitterPanel } from 'element-plus'
|
|
40
30
|
import { computed, ref, useSlots } from 'vue'
|
|
41
31
|
import { useBemClass } from '../../../hooks'
|
|
42
32
|
import SplitButton from './split-button.vue'
|
|
@@ -93,6 +83,7 @@ function handleClick() {
|
|
|
93
83
|
@use '../../../styles/var.scss' as a;
|
|
94
84
|
|
|
95
85
|
:deep(.el-splitter-bar__dragger-horizontal) {
|
|
86
|
+
|
|
96
87
|
&::before,
|
|
97
88
|
&::after {
|
|
98
89
|
width: 1px;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="getClass" @click="handleClick">
|
|
3
|
-
<
|
|
3
|
+
<ElIcon :size="props.iconSize">
|
|
4
4
|
<ArrowRightBold v-if="collapsed" :size="iconSize" />
|
|
5
5
|
<ArrowLeftBold v-else :size="iconSize" />
|
|
6
|
-
</
|
|
6
|
+
</ElIcon>
|
|
7
7
|
</div>
|
|
8
8
|
</template>
|
|
9
9
|
|
|
10
10
|
<script setup lang="ts">
|
|
11
11
|
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue'
|
|
12
|
+
import { ElIcon } from 'element-plus'
|
|
12
13
|
import { computed } from 'vue'
|
|
13
14
|
import { useBemClass } from '../../../hooks'
|
|
14
15
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<ElTableColumn v-bind="columnProps">
|
|
3
3
|
<!-- 处理render函数 -->
|
|
4
4
|
<template v-if="column.render" #default="scope">
|
|
5
5
|
<template v-if="typeof column.render(scope) === 'string'">{{ column.render(scope) }}</template>
|
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
</template>
|
|
21
21
|
</TableColumn>
|
|
22
22
|
</template>
|
|
23
|
-
</
|
|
23
|
+
</ElTableColumn>
|
|
24
24
|
</template>
|
|
25
25
|
|
|
26
26
|
<script lang="ts" setup>
|
|
27
27
|
import type { TableColumnItem } from './type'
|
|
28
|
+
import { ElTableColumn } from 'element-plus'
|
|
28
29
|
import { computed } from 'vue'
|
|
29
30
|
import TableColumn from './TableColumn.vue'
|
|
30
31
|
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="b('table')">
|
|
3
|
-
<
|
|
3
|
+
<ElTable v-bind="tableProps" ref="tableRef" :data="props.data as any[]">
|
|
4
4
|
<TableColumn v-for="item in props.columns" :key="item.prop || item.label" :column="item">
|
|
5
5
|
<!-- 将所有插槽传递给子组件 -->
|
|
6
6
|
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="scope">
|
|
7
7
|
<slot :name="slotName" v-bind="scope" />
|
|
8
8
|
</template>
|
|
9
9
|
</TableColumn>
|
|
10
|
-
</
|
|
10
|
+
</ElTable>
|
|
11
11
|
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
v-model:page-size="paginationProps.pageSize"
|
|
15
|
-
|
|
16
|
-
</el-row>
|
|
12
|
+
<ElRow justify="end" :class="b('table-pagination')">
|
|
13
|
+
<ElPagination v-bind="paginationProps" v-model:current-page="paginationProps.currentPage"
|
|
14
|
+
v-model:page-size="paginationProps.pageSize" />
|
|
15
|
+
</ElRow>
|
|
17
16
|
</div>
|
|
18
17
|
</template>
|
|
19
18
|
|
|
20
19
|
<script lang="ts" setup>
|
|
21
20
|
import type { TableProps } from './type'
|
|
21
|
+
import { ElPagination, ElRow, ElTable } from 'element-plus'
|
|
22
22
|
import { computed, useAttrs, useTemplateRef } from 'vue'
|
|
23
23
|
import { useBemClass } from '../../../hooks'
|
|
24
24
|
import TableColumn from './TableColumn.vue'
|
|
@@ -50,16 +50,6 @@ const paginationProps = computed(() => {
|
|
|
50
50
|
}
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
function handleSizeChange(size: number) {
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
props.pagination.pageSize = size
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function handleCurrentChange(page: number) {
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
props.pagination.currentPage = page
|
|
61
|
-
}
|
|
62
|
-
|
|
63
53
|
defineExpose({
|
|
64
54
|
tableRef
|
|
65
55
|
})
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
<div :class="getClass">
|
|
3
3
|
<div :class="b('tabs__default')">
|
|
4
4
|
<slot>
|
|
5
|
-
<
|
|
6
|
-
@tab-click="(p, e) => emits('
|
|
7
|
-
<
|
|
5
|
+
<ElTabs v-model="model" :type="props.type" :stretch="props.stretch"
|
|
6
|
+
@tab-click="(p, e) => emits('tab-click', p, e)" @tab-change="emits('tab-change', $event as any)">
|
|
7
|
+
<ElTabPane v-for="item in props.options" :key="item.name" :name="item.name" :disabled="item?.disabled">
|
|
8
8
|
<template #label>
|
|
9
9
|
<slot name="label" :data="item">{{ item.label }}</slot>
|
|
10
10
|
</template>
|
|
11
|
-
</
|
|
12
|
-
</
|
|
11
|
+
</ElTabPane>
|
|
12
|
+
</ElTabs>
|
|
13
13
|
</slot>
|
|
14
14
|
</div>
|
|
15
15
|
<div v-if="slots.extra" :class="b('tabs__extra')">
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
<script setup lang="ts">
|
|
22
22
|
import type { TabsProps as ElTabsProps, TabsPaneContext } from 'element-plus'
|
|
23
23
|
import type { TabsOptionItem, TabsProps } from './type.ts'
|
|
24
|
+
import { ElTabPane, ElTabs } from 'element-plus'
|
|
24
25
|
import { computed, useSlots } from 'vue'
|
|
25
26
|
import { useBemClass } from '../../../hooks'
|
|
26
27
|
|
|
@@ -34,8 +35,8 @@ const props = withDefaults(defineProps<TabsProps>(), {
|
|
|
34
35
|
})
|
|
35
36
|
|
|
36
37
|
const emits = defineEmits<{
|
|
37
|
-
(e: '
|
|
38
|
-
(e: '
|
|
38
|
+
(e: 'tab-click', pane: TabsPaneContext, ev: Event): void
|
|
39
|
+
(e: 'tab-change', value: string): void
|
|
39
40
|
}>()
|
|
40
41
|
|
|
41
42
|
defineSlots<{
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="el-transfer">
|
|
3
|
+
<div class="el-transfer-panel">
|
|
4
|
+
<div class="el-transfer-panel__header" @click="handleLeftAllChecked">
|
|
5
|
+
<ElCheckbox class="hide-checkbox" :model-value="leftAllChecked">
|
|
6
|
+
{{ props.titles[0] }}<span>{{ `${leftObj.checkedKeys.length}/${leftObj.total}`
|
|
7
|
+
}}</span>
|
|
8
|
+
</ElCheckbox>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="el-transfer-panel__body">
|
|
11
|
+
<ElScrollbar>
|
|
12
|
+
<ElTree ref="treeRef" :data="leftTreeData" default-expand-all show-checkbox v-bind="props.treeProps"
|
|
13
|
+
@check="handleCheck" />
|
|
14
|
+
</ElScrollbar>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="el-transfer__buttons">
|
|
19
|
+
<ElSpace>
|
|
20
|
+
<ElButton type="primary" :disabled="!rightObj.checkedKeys.length" @click="handleMoveLeft">
|
|
21
|
+
<ElIcon>
|
|
22
|
+
<ArrowLeft />
|
|
23
|
+
</ElIcon>
|
|
24
|
+
</ElButton>
|
|
25
|
+
<ElButton type="primary" :disabled="!leftObj.checkedKeys.length" @click="handleMoveRight">
|
|
26
|
+
<ElIcon>
|
|
27
|
+
<ArrowRight />
|
|
28
|
+
</ElIcon>
|
|
29
|
+
</ElButton>
|
|
30
|
+
</ElSpace>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="el-transfer-panel">
|
|
34
|
+
<div class="el-transfer-panel__header" @click="handleRightAllChecked">
|
|
35
|
+
<ElCheckbox :model-value="rightAllChecked">
|
|
36
|
+
{{ props.titles[1] }}<span>{{ `${rightObj.checkedKeys.length}/${rightObj.options.length}`
|
|
37
|
+
}}</span>
|
|
38
|
+
</ElCheckbox>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="el-transfer-panel__body">
|
|
41
|
+
<ElScrollbar>
|
|
42
|
+
<ElCheckboxGroup v-if="rightObj.options.length" v-model="rightObj.checkedKeys"
|
|
43
|
+
class="el-transfer-panel__list">
|
|
44
|
+
<ElCheckbox v-for="(item, index) in rightObj.options" :key="index" :label="item.label" :value="item.value"
|
|
45
|
+
class="el-transfer-panel__item" />
|
|
46
|
+
</ElCheckboxGroup>
|
|
47
|
+
<ElEmpty v-else :image-size="60"></ElEmpty>
|
|
48
|
+
</ElScrollbar>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup lang="ts">
|
|
55
|
+
import type { CheckboxOption, TreeInstance } from 'element-plus'
|
|
56
|
+
import type { PropType } from 'vue'
|
|
57
|
+
import type { TreeTransferProps } from './type'
|
|
58
|
+
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
|
|
59
|
+
import { ElButton, ElCheckbox, ElCheckboxGroup, ElEmpty, ElIcon, ElScrollbar, ElSpace, ElTree } from 'element-plus'
|
|
60
|
+
import { computed, onMounted, reactive, ref } from 'vue'
|
|
61
|
+
import pkg from 'xe-utils'
|
|
62
|
+
import { filterTree } from './utils'
|
|
63
|
+
|
|
64
|
+
// 右边的列表keys
|
|
65
|
+
const selectedKeys = defineModel('selectedKeys', { type: Array as PropType<string[]>, default: () => [] })
|
|
66
|
+
|
|
67
|
+
const props = withDefaults(defineProps<TreeTransferProps>(), {
|
|
68
|
+
titles: () => ['列表', '列表'],
|
|
69
|
+
data: () => [],
|
|
70
|
+
treeProps: () => ({})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const { eachTree } = pkg
|
|
74
|
+
|
|
75
|
+
const treeRef = ref<TreeInstance | null>(null)
|
|
76
|
+
const nodeKey = computed(() => props.treeProps?.nodeKey || 'id')
|
|
77
|
+
|
|
78
|
+
const leftObj = reactive({
|
|
79
|
+
checkedKeys: [] as string[],
|
|
80
|
+
total: 0,
|
|
81
|
+
options: [] as CheckboxOption[]
|
|
82
|
+
})
|
|
83
|
+
const rightObj = reactive({
|
|
84
|
+
checkedKeys: [] as string[],
|
|
85
|
+
options: [] as CheckboxOption[]
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const leftAllChecked = computed(() => {
|
|
89
|
+
const arr: string[] = []
|
|
90
|
+
eachTree(props.data, (i) => {
|
|
91
|
+
if (i.children === undefined) {
|
|
92
|
+
arr.push(i[nodeKey.value])
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
return arr.every((i) => leftObj.checkedKeys.includes(i))
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const getLeftTreeNodes = () => {
|
|
99
|
+
const arr: any[] = []
|
|
100
|
+
eachTree(props.data, (i) => {
|
|
101
|
+
if (i.children === undefined) {
|
|
102
|
+
arr.push(i)
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
return arr
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function handleLeftAllChecked() {
|
|
109
|
+
if (leftAllChecked.value) {
|
|
110
|
+
leftObj.checkedKeys = []
|
|
111
|
+
leftObj.options = []
|
|
112
|
+
treeRef.value?.setCheckedKeys([])
|
|
113
|
+
} else {
|
|
114
|
+
const arr = getLeftTreeNodes()
|
|
115
|
+
leftObj.checkedKeys = arr.map((i) => i[nodeKey.value])
|
|
116
|
+
leftObj.options = arr.map((i) => ({ label: i.label, value: i[nodeKey.value] }))
|
|
117
|
+
treeRef.value?.setCheckedKeys(leftObj.checkedKeys)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const rightAllChecked = computed(() => rightObj.checkedKeys.length === rightObj.options.length && rightObj.options.length !== 0)
|
|
122
|
+
function handleRightAllChecked() {
|
|
123
|
+
if (rightAllChecked.value) {
|
|
124
|
+
rightObj.checkedKeys = []
|
|
125
|
+
} else {
|
|
126
|
+
rightObj.checkedKeys = rightObj.options.map((i) => i.value as string)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const leftTreeData = computed(() => {
|
|
131
|
+
const treeData = JSON.parse(JSON.stringify(props.data))
|
|
132
|
+
const rightListKeys = rightObj.options.map((i) => i.value)
|
|
133
|
+
const data = filterTree(treeData, (i: any) => !rightListKeys.includes(i[nodeKey.value]))
|
|
134
|
+
return data
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
const handleCheck = (data: any, obj: any) => {
|
|
138
|
+
console.log(data, obj)
|
|
139
|
+
leftObj.checkedKeys = obj.checkedNodes.filter((i: any) => i?.children === undefined).map((j: any) => j[nodeKey.value])
|
|
140
|
+
leftObj.options = obj.checkedNodes.filter((i: any) => i?.children === undefined).map((j: any) => ({ label: j.label, value: j[nodeKey.value] }))
|
|
141
|
+
// leftObj.checkedKeys = obj.checkedNodes.map((i: any) => i[nodeKey.value])
|
|
142
|
+
// leftObj.options = obj.checkedNodes.map((j: any) => ({ label: j.label, value: j[nodeKey.value] }))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function getLeftTotal() {
|
|
146
|
+
const data: any[] = []
|
|
147
|
+
eachTree(props.data, (i) => {
|
|
148
|
+
if (i.children === undefined) {
|
|
149
|
+
data.push(i[props?.treeProps?.nodeKey || 'id'])
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
return data.length
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const handleMoveLeft = () => {
|
|
156
|
+
if (rightObj.checkedKeys.length) {
|
|
157
|
+
leftObj.checkedKeys = []
|
|
158
|
+
leftObj.options = []
|
|
159
|
+
rightObj.options = rightObj.options.filter((i) => !rightObj.checkedKeys.includes(i.value as string))
|
|
160
|
+
rightObj.checkedKeys = []
|
|
161
|
+
selectedKeys.value = rightObj.options.map((i) => i.value as string)
|
|
162
|
+
treeRef.value?.setCheckedKeys([])
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const handleMoveRight = () => {
|
|
167
|
+
rightObj.options = [...rightObj.options, ...leftObj.options]
|
|
168
|
+
leftObj.checkedKeys = []
|
|
169
|
+
leftObj.options = []
|
|
170
|
+
selectedKeys.value = rightObj.options.map((i) => i.value as string)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 获取初始选中
|
|
174
|
+
const setInitChecked = () => {
|
|
175
|
+
const arr: CheckboxOption[] = []
|
|
176
|
+
eachTree(props.data, (i) => {
|
|
177
|
+
if (selectedKeys.value.includes(i[nodeKey.value] as string)) {
|
|
178
|
+
arr.push({ label: i.label, value: i[nodeKey.value] as string })
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
rightObj.options = arr
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
onMounted(() => {
|
|
185
|
+
leftObj.total = getLeftTotal()
|
|
186
|
+
setInitChecked()
|
|
187
|
+
})
|
|
188
|
+
</script>
|
|
189
|
+
|
|
190
|
+
<style lang="scss" scoped>
|
|
191
|
+
.el-transfer-panel__list {
|
|
192
|
+
height: auto;
|
|
193
|
+
}
|
|
194
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import pkg from 'xe-utils'
|
|
2
|
+
|
|
3
|
+
const { mapTree } = pkg
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @desc 过滤树
|
|
7
|
+
* @param { values } 数组
|
|
8
|
+
*/
|
|
9
|
+
type FilterTree = <T extends { children?: T[] }>(
|
|
10
|
+
array: T[],
|
|
11
|
+
iterate: (item: T, index?: number, items?: T[]) => boolean
|
|
12
|
+
) => T[]
|
|
13
|
+
|
|
14
|
+
export const filterTree: FilterTree = (values, fn) => {
|
|
15
|
+
const arr = values.filter(fn)
|
|
16
|
+
const data = mapTree(arr, (item) => {
|
|
17
|
+
if (item.children && item.children.length) {
|
|
18
|
+
item.children = item.children.filter(fn)
|
|
19
|
+
}
|
|
20
|
+
return item
|
|
21
|
+
})
|
|
22
|
+
return data
|
|
23
|
+
}
|
package/packages/components.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Generated by unplugin-vue-components
|
|
4
4
|
// Read more: https://github.com/vuejs/core/pull/3399
|
|
5
5
|
// biome-ignore lint: disable
|
|
6
|
-
export {}
|
|
6
|
+
export { }
|
|
7
7
|
|
|
8
8
|
/* prettier-ignore */
|
|
9
9
|
declare module 'vue' {
|
|
@@ -11,6 +11,7 @@ declare module 'vue' {
|
|
|
11
11
|
GiButton: typeof import('./components/button/src/button.vue')['default']
|
|
12
12
|
GiCard: typeof import('./components/card/src/card.vue')['default']
|
|
13
13
|
GiDialog: typeof import('./components/dialog/src/dialog.vue')['default']
|
|
14
|
+
GiDrawer: typeof import('./components/drawer/src/drawer.vue')['default']
|
|
14
15
|
GiEditTable: typeof import('./components/edit-table/src/edit-table.vue')['default']
|
|
15
16
|
GiForm: typeof import('./components/form/src/form.vue')['default']
|
|
16
17
|
GiGrid: typeof import('./components/grid/src/grid.vue')['default']
|
|
@@ -22,5 +23,6 @@ declare module 'vue' {
|
|
|
22
23
|
GiTable: typeof import('./components/table/src/table.vue')['default']
|
|
23
24
|
GiTableColumn: typeof import('./components/table/src/TableColumn.vue')['default']
|
|
24
25
|
GiTabs: typeof import('./components/tabs/src/tabs.vue')['default']
|
|
26
|
+
GiTreeTransfer: typeof import('./components/tree-transfer/src/tree-transfer.vue')['default']
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Ref } from 'vue'
|
|
1
|
+
import type { Ref } from 'vue'
|
|
2
2
|
import { reactive, ref } from 'vue'
|
|
3
3
|
|
|
4
4
|
interface Options<T, U> {
|
|
@@ -94,4 +94,4 @@ export function useTable<T extends U, U = T>(api: UseTableApi<T>, options: Optio
|
|
|
94
94
|
/** 刷新 */
|
|
95
95
|
refresh
|
|
96
96
|
}
|
|
97
|
-
}
|
|
97
|
+
}
|
package/packages/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { App } from 'vue'
|
|
|
3
3
|
import Button from './components/button'
|
|
4
4
|
import Card from './components/card'
|
|
5
5
|
import Dialog from './components/dialog'
|
|
6
|
+
import Drawer from './components/drawer'
|
|
6
7
|
import EditTable from './components/edit-table'
|
|
7
8
|
import Form from './components/form'
|
|
8
9
|
import GridItem from './components/grid/src/grid-item.vue'
|
|
@@ -12,9 +13,11 @@ import InputSearch from './components/input-search'
|
|
|
12
13
|
import PageLayout from './components/page-layout'
|
|
13
14
|
import Table from './components/table'
|
|
14
15
|
import Tabs from './components/tabs'
|
|
16
|
+
import TreeTransfer from './components/tree-transfer'
|
|
15
17
|
import './styles/index.scss'
|
|
16
18
|
|
|
17
19
|
export * from './components/dialog'
|
|
20
|
+
export * from './components/drawer'
|
|
18
21
|
export * from './components/edit-table'
|
|
19
22
|
export * from './components/form'
|
|
20
23
|
export * from './components/table'
|
|
@@ -25,6 +28,7 @@ export * from './utils'
|
|
|
25
28
|
const components = {
|
|
26
29
|
Button,
|
|
27
30
|
Card,
|
|
31
|
+
Drawer,
|
|
28
32
|
Tabs,
|
|
29
33
|
InputGroup,
|
|
30
34
|
InputSearch,
|
|
@@ -34,12 +38,14 @@ const components = {
|
|
|
34
38
|
PageLayout,
|
|
35
39
|
Dialog,
|
|
36
40
|
EditTable,
|
|
37
|
-
Table
|
|
41
|
+
Table,
|
|
42
|
+
TreeTransfer
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
// 导出Gi前缀的组件并添加明确类型注解
|
|
41
46
|
export const GiButton: typeof Button = Button
|
|
42
47
|
export const GiCard: typeof Card = Card
|
|
48
|
+
export const GiDrawer: typeof Drawer = Drawer
|
|
43
49
|
export const GiTabs: typeof Tabs = Tabs
|
|
44
50
|
export const GiInputGroup: typeof InputGroup = InputGroup
|
|
45
51
|
export const GiInputSearch: typeof InputSearch = InputSearch
|
|
@@ -50,6 +56,7 @@ export const GiPageLayout: typeof PageLayout = PageLayout
|
|
|
50
56
|
export const GiDialog: typeof Dialog = Dialog
|
|
51
57
|
export const GiEditTable: typeof EditTable = EditTable
|
|
52
58
|
export const GiTable: typeof Table = Table
|
|
59
|
+
export const GiTreeTransfer: typeof TreeTransfer = TreeTransfer
|
|
53
60
|
|
|
54
61
|
function capitalizeWord(word: string) {
|
|
55
62
|
// 检查输入是否为字符串且不为空
|
|
@@ -9,6 +9,29 @@ body {
|
|
|
9
9
|
--padding-y-small: 8px;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
.el-table__body-wrapper tr td.el-table-fixed-column--left,
|
|
13
|
+
.el-table__body-wrapper tr td.el-table-fixed-column--right,
|
|
14
|
+
.el-table__body-wrapper tr th.el-table-fixed-column--left,
|
|
15
|
+
.el-table__body-wrapper tr th.el-table-fixed-column--right,
|
|
16
|
+
.el-table__footer-wrapper tr td.el-table-fixed-column--left,
|
|
17
|
+
.el-table__footer-wrapper tr td.el-table-fixed-column--right,
|
|
18
|
+
.el-table__footer-wrapper tr th.el-table-fixed-column--left,
|
|
19
|
+
.el-table__footer-wrapper tr th.el-table-fixed-column--right,
|
|
20
|
+
.el-table__header-wrapper tr td.el-table-fixed-column--left,
|
|
21
|
+
.el-table__header-wrapper tr td.el-table-fixed-column--right,
|
|
22
|
+
.el-table__header-wrapper tr th.el-table-fixed-column--left,
|
|
23
|
+
.el-table__header-wrapper tr th.el-table-fixed-column--right {
|
|
24
|
+
background: var(--el-bg-color);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.gi-table .el-table {
|
|
28
|
+
--el-table-header-bg-color: var(--el-fill-color-lighter);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.gi-table .el-table thead.is-group th.el-table__cell {
|
|
32
|
+
background: var(--el-fill-color-lighter);
|
|
33
|
+
}
|
|
34
|
+
|
|
12
35
|
.gi-card-title {
|
|
13
36
|
.gi-card-header__title {
|
|
14
37
|
padding-left: 8px;
|
|
@@ -28,12 +51,6 @@ body {
|
|
|
28
51
|
}
|
|
29
52
|
}
|
|
30
53
|
|
|
31
|
-
.el-dialog__headerbtn {
|
|
32
|
-
display: flex;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
align-items: center;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
54
|
.gi-w-full {
|
|
38
55
|
width: 100%;
|
|
39
56
|
}
|
|
@@ -180,4 +197,27 @@ body {
|
|
|
180
197
|
.el-dialog__footer {
|
|
181
198
|
border-top: none;
|
|
182
199
|
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.el-drawer[role=dialog] {
|
|
203
|
+
--el-drawer-padding-primary: 16px;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.el-drawer {
|
|
207
|
+
.el-drawer__header {
|
|
208
|
+
height: 48px;
|
|
209
|
+
margin-bottom: 0;
|
|
210
|
+
padding-top: 0;
|
|
211
|
+
border-bottom: 1px solid var(--el-border-color);
|
|
212
|
+
display: flex;
|
|
213
|
+
justify-content: space-between;
|
|
214
|
+
align-items: center;
|
|
215
|
+
box-sizing: border-box;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.el-drawer__footer {
|
|
219
|
+
padding-top: 12px;
|
|
220
|
+
padding-bottom: 12px;
|
|
221
|
+
border-top: 1px solid var(--el-border-color);
|
|
222
|
+
}
|
|
183
223
|
}
|