@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.
Files changed (59) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/core.css +1 -0
  3. package/dist/index.cjs +61 -0
  4. package/dist/index.js +50858 -0
  5. package/dist/types/core/index.d.ts +6 -0
  6. package/dist/types/core/src/BaseTable/helpers.d.ts +9 -0
  7. package/dist/types/core/src/BaseTable/index.d.ts +190 -0
  8. package/dist/types/core/src/BaseTable/registry.d.ts +9 -0
  9. package/dist/types/core/src/BaseTable/renderers/AreaCascader.d.ts +5 -0
  10. package/dist/types/core/src/BaseTable/renderers/AutoComplete.d.ts +4 -0
  11. package/dist/types/core/src/BaseTable/renderers/Button.d.ts +4 -0
  12. package/dist/types/core/src/BaseTable/renderers/Cascader.d.ts +5 -0
  13. package/dist/types/core/src/BaseTable/renderers/Checkbox.d.ts +4 -0
  14. package/dist/types/core/src/BaseTable/renderers/CheckboxGroup.d.ts +4 -0
  15. package/dist/types/core/src/BaseTable/renderers/DatePicker.d.ts +4 -0
  16. package/dist/types/core/src/BaseTable/renderers/Input.d.ts +4 -0
  17. package/dist/types/core/src/BaseTable/renderers/InputGroup.d.ts +5 -0
  18. package/dist/types/core/src/BaseTable/renderers/InputNumber.d.ts +4 -0
  19. package/dist/types/core/src/BaseTable/renderers/InputPassword.d.ts +4 -0
  20. package/dist/types/core/src/BaseTable/renderers/RadioGroup.d.ts +4 -0
  21. package/dist/types/core/src/BaseTable/renderers/Select.d.ts +4 -0
  22. package/dist/types/core/src/BaseTable/renderers/SselectPage.d.ts +4 -0
  23. package/dist/types/core/src/BaseTable/renderers/Switch.d.ts +4 -0
  24. package/dist/types/core/src/BaseTable/renderers/TreeSelect.d.ts +4 -0
  25. package/dist/types/core/src/BaseTable/renderers/Upload.d.ts +4 -0
  26. package/dist/types/core/src/BaseTable/renderers/index.d.ts +24 -0
  27. package/dist/types/core/src/BaseTable/state.d.ts +19 -0
  28. package/dist/types/core/src/BaseTable/types.d.ts +391 -0
  29. package/dist/types/core/src/BaseTable/utils.d.ts +8 -0
  30. package/dist/types/core/src/index.d.ts +2 -0
  31. package/index.css +2 -0
  32. package/index.ts +21 -0
  33. package/package.json +39 -3
  34. package/src/BaseTable/helpers.tsx +91 -0
  35. package/src/BaseTable/index.vue +881 -0
  36. package/src/BaseTable/registry.ts +20 -0
  37. package/src/BaseTable/renderers/AreaCascader.tsx +64 -0
  38. package/src/BaseTable/renderers/AutoComplete.tsx +101 -0
  39. package/src/BaseTable/renderers/Button.tsx +62 -0
  40. package/src/BaseTable/renderers/Cascader.tsx +45 -0
  41. package/src/BaseTable/renderers/Checkbox.tsx +65 -0
  42. package/src/BaseTable/renderers/CheckboxGroup.tsx +57 -0
  43. package/src/BaseTable/renderers/DatePicker.tsx +83 -0
  44. package/src/BaseTable/renderers/Input.tsx +140 -0
  45. package/src/BaseTable/renderers/InputGroup.tsx +115 -0
  46. package/src/BaseTable/renderers/InputNumber.tsx +205 -0
  47. package/src/BaseTable/renderers/InputPassword.tsx +81 -0
  48. package/src/BaseTable/renderers/RadioGroup.tsx +63 -0
  49. package/src/BaseTable/renderers/Select.tsx +96 -0
  50. package/src/BaseTable/renderers/SselectPage.tsx +107 -0
  51. package/src/BaseTable/renderers/Switch.tsx +60 -0
  52. package/src/BaseTable/renderers/TreeSelect.tsx +81 -0
  53. package/src/BaseTable/renderers/Upload.tsx +92 -0
  54. package/src/BaseTable/renderers/index.ts +67 -0
  55. package/src/BaseTable/state.ts +37 -0
  56. package/src/BaseTable/types.ts +507 -0
  57. package/src/BaseTable/utils.tsx +144 -0
  58. package/src/index.ts +3 -0
  59. 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
@@ -0,0 +1,3 @@
1
+ import BaseTable from './BaseTable/index.vue'
2
+
3
+ export { BaseTable }
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
+ })