@complex-suite/component-antd 4.10.12

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 (51) hide show
  1. package/LayoutResizeObserver.ts +104 -0
  2. package/LocalResizeObserver.ts +46 -0
  3. package/README.md +67 -0
  4. package/antdConfig.ts +361 -0
  5. package/format.ts +458 -0
  6. package/history.md +325 -0
  7. package/icon.ts +65 -0
  8. package/index.test.ts +5 -0
  9. package/index.ts +55 -0
  10. package/package.json +39 -0
  11. package/plugin.ts +95 -0
  12. package/quick/QuickCascade.tsx +107 -0
  13. package/quick/QuickEdit.tsx +117 -0
  14. package/quick/QuickFloat.tsx +32 -0
  15. package/quick/QuickFloatModal.tsx +95 -0
  16. package/quick/QuickFloatValue.tsx +103 -0
  17. package/quick/QuickList.tsx +433 -0
  18. package/quick/data/FloatData.ts +77 -0
  19. package/src/AutoSpin.vue +39 -0
  20. package/src/AutoText.vue +101 -0
  21. package/src/ButtonView.tsx +62 -0
  22. package/src/CollapseArea.tsx +88 -0
  23. package/src/EditArea.tsx +205 -0
  24. package/src/EditView.tsx +179 -0
  25. package/src/FlexBox.tsx +74 -0
  26. package/src/FormList.tsx +226 -0
  27. package/src/ImageViewer.tsx +122 -0
  28. package/src/InfoArea.tsx +182 -0
  29. package/src/InfoView.tsx +150 -0
  30. package/src/MenuView.tsx +91 -0
  31. package/src/ModalView.tsx +274 -0
  32. package/src/MultipleImport.tsx +231 -0
  33. package/src/SearchArea.tsx +170 -0
  34. package/src/SelectText.vue +59 -0
  35. package/src/SimpleTable.tsx +256 -0
  36. package/src/SingleImport.tsx +189 -0
  37. package/src/TableView.tsx +415 -0
  38. package/src/components/AutoRender.tsx +19 -0
  39. package/src/components/ChoiceInfo.vue +73 -0
  40. package/src/components/PaginationView.tsx +103 -0
  41. package/src/components/TableMenu.tsx +93 -0
  42. package/src/dictionary/AutoEditItem.tsx +164 -0
  43. package/src/dictionary/AutoInfoItem.tsx +126 -0
  44. package/src/dictionary/AutoItem.tsx +219 -0
  45. package/src/icons/EmptyImage.vue +30 -0
  46. package/src/icons/ErrorImage.vue +30 -0
  47. package/src/style/index.css +304 -0
  48. package/tsconfig.json +8 -0
  49. package/type.ts +4 -0
  50. package/vitest.config.ts +11 -0
  51. package/widthCalculator.ts +20 -0
package/format.ts ADDED
@@ -0,0 +1,458 @@
1
+ import { reactive } from 'vue'
2
+ import dayjs from 'dayjs'
3
+ import type { Dayjs } from 'dayjs'
4
+ import { isArray } from '@complex-suite/utils'
5
+ import { notice } from '@complex-suite/plugin'
6
+ import { AttrsValue, StatusValue, InputEdit, InputNumberEdit, TextAreaEdit, SwitchEdit, SelectEdit, DateEdit, DateRangeEdit, FileEdit, CustomEdit, FormEdit, SimpleDateEdit, ListEdit } from "@complex-suite/data"
7
+ import type { AttrsValueInitOption, DictionaryEditMod } from "@complex-suite/data"
8
+ import type { AutoItemPayloadType } from './src/dictionary/AutoItem'
9
+
10
+ const init = function (itemAttrs: AttrsValue, targetProp: PropertyKey, formData: Record<PropertyKey, unknown>, prop: PropertyKey) {
11
+ itemAttrs.props[targetProp] = formData[prop]
12
+ }
13
+
14
+ const createInit = function(targetProp: PropertyKey) {
15
+ return function (itemAttrs: AttrsValue, formData: Record<PropertyKey, unknown>, prop: PropertyKey) {
16
+ init(itemAttrs, targetProp, formData, prop)
17
+ }
18
+ }
19
+
20
+ const modelFuncDict = {
21
+ valueInit: createInit('value'),
22
+ checkInit: createInit('checked'),
23
+ input: function (formdata: Record<PropertyKey, unknown>, prop: PropertyKey, args: unknown[]) {
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ formdata[prop] = (args[0] as any).target.value
26
+ },
27
+ change: function (formdata: Record<PropertyKey, unknown>, prop: PropertyKey, args: unknown[]) {
28
+ formdata[prop] = args[0]
29
+ }
30
+ }
31
+
32
+ type modelFuncDictType = typeof modelFuncDict
33
+
34
+ interface dictItemType {
35
+ init: false | modelFuncDictType['checkInit'] | modelFuncDictType['valueInit']
36
+ on?: Record<string, modelFuncDictType['input'] | modelFuncDictType['change']>
37
+ format: (edit: DictionaryEditMod, payload: AutoItemPayloadType<'edit'>) => AttrsValue
38
+ }
39
+
40
+ const bindEvent = function(dictItem: dictItemType, itemAttrs: AttrsValue, edit: DictionaryEditMod, payload: AutoItemPayloadType<'edit'>) {
41
+ const formData = payload.targetData
42
+ const onData = dictItem.on
43
+ if (dictItem.init) {
44
+ dictItem.init(itemAttrs, formData, edit.$prop)
45
+ }
46
+ // 加载双向绑定逻辑
47
+ for (const funcName in onData) {
48
+ itemAttrs.pushEvent(funcName, (...args) => {
49
+ onData[funcName](formData, edit.$prop, args)
50
+ }, 'before')
51
+ }
52
+ // 加载单独设置的事件监控
53
+ for (const funcName in edit.$on) {
54
+ itemAttrs.pushEvent(funcName, (...args) => {
55
+ args.push(payload)
56
+ edit.$on[funcName](...args)
57
+ })
58
+ }
59
+ }
60
+
61
+ const dict = reactive({
62
+ $input: {
63
+ init: modelFuncDict.valueInit,
64
+ on: {
65
+ input: modelFuncDict.input
66
+ },
67
+ format(edit: InputEdit, payload: AutoItemPayloadType<'edit'>) {
68
+ const itemAttrs = new AttrsValue({
69
+ props: {
70
+ type: edit.$option.type,
71
+ allowClear: !edit.$option.hideClear,
72
+ maxLength: edit.$option.size,
73
+ disabled: payload.disabled,
74
+ placeholder: edit.placeholder ? edit.placeholder : undefined
75
+ },
76
+ on: {
77
+ pressEnter(_e: Event) {
78
+ payload.parent.triggerEnter(edit.$prop, payload)
79
+ }
80
+ }
81
+ })
82
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
83
+ return itemAttrs
84
+ }
85
+ },
86
+ $inputNumber: {
87
+ init: modelFuncDict.valueInit,
88
+ on: {
89
+ change: modelFuncDict.change
90
+ },
91
+ format(edit: InputNumberEdit, payload: AutoItemPayloadType<'edit'>) {
92
+ const itemAttrs = new AttrsValue({
93
+ props: {
94
+ min: edit.$option.min,
95
+ max: edit.$option.max,
96
+ precision: edit.$option.precision,
97
+ step: edit.$option.step,
98
+ disabled: payload.disabled,
99
+ placeholder: edit.placeholder ? edit.placeholder : undefined
100
+ },
101
+ on: {
102
+ pressEnter(_e: Event) {
103
+ payload.parent.triggerEnter(edit.$prop, payload)
104
+ }
105
+ }
106
+ })
107
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
108
+ return itemAttrs
109
+ }
110
+ },
111
+ $textArea: {
112
+ init: modelFuncDict.valueInit,
113
+ on: {
114
+ input: modelFuncDict.input
115
+ },
116
+ format(edit: TextAreaEdit, payload: AutoItemPayloadType<'edit'>) {
117
+ const itemAttrs = new AttrsValue({
118
+ props: {
119
+ maxLength: edit.$option.size,
120
+ autoSize: edit.$option.autoSize,
121
+ allowClear: !edit.$option.hideClear,
122
+ disabled: payload.disabled,
123
+ placeholder: edit.placeholder ? edit.placeholder : undefined
124
+ }
125
+ })
126
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
127
+ return itemAttrs
128
+ }
129
+ },
130
+ $switch: {
131
+ init: modelFuncDict.checkInit,
132
+ on: {
133
+ change: modelFuncDict.change
134
+ },
135
+ format(edit: SwitchEdit, payload: AutoItemPayloadType<'edit'>) {
136
+ const itemAttrs = new AttrsValue({
137
+ props: {
138
+ disabled: payload.disabled
139
+ }
140
+ })
141
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
142
+ return itemAttrs
143
+ }
144
+ },
145
+ $select: {
146
+ init: modelFuncDict.valueInit,
147
+ on: {
148
+ change: modelFuncDict.change
149
+ },
150
+ format(edit: SelectEdit, payload: AutoItemPayloadType<'edit'>) {
151
+ let isLoading = edit.$load ? edit.getLoad() === StatusValue.ing : false
152
+ const search = edit.$search
153
+ const on: AttrsValueInitOption['on'] = {}
154
+ if (search) {
155
+ if (isLoading && search.operate) {
156
+ isLoading = false
157
+ }
158
+ on.search = function(value?: string) {
159
+ edit.loadData(true, value)
160
+ }
161
+ // 关闭会自动触发search value = ''事件,因此reload=false不进行实现
162
+ // if (search.reload) {
163
+ // on.dropdownVisibleChange = function(open: boolean) {
164
+ // // reload模式下打开自动清空
165
+ // if (open) {
166
+ // search!.value = undefined
167
+ // edit.$clearData()
168
+ // }
169
+ // }
170
+ // }
171
+ }
172
+ const itemAttrs = new AttrsValue({
173
+ props: {
174
+ mode: edit.multiple ? 'multiple' : 'default',
175
+ options: !edit.$filter ? edit.$select.getList() : edit.$filter(edit.$select, payload.list),
176
+ open: (edit.$option as { open?: boolean }).open,
177
+ showSearch: !!search,
178
+ searchValue: search?.value,
179
+ showArrow: !edit.$option.hideArrow,
180
+ notFoundContent: edit.$option.notFoundContent,
181
+ filterOption: false,
182
+ allowClear: !edit.$option.hideClear,
183
+ dropdownMatchSelectWidth: edit.$option.autoWidth,
184
+ disabled: payload.disabled || isLoading,
185
+ placeholder: edit.placeholder ? edit.placeholder : undefined
186
+ },
187
+ on: on
188
+ })
189
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
190
+ return itemAttrs
191
+ }
192
+ },
193
+ $cascader: {
194
+ init: modelFuncDict.valueInit,
195
+ on: {
196
+ change: modelFuncDict.change
197
+ },
198
+ format(edit: SelectEdit<PropertyKey>, payload: AutoItemPayloadType<'edit'>) {
199
+ const isLoading = edit.$load ? edit.getLoad() === StatusValue.ing : false
200
+ const itemAttrs = new AttrsValue({
201
+ props: {
202
+ options: !edit.$filter ? edit.$select.getCascaderList() : edit.$filter(edit.$select, payload.list),
203
+ showArrow: !edit.$option.hideArrow,
204
+ allowClear: !edit.$option.hideClear,
205
+ disabled: payload.disabled || isLoading,
206
+ placeholder: edit.placeholder ? edit.placeholder : undefined
207
+ }
208
+ })
209
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
210
+ return itemAttrs
211
+ }
212
+ },
213
+ $date: {
214
+ init: modelFuncDict.valueInit,
215
+ on: {
216
+ change: modelFuncDict.change
217
+ },
218
+ format(edit: DateEdit, payload: AutoItemPayloadType<'edit'>) {
219
+ const showTime = edit.$option.time ? {
220
+ format: edit.$option.time.showFormat,
221
+ defaultValue: dayjs(edit.$option.time.defaultValue, edit.$option.time.format)
222
+ } : false
223
+ const itemAttrs = new AttrsValue({
224
+ props: {
225
+ disabled: payload.disabled,
226
+ placeholder: edit.placeholder ? edit.placeholder : undefined,
227
+ format: edit.$option.showFormat,
228
+ allowClear: !edit.$option.hideClear,
229
+ showTime: showTime,
230
+ defaultPickerValue: dayjs('00:00:00', 'HH:mm:ss')
231
+ }
232
+ })
233
+ const complexDisabledDate = edit.$option.complexDisabledDate
234
+ if (edit.$option.disabledDate) {
235
+ itemAttrs.props.disabledDate = !complexDisabledDate ? edit.$option.disabledDate : function(value: any) {
236
+ return edit.$option.disabledDate!(value, payload)
237
+ }
238
+ }
239
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
240
+ return itemAttrs
241
+ }
242
+ },
243
+ $dateRange: {
244
+ init: modelFuncDict.valueInit,
245
+ on: {
246
+ change: modelFuncDict.change
247
+ },
248
+ format(edit: DateRangeEdit, payload: AutoItemPayloadType<'edit'>) {
249
+ const showTime = edit.$option.time ? {
250
+ format: edit.$option.time.showFormat,
251
+ defaultValue: [dayjs(edit.$option.time!.defaultValue, edit.$option.time.format), dayjs(edit.$option.time!.defaultEndValue, edit.$option.time.format)]
252
+ } : false
253
+ const itemAttrs = new AttrsValue({
254
+ props: {
255
+ disabled: payload.disabled,
256
+ placeholder: [edit.placeholder, edit.endPlaceholder],
257
+ format: edit.$option.showFormat,
258
+ allowClear: !edit.$option.hideClear,
259
+ separator: edit.$option.separator,
260
+ showTime: showTime
261
+ }
262
+ })
263
+ const complexDisabledDate = edit.$option.complexDisabledDate || !!edit.$option.rangeLimit
264
+ if (edit.$option.disabledDate) {
265
+ itemAttrs.props.disabledDate = !complexDisabledDate ? edit.$option.disabledDate : function(value: any) {
266
+ return edit.$option.disabledDate!(value, payload, edit.$option.rangeLimit)
267
+ }
268
+ }
269
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
270
+ if (edit.$option.rangeLimit) {
271
+ itemAttrs.pushEvent('calendarChange', function(value: undefined | [null | Dayjs, null | Dayjs], dateStrings: [string, string], info: { range: 'start' | 'end' }) {
272
+ if (edit.$option.rangeLimit) {
273
+ if (value) {
274
+ if (value[0] && value[1]) {
275
+ // 限制模式下且存在值时进行值有效判断
276
+ const offset = Math.abs(SimpleDateEdit.$compareDate(value[0], value[1]))
277
+ const rangeLimitValue = edit.$option.rangeLimit.value * 1000
278
+ if (!edit.$option.rangeLimit.eq ? offset >= rangeLimitValue : offset > rangeLimitValue) {
279
+ // 当大于限制值时
280
+ if (info.range === 'start') {
281
+ value[1] = null
282
+ dateStrings[1] = ''
283
+ if (edit.$option.rangeLimit.message) {
284
+ const message = edit.$option.rangeLimit.message(offset, payload)
285
+ if (message) {
286
+ notice.message(message, 'warn')
287
+ }
288
+ }
289
+ } else if (info.range === 'end') {
290
+ value[0] = null
291
+ dateStrings[0] = ''
292
+ if (edit.$option.rangeLimit.message) {
293
+ const message = edit.$option.rangeLimit.message(offset, payload)
294
+ if (message) {
295
+ notice.message(message, 'warn')
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ // 限制模式下缓存值
302
+ payload.targetData[payload.prop] = value
303
+ }
304
+ }
305
+ }, 'before')
306
+ itemAttrs.pushEvent('openChange', function(status: boolean) {
307
+ if (edit.$option.rangeLimit) {
308
+ if(!status) {
309
+ // 关闭时
310
+ const value = payload.targetData[payload.prop] as undefined | [null | Dayjs, null | Dayjs]
311
+ if (value && isArray(value)) {
312
+ if (!!value[0] !== !!value[1]) {
313
+ // 有且仅有1个存在值
314
+ payload.targetData[payload.prop] = undefined
315
+ }
316
+ }
317
+ }
318
+ }
319
+ }, 'after')
320
+ }
321
+ return itemAttrs
322
+ }
323
+ },
324
+ $file: {
325
+ init: modelFuncDict.valueInit,
326
+ on: {
327
+ change: modelFuncDict.change
328
+ },
329
+ format(edit: FileEdit<boolean>, payload: AutoItemPayloadType<'edit'>) {
330
+ let layout = edit.$option.layout
331
+ if (layout == 'auto') {
332
+ if (!payload.parent.gridParse) {
333
+ layout = 'end'
334
+ } else {
335
+ layout = 'bottom'
336
+ }
337
+ }
338
+ const buttonOption = { ...edit.$option.button }
339
+ if (buttonOption.name == undefined) {
340
+ buttonOption.name = edit.$name
341
+ }
342
+ const itemAttrs = new AttrsValue({
343
+ props: {
344
+ accept: edit.$option.accept,
345
+ maxSize: edit.$option.size,
346
+ button: buttonOption,
347
+ multiple: (edit as FileEdit<true>).$option.multiple,
348
+ isUrl: edit.$option.isUrl,
349
+ complex: edit.$option.complex,
350
+ upload: edit.$option.upload,
351
+ image: edit.$option.image,
352
+ layout: layout,
353
+ disabled: payload.disabled
354
+ }
355
+ })
356
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
357
+ return itemAttrs
358
+ }
359
+ },
360
+ $custom: {
361
+ init: false,
362
+ on: {},
363
+ format(edit: CustomEdit, payload: AutoItemPayloadType<'edit'>) {
364
+ const itemAttrs = new AttrsValue({
365
+ props: {
366
+ ...edit.$option,
367
+ disabled: payload.disabled
368
+ }
369
+ })
370
+ const self = {
371
+ init: false,
372
+ on: {}
373
+ } as dictItemType
374
+ if (edit.$model.init) {
375
+ self.init = createInit(edit.$model.init)
376
+ }
377
+ if (edit.$model.change) {
378
+ if (edit.$model.handler) {
379
+ self.on![edit.$model.change] = edit.$model.handler
380
+ } else if (edit.$model.change === 'input') {
381
+ self.on!.input = modelFuncDict.input
382
+ } else {
383
+ self.on![edit.$model.change] = modelFuncDict.change
384
+ }
385
+ }
386
+ bindEvent(self as dictItemType, itemAttrs, edit, payload)
387
+ return itemAttrs
388
+ }
389
+ },
390
+ $form: {
391
+ init: false,
392
+ on: {},
393
+ format(edit: FormEdit, payload: AutoItemPayloadType<'edit'>) {
394
+ const itemAttrs = new AttrsValue({
395
+ props: {
396
+ list: edit.$runtime.observeList,
397
+ form: edit.$runtime.form,
398
+ type: edit.$runtime.type,
399
+ gridParse: edit.$option.gridParse === false ? undefined : (edit.$option.gridParse || edit.$runtime.dictionary!.$layout.grid.getValue(payload.type)),
400
+ menu: edit.$option.menu,
401
+ disabled: payload.disabled
402
+ }
403
+ })
404
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
405
+ return itemAttrs
406
+ }
407
+ },
408
+ $list: {
409
+ init: modelFuncDict.valueInit,
410
+ on: {
411
+ change: modelFuncDict.change
412
+ },
413
+ format(edit: ListEdit, payload: AutoItemPayloadType<'edit'>) {
414
+ const itemAttrs = new AttrsValue({
415
+ props: {
416
+ runtime: edit.$runtime,
417
+ type: edit.$runtime.type,
418
+ header: edit.$option.header,
419
+ menu: edit.$option.menu,
420
+ tableProps: edit.$option.tableProps
421
+ }
422
+ })
423
+ bindEvent(this as dictItemType, itemAttrs, edit, payload)
424
+ return itemAttrs
425
+ }
426
+ }
427
+ })
428
+
429
+ export const parseEditAttrs = function (edit: DictionaryEditMod, payload: AutoItemPayloadType<'edit'>) {
430
+ if (edit.type === 'input') {
431
+ return dict.$input.format(edit, payload)
432
+ } else if (edit.type === 'inputNumber') {
433
+ return dict.$inputNumber.format(edit, payload)
434
+ } else if (edit.type === 'textArea') {
435
+ return dict.$textArea.format(edit, payload)
436
+ } else if (edit.type === 'switch') {
437
+ return dict.$switch.format(edit, payload)
438
+ } else if (edit.type === 'select') {
439
+ return dict.$select.format(edit, payload)
440
+ } else if (edit.type === 'cascader') {
441
+ return dict.$cascader.format(edit, payload)
442
+ } else if (edit.type === 'date') {
443
+ return dict.$date.format(edit, payload)
444
+ } else if (edit.type === 'dateRange') {
445
+ return dict.$dateRange.format(edit, payload)
446
+ } else if (edit.type === 'file') {
447
+ return dict.$file.format(edit, payload)
448
+ } else if (edit.type === 'custom') {
449
+ return dict.$custom.format(edit, payload)
450
+ } else if (edit.type === 'form') {
451
+ return dict.$form.format(edit, payload)
452
+ } else if (edit.type === 'list') {
453
+ return dict.$list.format(edit, payload)
454
+ } else {
455
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
456
+ console.error(`[${(edit as any).type}]:FormItem类型匹配失败,请检查代码`)
457
+ }
458
+ }