fx-platform-ui 1.0.1 → 1.0.2
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/lib/fx-platform-ui.mjs +22377 -22248
- package/lib/fx-platform-ui.umd.js +67 -67
- package/lib/packages/components/editor/src/hook/useEditorState.d.ts +1 -0
- package/lib/packages/components/editor/src/index.vue.d.ts +1 -0
- package/lib/packages/components/table/src/hook/index.d.ts +1 -0
- package/lib/packages/components/table/src/hook/useTableForm.d.ts +5 -0
- package/lib/packages/components/tag-input/index.d.ts +2 -0
- package/lib/packages/components/tag-input/src/index.vue.d.ts +18 -0
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/component.ts +3 -2
- package/packages/components/editor/src/hook/useEditorState.ts +1 -0
- package/packages/components/table/src/hook/index.ts +1 -0
- package/packages/components/table/src/hook/useTableForm.ts +19 -0
- package/packages/components/table/src/index.vue +54 -38
- package/packages/components/table/src/plat-table-props.ts +15 -0
- package/packages/components/tag-input/index.ts +10 -0
- package/packages/components/tag-input/src/index.vue +162 -0
- package/packages/theme/color.variables.less +13 -0
- package/packages/.DS_Store +0 -0
- package/packages/theme/color.variables.scss +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { computed } from 'vue'
|
|
2
|
+
import type { UseTableStateParams } from './useTableState'
|
|
3
|
+
import type { ComputedRef } from 'vue'
|
|
4
|
+
|
|
5
|
+
export function useTableForm({ props }: UseTableStateParams) {
|
|
6
|
+
const schemas = props.formProps?.schemas || []
|
|
7
|
+
const getFormSlotKeys: ComputedRef<string[]> = computed(() => {
|
|
8
|
+
return schemas
|
|
9
|
+
.map((item) => {
|
|
10
|
+
const value = item['slot'] || null
|
|
11
|
+
return value ? value : null
|
|
12
|
+
})
|
|
13
|
+
.filter((item): item is string => !!item)
|
|
14
|
+
})
|
|
15
|
+
console.log('getFormSlotKeys', getFormSlotKeys)
|
|
16
|
+
return {
|
|
17
|
+
getFormSlotKeys
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -6,68 +6,79 @@
|
|
|
6
6
|
ref="queryFormRef"
|
|
7
7
|
v-bind="formProps"
|
|
8
8
|
@submit="handleSubmit"
|
|
9
|
-
|
|
9
|
+
>
|
|
10
|
+
<template v-for="item in getFormSlotKeys" #[item]="data">
|
|
11
|
+
<slot :name="item" v-bind="data || {}"></slot>
|
|
12
|
+
</template>
|
|
13
|
+
</PlForm>
|
|
14
|
+
<!-- 中间放置插槽以防需要 -->
|
|
15
|
+
<template v-if="$slots.middle">
|
|
16
|
+
<slot name="middle"></slot>
|
|
17
|
+
</template>
|
|
10
18
|
<!-- 工具按钮 + table -->
|
|
11
19
|
<div>
|
|
12
20
|
<ToolBar v-if="showToolBar"> </ToolBar>
|
|
13
21
|
<template v-if="$slots.toolbar">
|
|
14
22
|
<slot name="toolbar"></slot>
|
|
15
23
|
</template>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<template
|
|
24
|
-
v-for="defaultItem in Object.keys($slots)"
|
|
25
|
-
#[defaultItem]="slotData"
|
|
26
|
-
:key="defaultItem"
|
|
27
|
-
>
|
|
28
|
-
<slot :name="defaultItem" v-bind="slotData"></slot>
|
|
29
|
-
</template>
|
|
30
|
-
<!-- bodyCell, headerCell -->
|
|
31
|
-
<template
|
|
32
|
-
v-for="item in ['bodyCell', 'headerCell']"
|
|
33
|
-
#[item]="slotData"
|
|
34
|
-
:key="item"
|
|
24
|
+
<div :style="showCard ? cardStyle : ''">
|
|
25
|
+
<Table
|
|
26
|
+
v-show="tableShow"
|
|
27
|
+
ref="tableRef"
|
|
28
|
+
v-bind="getBindValues"
|
|
29
|
+
:data-source="tableData"
|
|
30
|
+
@change="handleTableChange"
|
|
35
31
|
>
|
|
36
|
-
<slot :name="item" v-bind="slotData"></slot>
|
|
37
32
|
<template
|
|
38
|
-
v-
|
|
39
|
-
|
|
40
|
-
"
|
|
33
|
+
v-for="defaultItem in Object.keys($slots)"
|
|
34
|
+
#[defaultItem]="slotData"
|
|
35
|
+
:key="defaultItem"
|
|
41
36
|
>
|
|
42
|
-
<
|
|
37
|
+
<slot :name="defaultItem" v-bind="slotData"></slot>
|
|
43
38
|
</template>
|
|
44
|
-
<!--
|
|
39
|
+
<!-- bodyCell, headerCell -->
|
|
45
40
|
<template
|
|
46
|
-
v-for="
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
:key="getColumnKey(slotItem)"
|
|
41
|
+
v-for="item in ['bodyCell', 'headerCell']"
|
|
42
|
+
#[item]="slotData"
|
|
43
|
+
:key="item"
|
|
50
44
|
>
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
v-if="
|
|
54
|
-
|
|
45
|
+
<slot :name="item" v-bind="slotData"></slot>
|
|
46
|
+
<template
|
|
47
|
+
v-if="
|
|
48
|
+
item === 'bodyCell' &&
|
|
49
|
+
getColumnKey(slotData.column) === '$action'
|
|
50
|
+
"
|
|
51
|
+
>
|
|
52
|
+
<TableAction :actions="slotData.column.actions(slotData)" />
|
|
53
|
+
</template>
|
|
54
|
+
<!-- 自定义展示构造 -->
|
|
55
|
+
<template
|
|
56
|
+
v-for="slotItem in getBindValues.columns?.filter(
|
|
57
|
+
(value) => value[item]
|
|
58
|
+
)"
|
|
59
|
+
:key="getColumnKey(slotItem)"
|
|
60
|
+
>
|
|
61
|
+
<component
|
|
62
|
+
:is="getComponent(slotItem?.[item]?.(slotData))"
|
|
63
|
+
v-if="getColumnKey(slotData.column) === getColumnKey(slotItem)"
|
|
64
|
+
/>
|
|
65
|
+
</template>
|
|
55
66
|
</template>
|
|
56
|
-
</
|
|
57
|
-
</
|
|
67
|
+
</Table>
|
|
68
|
+
</div>
|
|
58
69
|
</div>
|
|
59
70
|
</div>
|
|
60
71
|
</template>
|
|
61
72
|
|
|
62
73
|
<script lang="ts" setup>
|
|
63
|
-
import { onUpdated, unref } from
|
|
74
|
+
import { onUpdated, unref } from 'vue'
|
|
64
75
|
import { Table } from 'ant-design-vue'
|
|
65
76
|
import PlForm from '../../form'
|
|
66
77
|
import { isFunction } from '../../../utils/is'
|
|
67
78
|
import { ToolBar, TableAction } from './components'
|
|
68
79
|
import { platTableProps } from './plat-table-props'
|
|
69
80
|
import { platTableEmits } from './plat-table-emits'
|
|
70
|
-
import { useTableState, useTableMethods } from './hook'
|
|
81
|
+
import { useTableState, useTableMethods, useTableForm } from './hook'
|
|
71
82
|
defineOptions({
|
|
72
83
|
name: 'PlTable'
|
|
73
84
|
})
|
|
@@ -77,6 +88,11 @@ const emit = defineEmits(platTableEmits)
|
|
|
77
88
|
|
|
78
89
|
// table所有状态(可以理解成将props 和 slot 进行处理 并将结果输出)
|
|
79
90
|
const tableState = useTableState({ props })
|
|
91
|
+
|
|
92
|
+
const { getFormSlotKeys } = useTableForm({
|
|
93
|
+
props
|
|
94
|
+
})
|
|
95
|
+
|
|
80
96
|
const { tableData, queryFormRef, getBindValues } = tableState
|
|
81
97
|
|
|
82
98
|
// 表格内部方法
|
|
@@ -9,6 +9,21 @@ import type {
|
|
|
9
9
|
|
|
10
10
|
export const platTableProps = {
|
|
11
11
|
...tableProps(),
|
|
12
|
+
// 表格是否展示卡片属性
|
|
13
|
+
showCard: {
|
|
14
|
+
type: Boolean as PropType<boolean>,
|
|
15
|
+
default: false
|
|
16
|
+
},
|
|
17
|
+
// 表格外层卡片属性
|
|
18
|
+
cardStyle: {
|
|
19
|
+
type: Object as PropType<Recordable>,
|
|
20
|
+
default: () => ({
|
|
21
|
+
padding: '16px',
|
|
22
|
+
opacity: '1',
|
|
23
|
+
background: '#ffffff',
|
|
24
|
+
borderRadius: '4pt'
|
|
25
|
+
})
|
|
26
|
+
},
|
|
12
27
|
// 是否显示搜索菜单
|
|
13
28
|
searchShow: {
|
|
14
29
|
type: Boolean as PropType<boolean>,
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="fx-tag-input"
|
|
4
|
+
tabindex="0"
|
|
5
|
+
:style="contentStyle"
|
|
6
|
+
v-on="{ click: focusActive }"
|
|
7
|
+
>
|
|
8
|
+
<div v-if="inputVisible" class="fx-tag-input-body">
|
|
9
|
+
<template v-for="tag in value" :key="tag">
|
|
10
|
+
<a-tag v-bind="tagProps" closable @close="() => handleClose(tag)">
|
|
11
|
+
{{ tag }}
|
|
12
|
+
</a-tag>
|
|
13
|
+
</template>
|
|
14
|
+
<div class="fx-tag-input-wrap">
|
|
15
|
+
<div class="fx-tag-input-enter">
|
|
16
|
+
<a-input
|
|
17
|
+
ref="inputRef"
|
|
18
|
+
v-model:value="inputValue"
|
|
19
|
+
type="text"
|
|
20
|
+
size="small"
|
|
21
|
+
:bordered="false"
|
|
22
|
+
@compositionupdate="titleCompositionUpdate"
|
|
23
|
+
@compositionend="titleCompositionEnd"
|
|
24
|
+
@blur="handleInputBlur"
|
|
25
|
+
@keydown.enter="handleInputConfirm"
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="fx-tag-input-hidden"
|
|
29
|
+
>{{ inputValue }}{{ inputUpdateValue }}</div
|
|
30
|
+
>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="no-select">{{ prompt }}</div>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script lang="ts" setup>
|
|
38
|
+
import { nextTick, PropType, ref } from 'vue'
|
|
39
|
+
import { message } from 'ant-design-vue'
|
|
40
|
+
import type { TagProps } from 'ant-design-vue/es/tag'
|
|
41
|
+
defineOptions({
|
|
42
|
+
name: 'PlTagInput'
|
|
43
|
+
})
|
|
44
|
+
const emit = defineEmits(['update:value', 'change'])
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
tagProps: {
|
|
47
|
+
type: Object as PropType<TagProps>,
|
|
48
|
+
default: () => ({})
|
|
49
|
+
},
|
|
50
|
+
contentStyle: {
|
|
51
|
+
type: Object as PropType<Recordable>,
|
|
52
|
+
default: () => {
|
|
53
|
+
return {}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
value: {
|
|
57
|
+
type: Array as PropType<string[] | number[]>,
|
|
58
|
+
default: () => {
|
|
59
|
+
return []
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
prompt: {
|
|
63
|
+
type: String,
|
|
64
|
+
default: '请输入内容,按回车确认'
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
const inputRef = ref()
|
|
68
|
+
// 输入已确认的值
|
|
69
|
+
const inputValue = ref('')
|
|
70
|
+
// 输入的字符还没有被确认
|
|
71
|
+
const inputUpdateValue = ref('')
|
|
72
|
+
// 是否显示输入框
|
|
73
|
+
const inputVisible = ref(false)
|
|
74
|
+
|
|
75
|
+
// compositionupdate 事件触发于字符被输入到一段文字的时候,但是输入的字符还没有被确认,因此不能用于替代 input 事件。
|
|
76
|
+
const titleCompositionUpdate = (e: any) => {
|
|
77
|
+
inputUpdateValue.value = e.target.value
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const titleCompositionEnd = () => {
|
|
81
|
+
inputUpdateValue.value = ''
|
|
82
|
+
}
|
|
83
|
+
// 失焦事件
|
|
84
|
+
const handleInputBlur = () => {
|
|
85
|
+
inputValue.value = ''
|
|
86
|
+
inputVisible.value = props.value.length > 0
|
|
87
|
+
}
|
|
88
|
+
// 删除标签事件
|
|
89
|
+
const handleClose = (removedTag) => {
|
|
90
|
+
const tagsArray: (string | number)[] = props.value
|
|
91
|
+
const tags = tagsArray.filter((tag) => tag !== removedTag)
|
|
92
|
+
focusActive()
|
|
93
|
+
emit('update:value', tags)
|
|
94
|
+
}
|
|
95
|
+
// 确认输入事件
|
|
96
|
+
const handleInputConfirm = () => {
|
|
97
|
+
let tagsArray: (string | number)[] = props.value
|
|
98
|
+
if (inputValue.value && tagsArray.indexOf(inputValue.value) === -1) {
|
|
99
|
+
tagsArray = [...tagsArray, inputValue.value]
|
|
100
|
+
emit('update:value', tagsArray)
|
|
101
|
+
emit('change', tagsArray)
|
|
102
|
+
} else if (inputValue.value && tagsArray.indexOf(inputValue.value) !== -1) {
|
|
103
|
+
message.warning('内容已存在')
|
|
104
|
+
}
|
|
105
|
+
inputValue.value = ''
|
|
106
|
+
inputUpdateValue.value = ''
|
|
107
|
+
}
|
|
108
|
+
// 聚焦事件
|
|
109
|
+
const focusActive = () => {
|
|
110
|
+
inputVisible.value = true
|
|
111
|
+
nextTick(() => {
|
|
112
|
+
inputRef.value.focus()
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<style lang="less" scoped>
|
|
118
|
+
.fx-tag-input {
|
|
119
|
+
border: 1px solid #d9d9d9;
|
|
120
|
+
border-radius: 2px;
|
|
121
|
+
padding: 5px;
|
|
122
|
+
min-height: 100px;
|
|
123
|
+
|
|
124
|
+
.fx-tag-input-wrap {
|
|
125
|
+
display: inline-block;
|
|
126
|
+
width: auto;
|
|
127
|
+
min-width: 60px;
|
|
128
|
+
position: relative;
|
|
129
|
+
height: 22px;
|
|
130
|
+
vertical-align: middle;
|
|
131
|
+
|
|
132
|
+
.fx-tag-input-enter {
|
|
133
|
+
position: absolute;
|
|
134
|
+
top: 0;
|
|
135
|
+
left: 0;
|
|
136
|
+
width: 100%;
|
|
137
|
+
height: 100%;
|
|
138
|
+
z-index: 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.fx-tag-input-hidden {
|
|
142
|
+
height: 0;
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
white-space: nowrap;
|
|
145
|
+
// 对齐input所有会影响宽度的样式
|
|
146
|
+
padding: 0 15px;
|
|
147
|
+
font-size: 14px;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.no-select {
|
|
152
|
+
margin-top: 10px;
|
|
153
|
+
color: #bfbfbf;
|
|
154
|
+
-webkit-touch-callout: none;
|
|
155
|
+
-webkit-user-select: none;
|
|
156
|
+
-khtml-user-select: none;
|
|
157
|
+
-moz-user-select: none;
|
|
158
|
+
-ms-user-select: none;
|
|
159
|
+
user-select: none;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@primary-color: #1890ff; // 全局主色
|
|
2
|
+
@link-color: #1890ff; // 链接色
|
|
3
|
+
@success-color: #52c41a; // 成功色
|
|
4
|
+
@warning-color: #faad14; // 警告色
|
|
5
|
+
@error-color: #f5222d; // 错误色
|
|
6
|
+
@font-size-base: 14px; // 主字号
|
|
7
|
+
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
|
|
8
|
+
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
|
|
9
|
+
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
|
|
10
|
+
@disabled-color: rgba(0, 0, 0, 0.25); // 失效色
|
|
11
|
+
@border-radius-base: 2px; // 组件/浮层圆角
|
|
12
|
+
@border-color-base: #d9d9d9; // 边框色
|
|
13
|
+
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影
|
package/packages/.DS_Store
DELETED
|
Binary file
|
|
File without changes
|