@ithinkdt/ui 4.0.0-38 → 4.0.0-400

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 (60) hide show
  1. package/auto-imports.js +1 -1
  2. package/dist/components-B_qzc9ro.js +1736 -0
  3. package/dist/components.js +5 -0
  4. package/dist/directives-qqYcWl1I.js +194 -0
  5. package/dist/directives.js +3 -0
  6. package/dist/index.js +1212 -0
  7. package/dist/page.js +519 -0
  8. package/dist/use-i18n-Dx7V4KrY.js +6 -0
  9. package/dist/use-style-DcT-1dj4.js +29 -0
  10. package/dist/use-style.js +2 -0
  11. package/{src → esm}/components.d.ts +56 -15
  12. package/esm/components.js +1 -0
  13. package/esm/directives.js +1 -0
  14. package/esm/index.js +1 -0
  15. package/{src → esm}/page.d.ts +2 -2
  16. package/esm/page.js +1 -0
  17. package/esm/use-style.js +1 -0
  18. package/package.json +29 -26
  19. package/unocss-preset.d.ts +5 -0
  20. package/unocss-preset.js +163 -0
  21. package/src/components/Checkboxes.jsx +0 -130
  22. package/src/components/DataActions.jsx +0 -105
  23. package/src/components/DataCustom.jsx +0 -187
  24. package/src/components/DataFilter.jsx +0 -119
  25. package/src/components/DataForm.jsx +0 -264
  26. package/src/components/DataLocaleInput.jsx +0 -121
  27. package/src/components/DataPagination.jsx +0 -62
  28. package/src/components/DataSelection.jsx +0 -57
  29. package/src/components/DataTable.jsx +0 -302
  30. package/src/components/Radios.jsx +0 -134
  31. package/src/components/UserDept.jsx +0 -643
  32. package/src/components/assets.jsx +0 -274
  33. package/src/components/index.js +0 -11
  34. package/src/design/Account.jsx +0 -154
  35. package/src/design/Appearance.jsx +0 -89
  36. package/src/design/Breadcrumb.jsx +0 -67
  37. package/src/design/Fullscreen.jsx +0 -65
  38. package/src/design/Language.jsx +0 -45
  39. package/src/design/Layout.jsx +0 -241
  40. package/src/design/Logo.jsx +0 -92
  41. package/src/design/Menu.jsx +0 -133
  42. package/src/design/MultiTabs.jsx +0 -501
  43. package/src/design/Notification.jsx +0 -311
  44. package/src/design/Tenant.jsx +0 -88
  45. package/src/design/common.jsx +0 -21
  46. package/src/design/index.js +0 -11
  47. package/src/directives/index.js +0 -2
  48. package/src/directives/spin.js +0 -181
  49. package/src/directives/tooltip.jsx +0 -121
  50. package/src/index.js +0 -18
  51. package/src/page.jsx +0 -740
  52. package/src/use-i18n.js +0 -8
  53. package/src/use-style.js +0 -58
  54. package/src/utils.js +0 -20
  55. package/unocss.d.ts +0 -5
  56. package/unocss.js +0 -94
  57. /package/{src → esm}/design.d.ts +0 -0
  58. /package/{src → esm}/directives.d.ts +0 -0
  59. /package/{src → esm}/index.d.ts +0 -0
  60. /package/{src → esm}/use-style.d.ts +0 -0
package/src/page.jsx DELETED
@@ -1,740 +0,0 @@
1
- import { until } from '@vueuse/core'
2
- import { format } from 'date-fns'
3
- import {
4
- NButton, NCheckbox, NColorPicker, NDatePicker, NDrawer, NDrawerContent, NFlex, NInput,
5
- NInputNumber, NModal, NScrollbar, NSelect, NText, NUpload, useMessage,
6
- } from 'ithinkdt-ui'
7
- import { useFormItem } from 'ithinkdt-ui/es/_mixins'
8
- import { computed, defineComponent, h, mergeProps, ref, shallowRef, unref } from 'vue'
9
-
10
- import { useDict, useDictMap } from '@ithinkdt/common/dict'
11
-
12
- import { DataForm, DtDeptRender, DtUserDept, DtUserRender, NCheckboxes, NRadios } from './components'
13
- import { useI18n } from './use-i18n.js'
14
-
15
- const mapProps = (props) => {
16
- return Object.fromEntries(Object.entries(props || {}).map(([prop, value]) => [prop, unref(value)]))
17
- }
18
-
19
- const SimpleUpload = /* @__PURE__ */ defineComponent({
20
- name: 'SimpleUpload',
21
- props: {
22
- type: { type: String, default: 'file' }, // file | image
23
- size: { type: String, default: 'medium' },
24
- multiple: { type: Boolean, default: false },
25
- max: { type: Number, default: undefined },
26
- accept: { type: String, default: undefined },
27
- maxSize: { type: Number, default: undefined }, // MB
28
- disabled: { type: Boolean, default: undefined },
29
- fileList: { type: Array, default: () => [] },
30
- onUpdateFileList: { type: [Array, Function] },
31
- uploadFile: { type: Function },
32
- },
33
- setup(props, { slots, expose }) {
34
- const { t } = useI18n()
35
- SimpleUpload.t = t
36
-
37
- const formItem = useFormItem(props)
38
-
39
- const message = useMessage()
40
- const customRequest = computed(() => props.customRequest || (
41
- ({ file, onProgress, onFinish, onError }) => {
42
- props.uploadFile(file.file, percent => onProgress({ percent }))
43
- .then((id) => {
44
- file.file.fileId = id
45
- onFinish()
46
- }).catch((error) => {
47
- message.error(error.message)
48
- onError(error)
49
- })
50
- }
51
- ))
52
-
53
- const inst = ref()
54
- expose({
55
- submit() {
56
- return until(inst).toBeTruthy().then(inst => inst.submit())
57
- },
58
- })
59
-
60
- const onUpdate = (fileList) => {
61
- props.onUpdateFileList?.(fileList)
62
- nextTick(() => formItem.nTriggerFormChange())
63
- }
64
- return () => {
65
- const { type, onUpdateFileList, ...props0 } = props
66
- return (
67
- <NUpload
68
- {...props0}
69
- ref={inst}
70
- customRequest={customRequest.value}
71
- listType={type === 'image' ? 'image-card' : 'text'}
72
- accept={props0.accept ?? type === 'image' ? 'image/*' : undefined}
73
- onUpdate:fileList={onUpdate}
74
- >
75
- {{
76
- default: () => (
77
- <NButton disabled={formItem.mergedDisabledRef.value} size={formItem.mergedSizeRef.value}>
78
- {
79
- t('common.page.form.selectFileText')
80
- }
81
- </NButton>
82
- ),
83
- ...slots,
84
- }}
85
- </NUpload>
86
- )
87
- }
88
- },
89
- })
90
-
91
- export function createPageFormHelper({
92
- getUserGroups, getUsersByGroup, getUsersByDept, getUsersByUsername, uploadFile, getFileInfos,
93
- }) {
94
- return {
95
- input: () => (
96
- { slots, props },
97
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
98
- ) => {
99
- if (readonly) return <NText depth={2} style="line-height: 1.25">{modelValue ?? ''}</NText>
100
-
101
- props = mapProps(props)
102
- return h(NInput, {
103
- 'clearable': true,
104
- ...props,
105
- ...params,
106
- 'value': modelValue,
107
- 'onUpdate:value': onUpdateValue,
108
- }, slots)
109
- },
110
- number: () => (
111
- { slots, props },
112
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
113
- ) => {
114
- if (readonly) return <NText depth={2} style="line-height: 1.25">{modelValue ?? ''}</NText>
115
- props = mapProps(props)
116
- return h(NInputNumber, {
117
- 'clearable': true,
118
- ...props,
119
- ...params,
120
- 'value': modelValue,
121
- 'onUpdate:value': onUpdateValue,
122
- }, slots)
123
- },
124
- select: () => {
125
- let dictType0, options0
126
- return (
127
- { slots, props: props0 },
128
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
129
- ) => {
130
- const { dictType, options, ...props } = mapProps(props0)
131
- if (options) {
132
- options0 = options
133
- } else {
134
- if (dictType0 !== dictType) {
135
- dictType0 = dictType
136
- if (!options0 && dictType0) {
137
- options0 = useDict(dictType0)
138
- }
139
- }
140
- }
141
- if (readonly) {
142
- if (props.multiple) {
143
- const items = modelValue?.map(it => options0?.find(it2 => it2[props.valueField || 'value'] === it)) ?? []
144
- return (
145
- <NText depth={2} style="line-height: 1.25">
146
- {
147
- items.map((it, i, arr) => {
148
- const vn = it ? (props.renderLabel ? props.renderLabel(it) ?? '' : it[props.labelField || 'label'] ?? '') : (modelValue[i] ?? '')
149
- return (
150
- <span key={it[props.valueField || 'value']}>
151
- {vn}
152
- {i < arr.length - 1 ? ', ' : ''}
153
- </span>
154
- )
155
- })
156
- }
157
- </NText>
158
- )
159
- } else {
160
- const it = options0?.find(item => item[props.valueField || 'value'] === modelValue)
161
- return <NText depth={2} style="line-height: 1.25">{it ? (props.renderLabel ? props.renderLabel(it) ?? '' : it[props.labelField || 'label'] ?? '') : (modelValue ?? '')}</NText>
162
- }
163
- }
164
-
165
- return h(NSelect, {
166
- 'clearable': true,
167
- 'loading': options0?.loading,
168
- ...props,
169
- 'options': unref(options0),
170
- ...params,
171
- 'value': modelValue,
172
- 'onUpdate:value': onUpdateValue,
173
- }, slots)
174
- }
175
- },
176
- checkbox: () => (
177
- { slots, props },
178
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
179
- ) => {
180
- props = mapProps(props)
181
- if (readonly) {
182
- let content
183
- if (modelValue === (props.checkedValue ?? true)) {
184
- content = slots?.checked
185
- ? slots.checked()
186
- : <NCheckbox checked />
187
- } else {
188
- content = slots?.unchecked ? slots.unchecked() : <NCheckbox disabled />
189
- }
190
- return <NText depth={2} style="line-height: 1.25">{content}</NText>
191
- }
192
-
193
- return h(NCheckbox, {
194
- ...props,
195
- ...params,
196
- 'checked': modelValue,
197
- 'onUpdate:checked': onUpdateValue,
198
- }, slots)
199
- },
200
- checkboxes: () => {
201
- let dictType0, options0
202
- return (
203
- { props: props0 },
204
- { modelValue, required, readonly, ...params },
205
- ) => {
206
- const { dictType, options, ...props } = mapProps(props0)
207
- if (options) {
208
- options0 = options
209
- } else {
210
- if (dictType0 !== dictType) {
211
- dictType0 = dictType
212
- if (!options0 && dictType0) {
213
- options0 = useDict(dictType0)
214
- }
215
- }
216
- }
217
- if (readonly) {
218
- const items = modelValue?.map(it => options0?.find(it2 => it2[props.valueField || 'value'] === it)) ?? []
219
- return (
220
- <NText depth={2} style="line-height: 2.4">
221
- {
222
- items.map((it, i, arr) => {
223
- const vn = it ? (it[props.labelField ?? 'label'] ?? '') : (modelValue[i] ?? '')
224
- return (
225
- <span key={it[props.valueField ?? 'value']}>
226
- {vn}
227
- {i < arr.length - 1 ? ', ' : ''}
228
- </span>
229
- )
230
- })
231
- }
232
- </NText>
233
- )
234
- }
235
-
236
- return h(NCheckboxes,
237
- {
238
- ...props,
239
- ...params,
240
- options: options0,
241
- modelValue,
242
- },
243
- )
244
- }
245
- },
246
- radios: () => {
247
- let dictType0, options0
248
- return (
249
- { props: props0 },
250
- { modelValue, required, readonly, ...params },
251
- ) => {
252
- const { dictType, options, ...props } = mapProps(props0)
253
- if (options) {
254
- options0 = options
255
- } else {
256
- if (dictType0 !== dictType) {
257
- dictType0 = dictType
258
- if (!options0 && dictType0) {
259
- options0 = useDict(dictType0)
260
- }
261
- }
262
- }
263
-
264
- if (readonly) {
265
- const it = options0?.find(item => item[props.valueField ?? 'value'] === modelValue)
266
- return <NText depth={2} style="line-height: 1.25">{it ? (it[props.labelField ?? 'label'] ?? '') : (modelValue ?? '')}</NText>
267
- }
268
-
269
- return h(
270
- NRadios,
271
- {
272
- ...props,
273
- ...params,
274
- options: options0,
275
- modelValue,
276
- },
277
- )
278
- }
279
- },
280
- datepicker: () => (
281
- { slots, props },
282
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
283
- ) => {
284
- const { type = 'date', format: formatter = type.startsWith('datetime') ? 'yyyy-MM-dd HH:mm:ss' : 'yyyy-MM-dd', ...props2 } = mapProps(props)
285
- if (readonly) {
286
- if (type.endsWith('range')) {
287
- return (
288
- <NText depth={2} style="line-height: 1.25">
289
- {modelValue
290
- ? `${modelValue[0] ? format(modelValue[0], formatter) : ''
291
- } ~ ${modelValue[1] ? format(modelValue[1], formatter) : ''}`
292
- : ''}
293
- </NText>
294
- )
295
- }
296
- return (
297
- <NText depth={2} style="line-height: 1.25">
298
- {modelValue ? format(modelValue, formatter) : ''}
299
- </NText>
300
- )
301
- }
302
-
303
- return h(NDatePicker, {
304
- 'clearable': true,
305
- ...props2,
306
- ...params,
307
- type,
308
- 'format': formatter,
309
- 'value': modelValue,
310
- 'onUpdate:value': onUpdateValue,
311
- }, slots)
312
- },
313
- file: () => {
314
- return (
315
- { slots, props },
316
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
317
- ) => {
318
- props = mapProps(props)
319
- if (readonly) {
320
- console.warn(`[file] 原则上此组建不应该显示在详情中`)
321
- if (fileList.value.length === 0) return
322
- return (
323
- <NFlex gap="8" vertical>
324
- {modelValue.map(it => (
325
- <a
326
- key={it.id}
327
- href={it.url}
328
- target="_blank"
329
- rel="noreferrer"
330
- style="max-width: 100px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; display: inline-block"
331
- >
332
- {it.name}
333
- </a>
334
- ))}
335
- </NFlex>
336
- )
337
- }
338
- return h(SimpleUpload, {
339
- ...props,
340
- ...params,
341
- defaultUpload: false,
342
- uploadFile,
343
- fileList: modelValue,
344
- onUpdateFileList: onUpdateValue,
345
- }, slots)
346
- }
347
- },
348
- upload: () => {
349
- let lastModelValue = null
350
- const idMap = new Map()
351
- const fileMap = new Map()
352
- const fileList = shallowRef([])
353
- let key = 0
354
-
355
- const update = (ids) => {
356
- const key0 = ++key
357
- fileList.value = ids.map(id => fileMap.get(id)).filter(Boolean)
358
- const ids0 = ids.filter(id => !fileMap.has(id))
359
- Promise.resolve(ids0.length > 0 ? getFileInfos(ids0) : [])
360
- .then((res) => {
361
- if (key0 !== key) return
362
- fileList.value = ids.map(id => fileMap.get(id) || res.find(it => it.id === id))
363
- fileMap.clear()
364
- for (const it of fileList.value) {
365
- fileMap.set(it.id, it)
366
- }
367
- })
368
- }
369
-
370
- let inst
371
- const renderer = (
372
- { slots, props },
373
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
374
- ) => {
375
- const props0 = mapProps(props)
376
- inst = (props0.ref ??= shallowRef())
377
- if (lastModelValue !== modelValue) {
378
- lastModelValue = modelValue
379
- update(modelValue?.split(',') ?? [])
380
- }
381
- if (readonly) {
382
- if (fileList.value.length === 0) return
383
- return (
384
- <NFlex gap="8" vertical>
385
- {fileList.value.map(it => (
386
- <a
387
- key={it.id}
388
- href={it.url}
389
- target="_blank"
390
- rel="noreferrer"
391
- title={it.name}
392
- style="max-width: 100px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; display: inline-block"
393
- >
394
- {it.name}
395
- </a>
396
- ))}
397
- </NFlex>
398
- )
399
- }
400
- return h(SimpleUpload, {
401
- ...props0,
402
- ...params,
403
- uploadFile,
404
- fileList: fileList.value,
405
- onUpdateFileList: (fileList0 = []) => {
406
- fileMap.clear()
407
- for (const f of fileList0) {
408
- if (f.file.fileId) {
409
- idMap.set(f.id, f.file.fileId)
410
- }
411
-
412
- if (f.file.fileId) fileMap.set(f.file.fileId, f)
413
- else fileMap.set(f.id, f)
414
- }
415
- fileList.value = fileList0
416
- const ids = fileList.value.map(f => idMap.get(f.id) || f.id).join(',') || null
417
- onUpdateValue(ids)
418
- },
419
- }, slots)
420
- }
421
- return {
422
- renderer,
423
- beforeSubmit: async () => {
424
- await inst?.value?.submit()
425
- await until(fileList).toMatch(list => list.every(file => !['pending', 'uploading'].includes(file.status)))
426
- if (fileList.value.some(file => file.status === 'error')) {
427
- return SimpleUpload.t('common.page.form.validate.fileErrorMessage')
428
- }
429
- },
430
- }
431
- },
432
- user: () => {
433
- let users, groups, depts
434
- return (
435
- { slots, props: props0 },
436
- { modelValue, 'onUpdate:modelValue': onUpdateValue, required, readonly, ...params },
437
- ) => {
438
- const props = mapProps(props0)
439
- if (!users) {
440
- users = shallowRef([])
441
- getUsersByUsername().then((res) => {
442
- users.value = res
443
- })
444
- getUserGroups().then((res) => {
445
- groups.value = res
446
- })
447
- getDeptsByCode().then((res) => {
448
- depts.value = res
449
- })
450
- }
451
- if (readonly) {
452
- return <DtUserRender value={modelValue} multiple={props.multiple} getUsersByUsername={getUsersByUsername} />
453
- }
454
-
455
- return h(DtUserDept, {
456
- 'type': 'user',
457
- 'users': users.value,
458
- 'depts': depts.value,
459
- 'groups': groups.value,
460
- getUsersByDept,
461
- getUsersByGroup,
462
- ...props,
463
- ...params,
464
- modelValue,
465
- 'onUpdate:modelValue': onUpdateValue,
466
- }, slots)
467
- }
468
- },
469
- }
470
- }
471
-
472
- export function createPageTableHelper({ getDeptsByCode, getUsersByUsername, getFileInfos, previewFileUrl }) {
473
- const getFormatter = (defaultFormatter) => {
474
- return () => (value, record, index, params) => {
475
- if (value === undefined || value === null) return
476
- return format(value, params.formatter ?? defaultFormatter)
477
- }
478
- }
479
-
480
- const IDot = (props = {}) => (
481
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32" {...props}>
482
- {/* Icon from Carbon by IBM - undefined */}
483
- <circle cx="16" cy="16" r="8" fill="currentColor" />
484
- </svg>
485
- )
486
-
487
- return {
488
- date: getFormatter('yyyy-MM-dd'),
489
- datetime: getFormatter('yyyy-MM-dd HH:mm:ss'),
490
- dict: () => {
491
- let dictType0, options0, optionMap
492
- return (value, record, index, params) => {
493
- if (value === undefined || value === null) return
494
- const { dictType, options, multiple, statusMap } = mapProps(params)
495
- if (options) {
496
- if (options0 !== options) {
497
- options0 = options
498
- optionMap = new Map(options.map(op => [op[params.valueField || 'value'], op]))
499
- }
500
- } else {
501
- if (dictType0 !== dictType) {
502
- dictType0 = dictType
503
- if (!optionMap && dictType0) {
504
- optionMap = useDictMap(dictType0)
505
- }
506
- }
507
- }
508
- if (!multiple) {
509
- value = value.toString()
510
- if (statusMap && value in statusMap) {
511
- let status = statusMap[value] ?? 'default'
512
- if (['primary', 'success', 'warning', 'danger'].includes(status)) {
513
- status = `var(--color-${status})`
514
- }
515
- return (
516
- <span style="position: relative; padding-left: 1.25em">
517
- <IDot style={`color: ${status}; position: absolute;left: 0; top: 1.5px`} />
518
- <span>{optionMap.get(value?.toString())?.[params.labelField || 'label'] ?? ''}</span>
519
- </span>
520
- )
521
- }
522
- return optionMap.get(value)?.[params.labelField || 'label'] ?? ''
523
- }
524
- return value?.map(it => optionMap.get(it.toString())?.[params.labelField || 'label']) ?? ''
525
- }
526
- },
527
- number: () => {
528
- return (value, record, index, params) => {
529
- if (value === undefined || value === null) return
530
- if (params.percent) {
531
- value = Number(value) * 100
532
- }
533
- switch ('number') {
534
- case typeof params.fixed: {
535
- value = value.toFixed(params.fixed)
536
- break
537
- }
538
- case typeof params.round: {
539
- value = value.toFixed(params.round).replace(/0+$/, '')
540
- break
541
- }
542
- case typeof params.precision: {
543
- value = value.toPrecision(params.precision)
544
- break
545
- }
546
- }
547
- return params?.separator ? Number(value).toLocaleString() : value
548
- }
549
- },
550
- email: () => {
551
- return (value) => {
552
- return <a href={`mailto:${value}`}>{value}</a>
553
- }
554
- },
555
- url: () => {
556
- return (value) => {
557
- return <a href={value}>{value}</a>
558
- }
559
- },
560
- color: () => {
561
- return (value) => {
562
- return <NColorPicker value={value} disabled size="small" />
563
- }
564
- },
565
- image: () => {
566
- return (value, record, index, params) => {
567
- if (!value) return
568
- const urls = (Array.isArray(value) ? value : (params?.multiple ? value.split(',') : [value]))
569
- .map(id => previewFileUrl(id))
570
- return (
571
- <NFlex gap="8" wrap>
572
- {urls.map(url => (
573
- <img key={url} src={url} style="max-height: 32px; max-width: 100px; object-fit: contain" />
574
- ))}
575
- </NFlex>
576
- )
577
- }
578
- },
579
- file: () => {
580
- const key = nanoid()
581
- return (value, record, index, params) => {
582
- if (!value) return
583
- record.__file_urls ??= {}
584
- if (!record.__file_urls[key]) {
585
- getFileInfos(Array.isArray(value) ? value : (params?.multiple ? value.split(',') : [value]))
586
- .then((infos) => {
587
- record.__file_urls[key] = infos
588
- })
589
- }
590
- const infos = record.__file_urls[key] || []
591
-
592
- return (
593
- <NFlex gap="8" wrap>
594
- {infos.map(it => (
595
- <a
596
- key={it.id}
597
- href={it.url}
598
- target="_blank"
599
- rel="noreferrer"
600
- style="max-width: 100px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; display: inline-block"
601
- >
602
- {it.name}
603
- </a>
604
- ))}
605
- </NFlex>
606
- )
607
- }
608
- },
609
- dept: () => {
610
- return (value, record, index, params) => {
611
- if (!value) return
612
- return <DtDeptRender value={value} multiple={params?.multiple} getDeptsByCode={getDeptsByCode} />
613
- }
614
- },
615
- user: () => {
616
- return (value, record, index, params) => {
617
- if (!value) return
618
- return <DtUserRender value={value} multiple={params?.multiple} getUsersByUsername={getUsersByUsername} />
619
- }
620
- },
621
- }
622
- }
623
-
624
- export function createFormHelper() {
625
- return () => ({ items, model, handleSubmit, reset, validation, readonly, inModal, showColon }) => {
626
- return (
627
- <DataForm
628
- readonly={readonly}
629
- model={model}
630
- items={items}
631
- validation={validation}
632
- showColon={unref(showColon) ?? true}
633
- showAction={false}
634
- onSubmit={handleSubmit}
635
- onRest={reset}
636
- style={inModal ? 'padding-right: 2rem; padding-top: 1rem' : undefined}
637
- />
638
- )
639
- }
640
- }
641
-
642
- export function createModalHelper() {
643
- const formatLength = (length) => {
644
- if (typeof length === 'number') {
645
- return `${length}px`
646
- }
647
- return length
648
- }
649
- const contentStyle0 = {
650
- maxHeight: 'calc(100vh - 130px)',
651
- display: 'flex',
652
- flexDirection: 'column',
653
- }
654
-
655
- const segmented = { content: true }
656
- return () => ({
657
- type = 'dialog', visible, title, content, footer, placement, resizable, draggable, closeOnEsc, closable,
658
- showMask, maskClosable, width, height, style, onClose, onCancel, onConfirm, onAfterClose, onAfterOpen,
659
- confirmText, confirmDisabled, confirmLoading, cancelText, cancelDisabled, cancelLoading, nativeScrollbar, ...options
660
- }) => {
661
- const footer0 = footer
662
- ? () => footer
663
- : footer === null
664
- ? null
665
- : () => (
666
- <NFlex justify="end" gap="16">
667
- {cancelText === null ? undefined : <NButton onClick={onCancel} disabled={cancelDisabled} loading={cancelLoading} style="min-width: 60px">{cancelText}</NButton>}
668
- {confirmText === null ? undefined : <NButton type="primary" onClick={onConfirm} disabled={confirmDisabled} loading={confirmLoading} style="min-width: 60px">{confirmText}</NButton>}
669
- </NFlex>
670
- )
671
- if (type === 'dialog') {
672
- const { style: style0 } = mergeProps(
673
- { style: { width: formatLength(width ?? 520), height: formatLength(height) } },
674
- { style },
675
- )
676
- return (
677
- <NModal
678
- show={visible}
679
- preset="card"
680
- title={() => title}
681
- maskClosable={maskClosable ?? false}
682
- closeOnEsc={closeOnEsc}
683
- closable={closable}
684
- onClose={onClose}
685
- segmented={segmented}
686
- size="small"
687
- onAfterEnter={onAfterOpen}
688
- onAfterLeave={onAfterClose}
689
- onUpdateShow={onClose}
690
- draggable={draggable ?? true}
691
- style={style0}
692
- contentStyle={contentStyle0}
693
- {...options}
694
- >
695
- {{
696
- default: () => (
697
- <NScrollbar abstract style="display: flex; flex-direction: column">
698
- {content}
699
- </NScrollbar>
700
- ),
701
- action: footer0,
702
- }}
703
- </NModal>
704
- )
705
- }
706
-
707
- const { bodyContentClass, bodyContentStyle, ...options2 } = options
708
- return (
709
- <NDrawer
710
- show={visible}
711
- trapFocus={false}
712
- closeOnEsc={closeOnEsc}
713
- showMask={showMask}
714
- maskClosable={maskClosable}
715
- resizable={resizable}
716
- placement={placement}
717
- width={width ?? 440}
718
- height={height}
719
- onUpdateShow={onClose}
720
- onAfterEnter={onAfterOpen}
721
- onAfterLeave={onAfterClose}
722
- style={style}
723
- {...options2}
724
- >
725
- <NDrawerContent
726
- closable={closable}
727
- nativeScrollbar={nativeScrollbar ?? false}
728
- bodyContentClass={bodyContentClass}
729
- bodyContentStyle={bodyContentStyle}
730
- >
731
- {{
732
- default: () => content,
733
- header: () => title,
734
- footer: footer0,
735
- }}
736
- </NDrawerContent>
737
- </NDrawer>
738
- )
739
- }
740
- }