@antsoo-lib/core 0.0.0 → 1.0.0
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/CHANGELOG.md +13 -0
- package/dist/core.css +1 -0
- package/dist/index.cjs +61 -0
- package/dist/index.js +50858 -0
- package/dist/types/core/index.d.ts +6 -0
- package/dist/types/core/src/BaseTable/helpers.d.ts +9 -0
- package/dist/types/core/src/BaseTable/index.d.ts +190 -0
- package/dist/types/core/src/BaseTable/registry.d.ts +9 -0
- package/dist/types/core/src/BaseTable/renderers/AreaCascader.d.ts +5 -0
- package/dist/types/core/src/BaseTable/renderers/AutoComplete.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Button.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Cascader.d.ts +5 -0
- package/dist/types/core/src/BaseTable/renderers/Checkbox.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/CheckboxGroup.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/DatePicker.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Input.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/InputGroup.d.ts +5 -0
- package/dist/types/core/src/BaseTable/renderers/InputNumber.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/InputPassword.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/RadioGroup.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Select.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/SselectPage.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Switch.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/TreeSelect.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/Upload.d.ts +4 -0
- package/dist/types/core/src/BaseTable/renderers/index.d.ts +24 -0
- package/dist/types/core/src/BaseTable/state.d.ts +19 -0
- package/dist/types/core/src/BaseTable/types.d.ts +391 -0
- package/dist/types/core/src/BaseTable/utils.d.ts +8 -0
- package/dist/types/core/src/index.d.ts +2 -0
- package/index.css +2 -0
- package/index.ts +21 -0
- package/package.json +39 -3
- package/src/BaseTable/helpers.tsx +91 -0
- package/src/BaseTable/index.vue +881 -0
- package/src/BaseTable/registry.ts +20 -0
- package/src/BaseTable/renderers/AreaCascader.tsx +64 -0
- package/src/BaseTable/renderers/AutoComplete.tsx +101 -0
- package/src/BaseTable/renderers/Button.tsx +62 -0
- package/src/BaseTable/renderers/Cascader.tsx +45 -0
- package/src/BaseTable/renderers/Checkbox.tsx +65 -0
- package/src/BaseTable/renderers/CheckboxGroup.tsx +57 -0
- package/src/BaseTable/renderers/DatePicker.tsx +83 -0
- package/src/BaseTable/renderers/Input.tsx +140 -0
- package/src/BaseTable/renderers/InputGroup.tsx +115 -0
- package/src/BaseTable/renderers/InputNumber.tsx +205 -0
- package/src/BaseTable/renderers/InputPassword.tsx +81 -0
- package/src/BaseTable/renderers/RadioGroup.tsx +63 -0
- package/src/BaseTable/renderers/Select.tsx +96 -0
- package/src/BaseTable/renderers/SselectPage.tsx +107 -0
- package/src/BaseTable/renderers/Switch.tsx +60 -0
- package/src/BaseTable/renderers/TreeSelect.tsx +81 -0
- package/src/BaseTable/renderers/Upload.tsx +92 -0
- package/src/BaseTable/renderers/index.ts +67 -0
- package/src/BaseTable/state.ts +37 -0
- package/src/BaseTable/types.ts +507 -0
- package/src/BaseTable/utils.tsx +144 -0
- package/src/index.ts +3 -0
- package/vite.config.ts +48 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ButtonProps,
|
|
3
|
+
CascaderProps,
|
|
4
|
+
CheckboxGroupProps,
|
|
5
|
+
CheckboxProps,
|
|
6
|
+
ColProps,
|
|
7
|
+
DatePickerProps,
|
|
8
|
+
InputNumberProps,
|
|
9
|
+
InputProps,
|
|
10
|
+
RadioGroupProps,
|
|
11
|
+
RowProps,
|
|
12
|
+
SelectProps,
|
|
13
|
+
SwitchProps,
|
|
14
|
+
TreeSelectProps,
|
|
15
|
+
UploadProps,
|
|
16
|
+
} from '@antsoo-lib/components'
|
|
17
|
+
import type { AnyObject, VoidFunction } from '@antsoo-lib/shared'
|
|
18
|
+
|
|
19
|
+
import type { VNode } from 'vue'
|
|
20
|
+
|
|
21
|
+
import type { ToolbarState } from './state'
|
|
22
|
+
|
|
23
|
+
// 事件处理函数类型定义
|
|
24
|
+
export type ToolbarEventHandler = VoidFunction
|
|
25
|
+
|
|
26
|
+
// 基础事件接口
|
|
27
|
+
export interface BaseEvents {
|
|
28
|
+
[key: string]: ToolbarEventHandler | undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface BaseToolbarItem {
|
|
32
|
+
key?: string
|
|
33
|
+
label?: string
|
|
34
|
+
permission?: string
|
|
35
|
+
beforeCreate?: boolean | ((toolbarState: ToolbarState) => boolean)
|
|
36
|
+
disabled?: boolean | ((allValues: AnyObject, toolbarState: ToolbarState) => boolean)
|
|
37
|
+
props?: Record<string, any>
|
|
38
|
+
events?: BaseEvents
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 按钮工具栏项目
|
|
42
|
+
export interface ButtonToolbarItem extends BaseToolbarItem {
|
|
43
|
+
type: 'button'
|
|
44
|
+
props?: Partial<ButtonProps> & { loading?: boolean; disabled?: boolean }
|
|
45
|
+
events?: BaseEvents & {
|
|
46
|
+
onClick?: (
|
|
47
|
+
loadingControl: { setLoading: (loading: boolean) => void; getLoading: () => boolean },
|
|
48
|
+
allValues: AnyObject,
|
|
49
|
+
toolbarState: ToolbarState,
|
|
50
|
+
...args: any[]
|
|
51
|
+
) => void
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 插槽配置接口
|
|
56
|
+
export interface SlotConfig {
|
|
57
|
+
// 插槽内容可以是组件配置或渲染函数
|
|
58
|
+
content?:
|
|
59
|
+
| {
|
|
60
|
+
component: any // 组件
|
|
61
|
+
key: string // 主表字段
|
|
62
|
+
props?: AnyObject // 组件属性
|
|
63
|
+
events?: Record<string, VoidFunction> // 组件事件
|
|
64
|
+
options?: Array<{ label: string; value: any }> // 选项数据(用于select等)
|
|
65
|
+
}
|
|
66
|
+
| ((toolbarState: ToolbarState) => VNode)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 输入框工具栏项目
|
|
70
|
+
export interface InputToolbarItem extends BaseToolbarItem {
|
|
71
|
+
type: 'input'
|
|
72
|
+
props?: Partial<InputProps> & { value?: string; autoFocus?: boolean }
|
|
73
|
+
events?: BaseEvents & {
|
|
74
|
+
'onUpdate:value'?: (value: string, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
75
|
+
onChange?: (event: Event, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
76
|
+
onFocus?: VoidFunction
|
|
77
|
+
onFocusCapture?: VoidFunction
|
|
78
|
+
onBlur?: VoidFunction
|
|
79
|
+
onBlurCapture?: VoidFunction
|
|
80
|
+
}
|
|
81
|
+
textarea?: boolean
|
|
82
|
+
// 插槽配置
|
|
83
|
+
slots?: {
|
|
84
|
+
addonBefore?: SlotConfig
|
|
85
|
+
addonAfter?: SlotConfig
|
|
86
|
+
prefix?: SlotConfig
|
|
87
|
+
suffix?: SlotConfig
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 单选框工具栏项目
|
|
92
|
+
export interface RadioGroupToolbarItem extends BaseToolbarItem {
|
|
93
|
+
type: 'radioGroup'
|
|
94
|
+
props?: Partial<RadioGroupProps> & { value?: any }
|
|
95
|
+
events?: BaseEvents & {
|
|
96
|
+
'onUpdate:value'?: (value: string, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
97
|
+
onChange?: (event: Event, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 复选框工具栏项目
|
|
102
|
+
export interface CheckboxToolbarItem extends BaseToolbarItem {
|
|
103
|
+
type: 'checkbox'
|
|
104
|
+
props?: Partial<CheckboxProps> & { checked?: boolean; value?: boolean }
|
|
105
|
+
events?: BaseEvents & {
|
|
106
|
+
'onUpdate:checked'?: (
|
|
107
|
+
checked: boolean,
|
|
108
|
+
allValues: AnyObject,
|
|
109
|
+
toolbarState: ToolbarState,
|
|
110
|
+
) => void
|
|
111
|
+
onChange?: (event: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
112
|
+
'onUpdate:value'?: (checked: boolean, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
113
|
+
}
|
|
114
|
+
label?: string // 复选框后面显示的文案
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 开关工具栏项目
|
|
118
|
+
export interface SwitchToolbarItem extends BaseToolbarItem {
|
|
119
|
+
type: 'switch'
|
|
120
|
+
props?: Partial<SwitchProps> & { checked?: boolean }
|
|
121
|
+
events?: BaseEvents & {
|
|
122
|
+
'onUpdate:checked'?: (
|
|
123
|
+
checked: boolean,
|
|
124
|
+
allValues: AnyObject,
|
|
125
|
+
toolbarState: ToolbarState,
|
|
126
|
+
) => void
|
|
127
|
+
onChange?: (checked: boolean, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 复选框组工具栏项目
|
|
132
|
+
export interface CheckboxGroupToolbarItem extends BaseToolbarItem {
|
|
133
|
+
type: 'checkboxGroup'
|
|
134
|
+
props?: Partial<CheckboxGroupProps> & { value?: any[] }
|
|
135
|
+
events?: BaseEvents & {
|
|
136
|
+
'onUpdate:value'?: (value: any[], allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
137
|
+
onChange?: (checkedValues: any[], allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 日期选择器工具栏项目
|
|
142
|
+
export interface DatePickerToolbarItem extends BaseToolbarItem {
|
|
143
|
+
type: 'datePicker'
|
|
144
|
+
props?: Partial<DatePickerProps> & { value?: any; autoFocus?: boolean }
|
|
145
|
+
events?: BaseEvents & {
|
|
146
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
147
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
148
|
+
onFocus?: VoidFunction
|
|
149
|
+
}
|
|
150
|
+
range?: boolean
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface SelectToolbarItem extends BaseToolbarItem {
|
|
154
|
+
type: 'select'
|
|
155
|
+
props?: Partial<SelectProps> & {
|
|
156
|
+
value?: any
|
|
157
|
+
options?: any[] | ((values: AnyObject) => any[])
|
|
158
|
+
}
|
|
159
|
+
events?: BaseEvents & {
|
|
160
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
161
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 级联选择器工具栏项目
|
|
166
|
+
export interface CascaderToolbarItem extends BaseToolbarItem {
|
|
167
|
+
type: 'cascader'
|
|
168
|
+
props?: Partial<CascaderProps> & { value?: any }
|
|
169
|
+
events?: BaseEvents & {
|
|
170
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
171
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 地区级联选择器属性定义
|
|
176
|
+
export interface AreaCascaderProps {
|
|
177
|
+
value?: any[]
|
|
178
|
+
placeholder?: string
|
|
179
|
+
disabled?: boolean
|
|
180
|
+
allowClear?: boolean
|
|
181
|
+
[key: string]: any
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 地区级联选择器工具栏项目
|
|
185
|
+
export interface AreaCascaderToolbarItem extends BaseToolbarItem {
|
|
186
|
+
type: 'areaCascader'
|
|
187
|
+
props?: AreaCascaderProps
|
|
188
|
+
attr?: Record<string, any>
|
|
189
|
+
events?: BaseEvents & {
|
|
190
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
191
|
+
selectedArea?: (area: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 树选择器工具栏项目
|
|
196
|
+
export interface TreeSelectToolbarItem extends BaseToolbarItem {
|
|
197
|
+
type: 'treeSelect'
|
|
198
|
+
props?: Partial<TreeSelectProps> & {
|
|
199
|
+
value?: any
|
|
200
|
+
options?: any[] | ((values: AnyObject) => any[])
|
|
201
|
+
}
|
|
202
|
+
events?: BaseEvents & {
|
|
203
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
204
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface InputNumberToolbarItem extends BaseToolbarItem {
|
|
209
|
+
type: 'inputNumber'
|
|
210
|
+
props?: Partial<InputNumberProps> & {
|
|
211
|
+
value?: any
|
|
212
|
+
autoFocus?: boolean
|
|
213
|
+
xmoney?: boolean
|
|
214
|
+
xprice?: boolean
|
|
215
|
+
xweight?: boolean
|
|
216
|
+
xtaxrate?: boolean
|
|
217
|
+
xnumber?: boolean
|
|
218
|
+
}
|
|
219
|
+
events?: BaseEvents & {
|
|
220
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
221
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
222
|
+
onStep?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
223
|
+
onFocus?: VoidFunction
|
|
224
|
+
onFocusCapture?: VoidFunction
|
|
225
|
+
onBlur?: VoidFunction
|
|
226
|
+
onBlurCapture?: VoidFunction
|
|
227
|
+
}
|
|
228
|
+
slots?: {
|
|
229
|
+
addonBefore?: SlotConfig
|
|
230
|
+
addonAfter?: SlotConfig
|
|
231
|
+
prefix?: SlotConfig
|
|
232
|
+
suffix?: SlotConfig
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface InputPasswordToolbarItem extends BaseToolbarItem {
|
|
237
|
+
type: 'inputPassword'
|
|
238
|
+
props?: Partial<InputProps> & { value?: string }
|
|
239
|
+
events?: BaseEvents & {
|
|
240
|
+
'onUpdate:value'?: (value: string, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
241
|
+
onChange?: (event: Event, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
242
|
+
}
|
|
243
|
+
textarea?: boolean
|
|
244
|
+
// 插槽配置
|
|
245
|
+
slots?: {
|
|
246
|
+
addonBefore?: SlotConfig
|
|
247
|
+
addonAfter?: SlotConfig
|
|
248
|
+
prefix?: SlotConfig
|
|
249
|
+
suffix?: SlotConfig
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export interface UploadToolbarItem extends BaseToolbarItem {
|
|
254
|
+
type: 'upload'
|
|
255
|
+
props?: Partial<UploadProps> & {
|
|
256
|
+
value?: any[]
|
|
257
|
+
// 基础属性
|
|
258
|
+
placeholder?: string
|
|
259
|
+
allowClear?: boolean
|
|
260
|
+
disabled?: boolean | ((allValues: AnyObject, toolbarState: ToolbarState) => boolean)
|
|
261
|
+
multiple?: boolean
|
|
262
|
+
maxCount?: number
|
|
263
|
+
listType?: 'text' | 'picture' | 'picture-card'
|
|
264
|
+
|
|
265
|
+
// 接口配置
|
|
266
|
+
api?: {
|
|
267
|
+
url: string
|
|
268
|
+
method?: 'GET' | 'POST'
|
|
269
|
+
headers?: Record<string, string>
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 额外参数配置
|
|
273
|
+
extraParams?: AnyObject | ((allValues: AnyObject, toolbarState: ToolbarState) => AnyObject)
|
|
274
|
+
|
|
275
|
+
// 数据映射配置
|
|
276
|
+
dataMapping?: {
|
|
277
|
+
list?: string // 文件列表字段路径
|
|
278
|
+
url?: string // 文件URL字段
|
|
279
|
+
name?: string // 文件名字段
|
|
280
|
+
status?: string // 文件状态字段
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// UI 配置
|
|
284
|
+
buttonText?: string // 上传按钮文本,默认为"点击上传"
|
|
285
|
+
placeholderSrc?: string // picture-card 模式下的占位符图片地址
|
|
286
|
+
placeholderAlt?: string // 占位符图片的 alt 属性
|
|
287
|
+
placeholderClass?: string // 占位符图片的 CSS 类名
|
|
288
|
+
placeholderStyle?: AnyObject // 占位符图片的内联样式
|
|
289
|
+
|
|
290
|
+
// 其他配置
|
|
291
|
+
transformData?: (data: any) => any
|
|
292
|
+
beforeUpload?: (file: File, fileList: File[]) => boolean | Promise<boolean>
|
|
293
|
+
onPreview?: (file: any) => void
|
|
294
|
+
onRemove?: (file: any) => boolean | Promise<boolean>
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 文件类型限制配置
|
|
298
|
+
passage?: 'image' | 'pdf' | 'word' | 'excel' | 'video' | 'audio' | string
|
|
299
|
+
|
|
300
|
+
events?: BaseEvents & {
|
|
301
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
302
|
+
onChange?: (info: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
303
|
+
onSuccess?: (response: any, file: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
304
|
+
onError?: (error: any, file: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// SselectPage 属性定义
|
|
309
|
+
export interface SselectPageProps {
|
|
310
|
+
value?: any
|
|
311
|
+
placeholder?: string
|
|
312
|
+
allowClear?: boolean
|
|
313
|
+
showSearch?: boolean
|
|
314
|
+
disabled?: boolean
|
|
315
|
+
maxTagCount?: number
|
|
316
|
+
size?: 'large' | 'middle' | 'small'
|
|
317
|
+
mode?: 'multiple' | 'tags'
|
|
318
|
+
api: {
|
|
319
|
+
url: string
|
|
320
|
+
method?: 'GET' | 'POST'
|
|
321
|
+
headers?: Record<string, string>
|
|
322
|
+
params?: AnyObject
|
|
323
|
+
data?: AnyObject
|
|
324
|
+
}
|
|
325
|
+
dataMapping?: {
|
|
326
|
+
list?: string
|
|
327
|
+
total?: string
|
|
328
|
+
value?: string
|
|
329
|
+
label?: string
|
|
330
|
+
}
|
|
331
|
+
pagination?: boolean
|
|
332
|
+
paginationConfig?: {
|
|
333
|
+
pageField?: string
|
|
334
|
+
pageSizeField?: string
|
|
335
|
+
searchField?: string
|
|
336
|
+
searchContains?: string
|
|
337
|
+
}
|
|
338
|
+
pageSize?: number
|
|
339
|
+
searchDelay?: number
|
|
340
|
+
extraParams?: AnyObject | ((allValues: AnyObject, toolbarState: ToolbarState) => AnyObject)
|
|
341
|
+
transformData?: (data: any) => any
|
|
342
|
+
autoLoad?: boolean
|
|
343
|
+
autoFocus?: boolean
|
|
344
|
+
[key: string]: any
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export interface SselectPageToolbarItem extends BaseToolbarItem {
|
|
348
|
+
type: 'sselectPage'
|
|
349
|
+
props?: SselectPageProps & {
|
|
350
|
+
disabled?: boolean | ((allValues: AnyObject, toolbarState: ToolbarState) => boolean)
|
|
351
|
+
}
|
|
352
|
+
events?: BaseEvents & {
|
|
353
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
354
|
+
onChange?: (value: any, option: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
355
|
+
onSearch?: (value: string, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
356
|
+
onClear?: (allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface AutoCompleteProps {
|
|
361
|
+
value?: any
|
|
362
|
+
options?: any[]
|
|
363
|
+
placeholder?: string
|
|
364
|
+
disabled?: boolean
|
|
365
|
+
allowClear?: boolean
|
|
366
|
+
[key: string]: any
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface AutoCompleteToolbarItem extends BaseToolbarItem {
|
|
370
|
+
type: 'autoComplete'
|
|
371
|
+
props?: AutoCompleteProps
|
|
372
|
+
events?: BaseEvents & {
|
|
373
|
+
'onUpdate:value'?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
374
|
+
onChange?: (value: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
375
|
+
onSelect?: (value: any, option: any, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
376
|
+
onSearch?: (value: string, allValues: AnyObject, toolbarState: ToolbarState) => void
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ------------------------------
|
|
381
|
+
// Input.Group 渲染器配置定义
|
|
382
|
+
// ------------------------------
|
|
383
|
+
export type InputGroupSize = 'large' | 'middle' | 'small' | 'default'
|
|
384
|
+
export interface InputGroupPropsLike {
|
|
385
|
+
size?: InputGroupSize
|
|
386
|
+
compact?: boolean
|
|
387
|
+
prefixCls?: string
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// 允许在工具栏中直接使用预设描述项(xtype)
|
|
391
|
+
export type PresetXtype = 'add' | 'edit' | 'dels' | 'export' | 'print' | 'files'
|
|
392
|
+
|
|
393
|
+
export interface FilesCategoryOption {
|
|
394
|
+
label: string
|
|
395
|
+
value: string
|
|
396
|
+
[key: string]: any
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export interface FilesPresetConfig {
|
|
400
|
+
title?: string
|
|
401
|
+
// 单据类型:决定附件归属(UploadPopup 内部请求依赖该字段)
|
|
402
|
+
billtypeCode: string | ((row: AnyObject) => string)
|
|
403
|
+
// 分类下拉:UploadPopup 打开后默认选第一个,并按 category 拉历史列表
|
|
404
|
+
categoryOptions: FilesCategoryOption[] | ((row: AnyObject) => FilesCategoryOption[])
|
|
405
|
+
// objId 从行对象取值的字段名,默认 id
|
|
406
|
+
objIdKey?: string
|
|
407
|
+
accept?: string
|
|
408
|
+
passage?: 'image' | 'pdf' | 'word' | 'excel' | 'video' | 'audio' | string
|
|
409
|
+
maxFileSizeMB?: number
|
|
410
|
+
maxCount?: number
|
|
411
|
+
// 上传成功后是否刷新表格(由 SearchTable.openFilesPopup 控制)
|
|
412
|
+
refreshOnSuccess?: boolean
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface PresetBaseToolbarItem extends BaseToolbarItem {
|
|
416
|
+
xtype: PresetXtype
|
|
417
|
+
permission?: string
|
|
418
|
+
label?: string
|
|
419
|
+
events?: any
|
|
420
|
+
props?: any
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export interface PresetDelsToolbarItem extends PresetBaseToolbarItem {
|
|
424
|
+
xtype: 'dels'
|
|
425
|
+
api?: {
|
|
426
|
+
url?: string
|
|
427
|
+
method?: 'get' | 'post'
|
|
428
|
+
useParams?: boolean
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export interface PresetExportToolbarItem extends PresetBaseToolbarItem {
|
|
433
|
+
xtype: 'export'
|
|
434
|
+
filename?: string
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export interface PresetFilesToolbarItem extends PresetBaseToolbarItem {
|
|
438
|
+
xtype: 'files'
|
|
439
|
+
// 附件预设配置:由 SearchTable 内置 UploadPopup 消费
|
|
440
|
+
files: FilesPresetConfig
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export type PresetToolbarItem =
|
|
444
|
+
| PresetDelsToolbarItem
|
|
445
|
+
| PresetExportToolbarItem
|
|
446
|
+
| PresetFilesToolbarItem
|
|
447
|
+
|
|
448
|
+
// Renderable items (those with a 'type' property)
|
|
449
|
+
export type RenderableToolbarItem =
|
|
450
|
+
| ButtonToolbarItem
|
|
451
|
+
| InputToolbarItem
|
|
452
|
+
| RadioGroupToolbarItem
|
|
453
|
+
| CheckboxToolbarItem
|
|
454
|
+
| SwitchToolbarItem
|
|
455
|
+
| CheckboxGroupToolbarItem
|
|
456
|
+
| DatePickerToolbarItem
|
|
457
|
+
| UploadToolbarItem
|
|
458
|
+
| InputNumberToolbarItem
|
|
459
|
+
| SelectToolbarItem
|
|
460
|
+
| TreeSelectToolbarItem
|
|
461
|
+
| InputPasswordToolbarItem
|
|
462
|
+
| SselectPageToolbarItem
|
|
463
|
+
| AutoCompleteToolbarItem
|
|
464
|
+
| InputGroupToolbarItem
|
|
465
|
+
| CascaderToolbarItem
|
|
466
|
+
| AreaCascaderToolbarItem
|
|
467
|
+
|
|
468
|
+
export type ToolbarItem = RenderableToolbarItem | PresetToolbarItem
|
|
469
|
+
|
|
470
|
+
export type InputGroupChild = RenderableToolbarItem & {
|
|
471
|
+
// 当使用 Row 布局时的列宽设置
|
|
472
|
+
span?: number // 24 栅格系统
|
|
473
|
+
flex?: string // 可选:flex 布局
|
|
474
|
+
class?: string
|
|
475
|
+
style?: AnyObject
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export interface InputGroupToolbarItem extends BaseToolbarItem {
|
|
479
|
+
[x: string]: any
|
|
480
|
+
type: 'inputGroup'
|
|
481
|
+
props?: Partial<InputGroupPropsLike>
|
|
482
|
+
// 布局控制:compact(紧凑)/ row(栅格)/ none(默认)
|
|
483
|
+
layout?: {
|
|
484
|
+
type?: 'compact' | 'row' | 'none'
|
|
485
|
+
rowProps?: Partial<RowProps>
|
|
486
|
+
// 针对每个子项的列设置(仅当 type=row 时生效)
|
|
487
|
+
cols?: Array<Partial<ColProps> & { span?: number }>
|
|
488
|
+
}
|
|
489
|
+
children: InputGroupChild[]
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// 工具栏配置类型
|
|
493
|
+
export interface ToolbarConfig {
|
|
494
|
+
items: ToolbarItem[]
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export type {
|
|
498
|
+
ButtonProps,
|
|
499
|
+
DatePickerProps,
|
|
500
|
+
InputNumberProps,
|
|
501
|
+
InputProps,
|
|
502
|
+
RadioGroupProps,
|
|
503
|
+
SelectProps,
|
|
504
|
+
SwitchProps,
|
|
505
|
+
TreeSelectProps,
|
|
506
|
+
UploadProps,
|
|
507
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Button, Dropdown, Menu, MenuItem } from '@antsoo-lib/components'
|
|
2
|
+
import { DownOutlined, UpOutlined } from '@antsoo-lib/icons'
|
|
3
|
+
import { isEmpty, isFunction } from '@antsoo-lib/utils'
|
|
4
|
+
|
|
5
|
+
import { markRaw, ref } from 'vue'
|
|
6
|
+
import type { VNode } from 'vue'
|
|
7
|
+
|
|
8
|
+
import { registerBaseTableComponents } from './registry'
|
|
9
|
+
import { rendererMap } from './renderers'
|
|
10
|
+
import { useToolbarState } from './state'
|
|
11
|
+
import type { ToolbarState } from './state'
|
|
12
|
+
import type { ToolbarConfig, ToolbarItem } from './types'
|
|
13
|
+
|
|
14
|
+
// 工具栏渲染函数
|
|
15
|
+
export function renderToolbar(
|
|
16
|
+
config: ToolbarConfig,
|
|
17
|
+
toolbarState: ToolbarState,
|
|
18
|
+
count: number | (() => number),
|
|
19
|
+
permissions: string[] = [],
|
|
20
|
+
): VNode[] {
|
|
21
|
+
if (!config || !config.items || !Array.isArray(config.items)) {
|
|
22
|
+
return []
|
|
23
|
+
}
|
|
24
|
+
const allShowBtn = config.items.filter((item) => {
|
|
25
|
+
// 预设xtype项由上层组件转换,这里直接过滤掉
|
|
26
|
+
if ((item as any).xtype) {
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
// Decoupled: Check permission against the passed array
|
|
30
|
+
if (item.permission && !permissions.includes(item.permission)) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
// 检查 beforeCreate 属性
|
|
34
|
+
if (item.beforeCreate === undefined) {
|
|
35
|
+
return true // 默认显示
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (typeof item.beforeCreate === 'boolean') {
|
|
39
|
+
return item.beforeCreate
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (typeof item.beforeCreate === 'function') {
|
|
43
|
+
try {
|
|
44
|
+
return item.beforeCreate(toolbarState)
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.warn(`beforeCreate function error for item ${item.key}:`, error)
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return true
|
|
52
|
+
})
|
|
53
|
+
const extendCount = isFunction(count) ? count() : count
|
|
54
|
+
|
|
55
|
+
// 优化按钮展示逻辑
|
|
56
|
+
let extendShow: any[]
|
|
57
|
+
let foldShow: any[]
|
|
58
|
+
|
|
59
|
+
if (extendCount <= 0 || allShowBtn.length === 0) {
|
|
60
|
+
// 边界条件:extendCount 无效或没有按钮
|
|
61
|
+
extendShow = []
|
|
62
|
+
foldShow = []
|
|
63
|
+
} else if (allShowBtn.length <= extendCount) {
|
|
64
|
+
// 按钮数量不超过限制,全部展示
|
|
65
|
+
extendShow = allShowBtn
|
|
66
|
+
foldShow = []
|
|
67
|
+
} else {
|
|
68
|
+
// 按钮数量超过限制,需要收起部分按钮
|
|
69
|
+
if (extendCount === 1) {
|
|
70
|
+
// 特殊情况:只能展示1个按钮,直接显示"更多"按钮
|
|
71
|
+
extendShow = []
|
|
72
|
+
foldShow = allShowBtn
|
|
73
|
+
} else {
|
|
74
|
+
// 实际展示的普通按钮数量为 extendCount - 1,为"更多"按钮预留位置
|
|
75
|
+
extendShow = allShowBtn.slice(0, extendCount - 1)
|
|
76
|
+
foldShow = allShowBtn.slice(extendCount - 1)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 渲染显示的按钮
|
|
81
|
+
const renderedExtendShow = extendShow.map((item: ToolbarItem) => {
|
|
82
|
+
// 对于 PresetToolbarItem,它没有 type 属性来匹配 rendererMap,但应该已被 filter 掉。
|
|
83
|
+
if ('xtype' in item) return null
|
|
84
|
+
|
|
85
|
+
const renderer = rendererMap[item.type]
|
|
86
|
+
if (!renderer) {
|
|
87
|
+
console.warn(`Unknown toolbar item type: ${item.type}`)
|
|
88
|
+
return <div key={item.key}>Unknown type: {item.type}</div>
|
|
89
|
+
}
|
|
90
|
+
return renderer(item, toolbarState, toolbarState.getAllValues())
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// 如果有折叠的按钮,添加下拉菜单
|
|
94
|
+
if (!isEmpty(foldShow)) {
|
|
95
|
+
const menuItems = foldShow.map((item: ToolbarItem) => {
|
|
96
|
+
// 同样的类型守卫
|
|
97
|
+
if ('xtype' in item) return null
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<MenuItem
|
|
101
|
+
key={item.key || `fold-${Math.random()}`}
|
|
102
|
+
onClick={() => {
|
|
103
|
+
// 处理按钮点击事件
|
|
104
|
+
if (item.events?.onClick) {
|
|
105
|
+
const loadingControl = {
|
|
106
|
+
setLoading: (_loading: boolean) => {
|
|
107
|
+
// 这里可以根据需要实现加载状态控制
|
|
108
|
+
},
|
|
109
|
+
getLoading: () => false,
|
|
110
|
+
}
|
|
111
|
+
item.events.onClick(loadingControl, toolbarState.getAllValues(), toolbarState)
|
|
112
|
+
}
|
|
113
|
+
}}
|
|
114
|
+
>
|
|
115
|
+
{item.label || item.key || '未命名'}
|
|
116
|
+
</MenuItem>
|
|
117
|
+
)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const dropdownMenu = <Menu>{menuItems}</Menu>
|
|
121
|
+
const dropdownVisible = ref(false)
|
|
122
|
+
const MoreButton = markRaw(Dropdown)
|
|
123
|
+
const moreButton = (
|
|
124
|
+
<MoreButton
|
|
125
|
+
overlay={dropdownMenu}
|
|
126
|
+
trigger={['hover']}
|
|
127
|
+
onOpenChange={(visible: boolean) => {
|
|
128
|
+
dropdownVisible.value = visible
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
131
|
+
<Button type="default">
|
|
132
|
+
更多
|
|
133
|
+
{dropdownVisible.value ? <UpOutlined /> : <DownOutlined />}
|
|
134
|
+
</Button>
|
|
135
|
+
</MoreButton>
|
|
136
|
+
)
|
|
137
|
+
renderedExtendShow.push(moreButton)
|
|
138
|
+
}
|
|
139
|
+
return renderedExtendShow.filter(Boolean) as VNode[]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { registerBaseTableComponents, ToolbarState, useToolbarState }
|
|
143
|
+
export * from './types'
|
|
144
|
+
export * from './renderers'
|
package/src/index.ts
ADDED
package/vite.config.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import vue from '@vitejs/plugin-vue'
|
|
2
|
+
import vueJsx from '@vitejs/plugin-vue-jsx'
|
|
3
|
+
import { resolve } from 'node:path'
|
|
4
|
+
import { defineConfig } from 'vite'
|
|
5
|
+
import dts from 'vite-plugin-dts'
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
resolve: {
|
|
9
|
+
extensions: ['.ts', '.tsx', '.vue'],
|
|
10
|
+
},
|
|
11
|
+
plugins: [
|
|
12
|
+
vue(),
|
|
13
|
+
vueJsx(),
|
|
14
|
+
dts({
|
|
15
|
+
include: ['index.ts', 'src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
|
|
16
|
+
outDir: 'dist/types',
|
|
17
|
+
cleanVueFileName: true,
|
|
18
|
+
}),
|
|
19
|
+
],
|
|
20
|
+
build: {
|
|
21
|
+
cssCodeSplit: false,
|
|
22
|
+
lib: {
|
|
23
|
+
entry: resolve(__dirname, 'index.ts'),
|
|
24
|
+
name: 'AntsooTableCore',
|
|
25
|
+
fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`,
|
|
26
|
+
formats: ['es', 'cjs'],
|
|
27
|
+
},
|
|
28
|
+
rollupOptions: {
|
|
29
|
+
external: [
|
|
30
|
+
'vue',
|
|
31
|
+
'@antsoo-lib/utils',
|
|
32
|
+
'@antsoo-lib/shared',
|
|
33
|
+
'@antsoo-lib/components',
|
|
34
|
+
'lodash-es',
|
|
35
|
+
/^@ant-design\/icons-svg/,
|
|
36
|
+
],
|
|
37
|
+
output: {
|
|
38
|
+
globals: {
|
|
39
|
+
vue: 'Vue',
|
|
40
|
+
'@antsoo-lib/utils': 'AntsooUtils',
|
|
41
|
+
'@antsoo-lib/shared': 'AntsooShared',
|
|
42
|
+
'@antsoo-lib/components': 'AntsooComponents',
|
|
43
|
+
'lodash-es': 'lodash-es',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
})
|