@antsoo-lib/core 2.0.5 → 3.0.1

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 (43) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/core.css +1 -1
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.js +6 -5
  5. package/dist/types/BaseSearch/index.d.ts +1 -1
  6. package/dist/types/BaseTable/index.d.ts +4 -480
  7. package/dist/types/Form/CoreForm.d.ts +82 -0
  8. package/dist/types/SSelectPage/index.d.ts +102 -0
  9. package/package.json +5 -5
  10. package/src/BaseSearch/index.vue +371 -371
  11. package/src/BaseTable/index.vue +910 -910
  12. package/src/Form/CoreForm.vue +782 -782
  13. package/src/Form/types.ts +86 -86
  14. package/src/SSelectPage/index.vue +607 -607
  15. package/src/index.ts +17 -17
  16. package/src/render/AreaCascader.tsx +64 -64
  17. package/src/render/AutoComplete.tsx +101 -101
  18. package/src/render/Button.tsx +62 -62
  19. package/src/render/Cascader.tsx +45 -45
  20. package/src/render/Checkbox.tsx +65 -65
  21. package/src/render/CheckboxGroup.tsx +57 -57
  22. package/src/render/Custom.tsx +19 -19
  23. package/src/render/DatePicker.tsx +83 -83
  24. package/src/render/Input.tsx +140 -140
  25. package/src/render/InputGroup.tsx +115 -115
  26. package/src/render/InputNumber.tsx +205 -205
  27. package/src/render/InputPassword.tsx +81 -81
  28. package/src/render/InputRange.tsx +154 -154
  29. package/src/render/RadioGroup.tsx +63 -63
  30. package/src/render/Select.tsx +96 -96
  31. package/src/render/SselectPage.tsx +107 -107
  32. package/src/render/Switch.tsx +60 -60
  33. package/src/render/Tree.tsx +136 -136
  34. package/src/render/TreeSelect.tsx +81 -81
  35. package/src/render/Upload.tsx +91 -91
  36. package/src/render/helper.tsx +221 -221
  37. package/src/render/index.ts +108 -108
  38. package/src/render/registry.ts +20 -20
  39. package/src/render/state.ts +37 -37
  40. package/src/render/types.ts +567 -567
  41. package/src/utils/attrMapping.ts +106 -106
  42. package/vite.config.ts +61 -61
  43. package/.turbo/turbo-build.log +0 -40
@@ -1,221 +1,221 @@
1
- import { Button, Dropdown, Menu, MenuItem, Select } from '@antsoo-lib/components'
2
- import { DownOutlined, UpOutlined } from '@antsoo-lib/icons'
3
- import { isEmpty, isFunction } from '@antsoo-lib/utils'
4
-
5
- import { markRaw, nextTick, ref } from 'vue'
6
- import type { VNode } from 'vue'
7
-
8
- import { rendererMap } from '.'
9
- import type { ToolbarState } from './state'
10
- import type { InputGroupToolbarItem, SlotConfig, ToolbarConfig, ToolbarItem } from './types'
11
-
12
- // 工具栏渲染函数
13
- export function renderToolbar(
14
- config: ToolbarConfig,
15
- toolbarState: ToolbarState,
16
- count: number | (() => number),
17
- permissions: string[] = [],
18
- ): VNode[] {
19
- if (!config || !config.items || !Array.isArray(config.items)) {
20
- return []
21
- }
22
- const allShowBtn = config.items.filter((item) => {
23
- // 预设xtype项由上层组件转换,这里直接过滤掉
24
- if ((item as any).xtype) {
25
- return false
26
- }
27
- // Decoupled: Check permission against the passed array
28
- if (item.permission && !permissions.includes(item.permission)) {
29
- return false
30
- }
31
- // 检查 beforeCreate 属性
32
- if (item.beforeCreate === undefined) {
33
- return true // 默认显示
34
- }
35
-
36
- if (typeof item.beforeCreate === 'boolean') {
37
- return item.beforeCreate
38
- }
39
-
40
- if (typeof item.beforeCreate === 'function') {
41
- try {
42
- return item.beforeCreate(toolbarState)
43
- } catch (error) {
44
- console.warn(`beforeCreate function error for item ${item.key}:`, error)
45
- return false
46
- }
47
- }
48
-
49
- return true
50
- })
51
- const extendCount = isFunction(count) ? count() : count
52
-
53
- // 优化按钮展示逻辑
54
- let extendShow: any[]
55
- let foldShow: any[]
56
-
57
- if (extendCount <= 0 || allShowBtn.length === 0) {
58
- // 边界条件:extendCount 无效或没有按钮
59
- extendShow = []
60
- foldShow = []
61
- } else if (allShowBtn.length <= extendCount) {
62
- // 按钮数量不超过限制,全部展示
63
- extendShow = allShowBtn
64
- foldShow = []
65
- } else {
66
- // 按钮数量超过限制,需要收起部分按钮
67
- if (extendCount === 1) {
68
- // 特殊情况:只能展示1个按钮,直接显示"更多"按钮
69
- extendShow = []
70
- foldShow = allShowBtn
71
- } else {
72
- // 实际展示的普通按钮数量为 extendCount - 1,为"更多"按钮预留位置
73
- extendShow = allShowBtn.slice(0, extendCount - 1)
74
- foldShow = allShowBtn.slice(extendCount - 1)
75
- }
76
- }
77
-
78
- // 渲染显示的按钮
79
- const renderedExtendShow = extendShow.map((item: ToolbarItem) => {
80
- // 对于 PresetToolbarItem,它没有 type 属性来匹配 rendererMap,但应该已被 filter 掉。
81
- if ('xtype' in item) return null
82
-
83
- const renderer = rendererMap[item.type]
84
- if (!renderer) {
85
- console.warn(`Unknown toolbar item type: ${item.type}`)
86
- return <div key={item.key}>Unknown type: {item.type}</div>
87
- }
88
- return renderer(item, toolbarState, toolbarState.getAllValues())
89
- })
90
-
91
- // 如果有折叠的按钮,添加下拉菜单
92
- if (!isEmpty(foldShow)) {
93
- const menuItems = foldShow.map((item: ToolbarItem) => {
94
- // 同样的类型守卫
95
- if ('xtype' in item) return null
96
-
97
- return (
98
- <MenuItem
99
- key={item.key || `fold-${Math.random()}`}
100
- onClick={() => {
101
- // 处理按钮点击事件
102
- if (item.events?.onClick) {
103
- const loadingControl = {
104
- setLoading: (_loading: boolean) => {
105
- // 这里可以根据需要实现加载状态控制
106
- },
107
- getLoading: () => false,
108
- }
109
- item.events.onClick(loadingControl, toolbarState.getAllValues(), toolbarState)
110
- }
111
- }}
112
- >
113
- {item.label || item.key || '未命名'}
114
- </MenuItem>
115
- )
116
- })
117
-
118
- const dropdownMenu = <Menu>{menuItems}</Menu>
119
- const dropdownVisible = ref(false)
120
- const MoreButton = markRaw(Dropdown)
121
- const moreButton = (
122
- <MoreButton
123
- overlay={dropdownMenu}
124
- trigger={['hover']}
125
- onOpenChange={(visible: boolean) => {
126
- dropdownVisible.value = visible
127
- }}
128
- >
129
- <Button type="default">
130
- 更多
131
- {dropdownVisible.value ? <UpOutlined /> : <DownOutlined />}
132
- </Button>
133
- </MoreButton>
134
- )
135
- renderedExtendShow.push(moreButton)
136
- }
137
- return renderedExtendShow.filter(Boolean) as VNode[]
138
- }
139
-
140
- // 渲染插槽内容的辅助函数
141
- export function renderSlotContent(
142
- slotConfig: SlotConfig,
143
- toolbarState: ToolbarState,
144
- ): VNode | undefined {
145
- if (!slotConfig?.content) return undefined
146
-
147
- // 如果是函数,直接调用
148
- if (typeof slotConfig.content === 'function') {
149
- return slotConfig.content(toolbarState)
150
- }
151
-
152
- // 如果是组件配置对象
153
- const { component, key, props = {}, events = {}, options = [] } = slotConfig.content
154
- const allValues = toolbarState.getAllValues()
155
-
156
- // 处理事件,注入工具栏状态
157
- const processedEvents: Record<string, VoidFunction> = {}
158
- Object.entries(events).forEach(([eventName, handler]) => {
159
- if (eventName === 'onChange') {
160
- // 对于 onChange 事件,使用 nextTick 确保在下一个 tick 中执行外部处理函数
161
- processedEvents[eventName] = (...args: any[]) => {
162
- nextTick(() => {
163
- handler(...args, allValues, toolbarState)
164
- })
165
- }
166
- } else {
167
- // 其他事件保持原有逻辑
168
- processedEvents[eventName] = (...args: any[]) => {
169
- handler(...args, allValues, toolbarState)
170
- }
171
- }
172
- })
173
-
174
- const value = allValues[key]
175
-
176
- // 如果是Select组件且有options,添加选项子节点
177
- if (component === Select && options.length > 0) {
178
- const Comp = markRaw(component)
179
- return (
180
- <Comp value={value ?? ''} {...props} {...processedEvents}>
181
- {options.map((option: any) => (
182
- <Select.Option key={option.value} value={option.value}>
183
- {option.label}
184
- </Select.Option>
185
- ))}
186
- </Comp>
187
- )
188
- }
189
-
190
- // 普通组件渲染
191
- const Comp = markRaw(component)
192
- return <Comp value={value ?? ''} {...props} {...processedEvents} />
193
- }
194
-
195
- export function validateInputGroupConfig(cfg: InputGroupToolbarItem): {
196
- valid: boolean
197
- errors?: string[]
198
- } {
199
- const errors: string[] = []
200
- if (!cfg) errors.push('inputGroup config is required')
201
- if (cfg.type !== 'inputGroup') errors.push("type must be 'inputGroup'")
202
- if (!Array.isArray(cfg.children) || cfg.children.length === 0)
203
- errors.push('children must be a non-empty array')
204
- // 校验子项 key 唯一性
205
- const keys = (cfg.children || []).map((c) => c.key).filter(Boolean) as string[]
206
- const dup = keys.filter((k, i) => keys.indexOf(k) !== i)
207
- if (dup.length) errors.push(`duplicate child keys: ${Array.from(new Set(dup)).join(',')}`)
208
- return { valid: errors.length === 0, errors: errors.length ? errors : undefined }
209
- }
210
-
211
- // InputNumber 的焦点态只用于“显示逻辑(失焦补零)”,不属于业务值:
212
- // - 不写入 ToolbarState,避免污染 getAllValues() 及其下游(按钮事件、联动禁用、外部 expose、deep watch 等)
213
- // - 采用 WeakMap:当 ToolbarState 实例被销毁且无引用时,对应缓存可被 GC 自动回收
214
- const inputNumberFocusState = new WeakMap<ToolbarState, Map<string, boolean>>()
215
- export function getInputNumberFocusState(toolbarState: ToolbarState) {
216
- const existing = inputNumberFocusState.get(toolbarState)
217
- if (existing) return existing
218
- const next = new Map<string, boolean>()
219
- inputNumberFocusState.set(toolbarState, next)
220
- return next
221
- }
1
+ import { Button, Dropdown, Menu, MenuItem, Select } from '@antsoo-lib/components'
2
+ import { DownOutlined, UpOutlined } from '@antsoo-lib/icons'
3
+ import { isEmpty, isFunction } from '@antsoo-lib/utils'
4
+
5
+ import { markRaw, nextTick, ref } from 'vue'
6
+ import type { VNode } from 'vue'
7
+
8
+ import { rendererMap } from '.'
9
+ import type { ToolbarState } from './state'
10
+ import type { InputGroupToolbarItem, SlotConfig, ToolbarConfig, ToolbarItem } from './types'
11
+
12
+ // 工具栏渲染函数
13
+ export function renderToolbar(
14
+ config: ToolbarConfig,
15
+ toolbarState: ToolbarState,
16
+ count: number | (() => number),
17
+ permissions: string[] = [],
18
+ ): VNode[] {
19
+ if (!config || !config.items || !Array.isArray(config.items)) {
20
+ return []
21
+ }
22
+ const allShowBtn = config.items.filter((item) => {
23
+ // 预设xtype项由上层组件转换,这里直接过滤掉
24
+ if ((item as any).xtype) {
25
+ return false
26
+ }
27
+ // Decoupled: Check permission against the passed array
28
+ if (item.permission && !permissions.includes(item.permission)) {
29
+ return false
30
+ }
31
+ // 检查 beforeCreate 属性
32
+ if (item.beforeCreate === undefined) {
33
+ return true // 默认显示
34
+ }
35
+
36
+ if (typeof item.beforeCreate === 'boolean') {
37
+ return item.beforeCreate
38
+ }
39
+
40
+ if (typeof item.beforeCreate === 'function') {
41
+ try {
42
+ return item.beforeCreate(toolbarState)
43
+ } catch (error) {
44
+ console.warn(`beforeCreate function error for item ${item.key}:`, error)
45
+ return false
46
+ }
47
+ }
48
+
49
+ return true
50
+ })
51
+ const extendCount = isFunction(count) ? count() : count
52
+
53
+ // 优化按钮展示逻辑
54
+ let extendShow: any[]
55
+ let foldShow: any[]
56
+
57
+ if (extendCount <= 0 || allShowBtn.length === 0) {
58
+ // 边界条件:extendCount 无效或没有按钮
59
+ extendShow = []
60
+ foldShow = []
61
+ } else if (allShowBtn.length <= extendCount) {
62
+ // 按钮数量不超过限制,全部展示
63
+ extendShow = allShowBtn
64
+ foldShow = []
65
+ } else {
66
+ // 按钮数量超过限制,需要收起部分按钮
67
+ if (extendCount === 1) {
68
+ // 特殊情况:只能展示1个按钮,直接显示"更多"按钮
69
+ extendShow = []
70
+ foldShow = allShowBtn
71
+ } else {
72
+ // 实际展示的普通按钮数量为 extendCount - 1,为"更多"按钮预留位置
73
+ extendShow = allShowBtn.slice(0, extendCount - 1)
74
+ foldShow = allShowBtn.slice(extendCount - 1)
75
+ }
76
+ }
77
+
78
+ // 渲染显示的按钮
79
+ const renderedExtendShow = extendShow.map((item: ToolbarItem) => {
80
+ // 对于 PresetToolbarItem,它没有 type 属性来匹配 rendererMap,但应该已被 filter 掉。
81
+ if ('xtype' in item) return null
82
+
83
+ const renderer = rendererMap[item.type]
84
+ if (!renderer) {
85
+ console.warn(`Unknown toolbar item type: ${item.type}`)
86
+ return <div key={item.key}>Unknown type: {item.type}</div>
87
+ }
88
+ return renderer(item, toolbarState, toolbarState.getAllValues())
89
+ })
90
+
91
+ // 如果有折叠的按钮,添加下拉菜单
92
+ if (!isEmpty(foldShow)) {
93
+ const menuItems = foldShow.map((item: ToolbarItem) => {
94
+ // 同样的类型守卫
95
+ if ('xtype' in item) return null
96
+
97
+ return (
98
+ <MenuItem
99
+ key={item.key || `fold-${Math.random()}`}
100
+ onClick={() => {
101
+ // 处理按钮点击事件
102
+ if (item.events?.onClick) {
103
+ const loadingControl = {
104
+ setLoading: (_loading: boolean) => {
105
+ // 这里可以根据需要实现加载状态控制
106
+ },
107
+ getLoading: () => false,
108
+ }
109
+ item.events.onClick(loadingControl, toolbarState.getAllValues(), toolbarState)
110
+ }
111
+ }}
112
+ >
113
+ {item.label || item.key || '未命名'}
114
+ </MenuItem>
115
+ )
116
+ })
117
+
118
+ const dropdownMenu = <Menu>{menuItems}</Menu>
119
+ const dropdownVisible = ref(false)
120
+ const MoreButton = markRaw(Dropdown)
121
+ const moreButton = (
122
+ <MoreButton
123
+ overlay={dropdownMenu}
124
+ trigger={['hover']}
125
+ onOpenChange={(visible: boolean) => {
126
+ dropdownVisible.value = visible
127
+ }}
128
+ >
129
+ <Button type="default">
130
+ 更多
131
+ {dropdownVisible.value ? <UpOutlined /> : <DownOutlined />}
132
+ </Button>
133
+ </MoreButton>
134
+ )
135
+ renderedExtendShow.push(moreButton)
136
+ }
137
+ return renderedExtendShow.filter(Boolean) as VNode[]
138
+ }
139
+
140
+ // 渲染插槽内容的辅助函数
141
+ export function renderSlotContent(
142
+ slotConfig: SlotConfig,
143
+ toolbarState: ToolbarState,
144
+ ): VNode | undefined {
145
+ if (!slotConfig?.content) return undefined
146
+
147
+ // 如果是函数,直接调用
148
+ if (typeof slotConfig.content === 'function') {
149
+ return slotConfig.content(toolbarState)
150
+ }
151
+
152
+ // 如果是组件配置对象
153
+ const { component, key, props = {}, events = {}, options = [] } = slotConfig.content
154
+ const allValues = toolbarState.getAllValues()
155
+
156
+ // 处理事件,注入工具栏状态
157
+ const processedEvents: Record<string, VoidFunction> = {}
158
+ Object.entries(events).forEach(([eventName, handler]) => {
159
+ if (eventName === 'onChange') {
160
+ // 对于 onChange 事件,使用 nextTick 确保在下一个 tick 中执行外部处理函数
161
+ processedEvents[eventName] = (...args: any[]) => {
162
+ nextTick(() => {
163
+ handler(...args, allValues, toolbarState)
164
+ })
165
+ }
166
+ } else {
167
+ // 其他事件保持原有逻辑
168
+ processedEvents[eventName] = (...args: any[]) => {
169
+ handler(...args, allValues, toolbarState)
170
+ }
171
+ }
172
+ })
173
+
174
+ const value = allValues[key]
175
+
176
+ // 如果是Select组件且有options,添加选项子节点
177
+ if (component === Select && options.length > 0) {
178
+ const Comp = markRaw(component)
179
+ return (
180
+ <Comp value={value ?? ''} {...props} {...processedEvents}>
181
+ {options.map((option: any) => (
182
+ <Select.Option key={option.value} value={option.value}>
183
+ {option.label}
184
+ </Select.Option>
185
+ ))}
186
+ </Comp>
187
+ )
188
+ }
189
+
190
+ // 普通组件渲染
191
+ const Comp = markRaw(component)
192
+ return <Comp value={value ?? ''} {...props} {...processedEvents} />
193
+ }
194
+
195
+ export function validateInputGroupConfig(cfg: InputGroupToolbarItem): {
196
+ valid: boolean
197
+ errors?: string[]
198
+ } {
199
+ const errors: string[] = []
200
+ if (!cfg) errors.push('inputGroup config is required')
201
+ if (cfg.type !== 'inputGroup') errors.push("type must be 'inputGroup'")
202
+ if (!Array.isArray(cfg.children) || cfg.children.length === 0)
203
+ errors.push('children must be a non-empty array')
204
+ // 校验子项 key 唯一性
205
+ const keys = (cfg.children || []).map((c) => c.key).filter(Boolean) as string[]
206
+ const dup = keys.filter((k, i) => keys.indexOf(k) !== i)
207
+ if (dup.length) errors.push(`duplicate child keys: ${Array.from(new Set(dup)).join(',')}`)
208
+ return { valid: errors.length === 0, errors: errors.length ? errors : undefined }
209
+ }
210
+
211
+ // InputNumber 的焦点态只用于“显示逻辑(失焦补零)”,不属于业务值:
212
+ // - 不写入 ToolbarState,避免污染 getAllValues() 及其下游(按钮事件、联动禁用、外部 expose、deep watch 等)
213
+ // - 采用 WeakMap:当 ToolbarState 实例被销毁且无引用时,对应缓存可被 GC 自动回收
214
+ const inputNumberFocusState = new WeakMap<ToolbarState, Map<string, boolean>>()
215
+ export function getInputNumberFocusState(toolbarState: ToolbarState) {
216
+ const existing = inputNumberFocusState.get(toolbarState)
217
+ if (existing) return existing
218
+ const next = new Map<string, boolean>()
219
+ inputNumberFocusState.set(toolbarState, next)
220
+ return next
221
+ }
@@ -1,108 +1,108 @@
1
- import type { AnyObject } from '@antsoo-lib/shared'
2
-
3
- import type { VNode } from 'vue'
4
-
5
- import { renderAreaCascader } from './AreaCascader'
6
- import { renderAutoComplete } from './AutoComplete'
7
- import { renderButton } from './Button'
8
- import { renderCascader } from './Cascader'
9
- import { renderCheckbox } from './Checkbox'
10
- import { renderCheckboxGroup } from './CheckboxGroup'
11
- import { renderCustom } from './Custom'
12
- import { renderDatePicker } from './DatePicker'
13
- import { renderInput } from './Input'
14
- import { renderInputGroup } from './InputGroup'
15
- import { renderInputNumber } from './InputNumber'
16
- import { renderInputPassword } from './InputPassword'
17
- import { renderInputRange } from './InputRange'
18
- import { renderRadioGroup } from './RadioGroup'
19
- import { renderSelect } from './Select'
20
- import { renderSselectPage } from './SselectPage'
21
- import { renderSwitch } from './Switch'
22
- import { renderTree } from './Tree'
23
- import { renderTreeSelect } from './TreeSelect'
24
- import { renderUpload } from './Upload'
25
- import type { ToolbarState } from './state'
26
- import type { ToolbarItem } from './types'
27
-
28
- // 渲染器映射类型定义
29
- export type Renderer = (
30
- item: ToolbarItem,
31
- toolbarState: ToolbarState,
32
- formValues?: AnyObject,
33
- ) => VNode
34
-
35
- // 渲染器映射
36
- const defaultRendererMap: Record<string, Renderer> = {
37
- button: renderButton,
38
- input: renderInput,
39
- inputRange: renderInputRange as Renderer,
40
- inputGroup: renderInputGroup as Renderer,
41
- radioGroup: renderRadioGroup,
42
- checkbox: renderCheckbox,
43
- switch: renderSwitch,
44
- checkboxGroup: renderCheckboxGroup,
45
- datePicker: renderDatePicker,
46
- select: renderSelect,
47
- inputNumber: renderInputNumber,
48
- inputPassword: renderInputPassword,
49
- upload: renderUpload,
50
- tree: renderTree as Renderer,
51
- treeSelect: renderTreeSelect,
52
- sselectPage: renderSselectPage,
53
- autoComplete: renderAutoComplete as Renderer,
54
- cascader: renderCascader as Renderer,
55
- areaCascader: renderAreaCascader as Renderer,
56
- custom: renderCustom as Renderer,
57
- }
58
-
59
- // 导出的渲染器映射,支持动态修改
60
- export const rendererMap: Record<string, Renderer> = { ...defaultRendererMap }
61
-
62
- /**
63
- * 注册自定义渲染器
64
- * @param name 渲染器名称
65
- * @param renderer 渲染函数
66
- */
67
- export function registerRenderer(name: string, renderer: Renderer) {
68
- rendererMap[name] = renderer
69
- }
70
-
71
- /**
72
- * 批量注册自定义渲染器
73
- * @param renderers 渲染器映射对象
74
- */
75
- export function registerRenderers(renderers: Record<string, Renderer>) {
76
- Object.assign(rendererMap, renderers)
77
- }
78
-
79
- /**
80
- * 获取渲染器
81
- * @param name 渲染器名称
82
- * @returns 渲染函数
83
- */
84
- export function getRenderer(name: string): Renderer | undefined {
85
- return rendererMap[name]
86
- }
87
-
88
- export {
89
- renderAreaCascader,
90
- renderAutoComplete,
91
- renderButton,
92
- renderCascader,
93
- renderCheckbox,
94
- renderCheckboxGroup,
95
- renderDatePicker,
96
- renderInput,
97
- renderInputGroup,
98
- renderInputNumber,
99
- renderInputPassword,
100
- renderInputRange,
101
- renderRadioGroup,
102
- renderSelect,
103
- renderSselectPage,
104
- renderSwitch,
105
- renderTree,
106
- renderTreeSelect,
107
- renderUpload,
108
- }
1
+ import type { AnyObject } from '@antsoo-lib/shared'
2
+
3
+ import type { VNode } from 'vue'
4
+
5
+ import { renderAreaCascader } from './AreaCascader'
6
+ import { renderAutoComplete } from './AutoComplete'
7
+ import { renderButton } from './Button'
8
+ import { renderCascader } from './Cascader'
9
+ import { renderCheckbox } from './Checkbox'
10
+ import { renderCheckboxGroup } from './CheckboxGroup'
11
+ import { renderCustom } from './Custom'
12
+ import { renderDatePicker } from './DatePicker'
13
+ import { renderInput } from './Input'
14
+ import { renderInputGroup } from './InputGroup'
15
+ import { renderInputNumber } from './InputNumber'
16
+ import { renderInputPassword } from './InputPassword'
17
+ import { renderInputRange } from './InputRange'
18
+ import { renderRadioGroup } from './RadioGroup'
19
+ import { renderSelect } from './Select'
20
+ import { renderSselectPage } from './SselectPage'
21
+ import { renderSwitch } from './Switch'
22
+ import { renderTree } from './Tree'
23
+ import { renderTreeSelect } from './TreeSelect'
24
+ import { renderUpload } from './Upload'
25
+ import type { ToolbarState } from './state'
26
+ import type { ToolbarItem } from './types'
27
+
28
+ // 渲染器映射类型定义
29
+ export type Renderer = (
30
+ item: ToolbarItem,
31
+ toolbarState: ToolbarState,
32
+ formValues?: AnyObject,
33
+ ) => VNode
34
+
35
+ // 渲染器映射
36
+ const defaultRendererMap: Record<string, Renderer> = {
37
+ button: renderButton,
38
+ input: renderInput,
39
+ inputRange: renderInputRange as Renderer,
40
+ inputGroup: renderInputGroup as Renderer,
41
+ radioGroup: renderRadioGroup,
42
+ checkbox: renderCheckbox,
43
+ switch: renderSwitch,
44
+ checkboxGroup: renderCheckboxGroup,
45
+ datePicker: renderDatePicker,
46
+ select: renderSelect,
47
+ inputNumber: renderInputNumber,
48
+ inputPassword: renderInputPassword,
49
+ upload: renderUpload,
50
+ tree: renderTree as Renderer,
51
+ treeSelect: renderTreeSelect,
52
+ sselectPage: renderSselectPage,
53
+ autoComplete: renderAutoComplete as Renderer,
54
+ cascader: renderCascader as Renderer,
55
+ areaCascader: renderAreaCascader as Renderer,
56
+ custom: renderCustom as Renderer,
57
+ }
58
+
59
+ // 导出的渲染器映射,支持动态修改
60
+ export const rendererMap: Record<string, Renderer> = { ...defaultRendererMap }
61
+
62
+ /**
63
+ * 注册自定义渲染器
64
+ * @param name 渲染器名称
65
+ * @param renderer 渲染函数
66
+ */
67
+ export function registerRenderer(name: string, renderer: Renderer) {
68
+ rendererMap[name] = renderer
69
+ }
70
+
71
+ /**
72
+ * 批量注册自定义渲染器
73
+ * @param renderers 渲染器映射对象
74
+ */
75
+ export function registerRenderers(renderers: Record<string, Renderer>) {
76
+ Object.assign(rendererMap, renderers)
77
+ }
78
+
79
+ /**
80
+ * 获取渲染器
81
+ * @param name 渲染器名称
82
+ * @returns 渲染函数
83
+ */
84
+ export function getRenderer(name: string): Renderer | undefined {
85
+ return rendererMap[name]
86
+ }
87
+
88
+ export {
89
+ renderAreaCascader,
90
+ renderAutoComplete,
91
+ renderButton,
92
+ renderCascader,
93
+ renderCheckbox,
94
+ renderCheckboxGroup,
95
+ renderDatePicker,
96
+ renderInput,
97
+ renderInputGroup,
98
+ renderInputNumber,
99
+ renderInputPassword,
100
+ renderInputRange,
101
+ renderRadioGroup,
102
+ renderSelect,
103
+ renderSselectPage,
104
+ renderSwitch,
105
+ renderTree,
106
+ renderTreeSelect,
107
+ renderUpload,
108
+ }