@veltra/desktop 1.1.31 → 1.1.33
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/dist/components/action/action-group.vue.d.ts +1 -1
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +1 -1
- package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
- package/dist/components/contextmenu/api.d.ts +8 -0
- package/dist/components/{context-menu → contextmenu}/api.js +2 -2
- package/dist/components/contextmenu/api.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-item.js +64 -0
- package/dist/components/contextmenu/contextmenu-item.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-panel.js +33 -0
- package/dist/components/contextmenu/contextmenu-panel.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-sub.js +83 -0
- package/dist/components/contextmenu/contextmenu-sub.js.map +1 -0
- package/dist/components/contextmenu/contextmenu.js +79 -0
- package/dist/components/contextmenu/contextmenu.js.map +1 -0
- package/dist/components/{context-menu/context-menu.vue.d.ts → contextmenu/contextmenu.vue.d.ts} +5 -5
- package/dist/components/contextmenu/di.js +7 -0
- package/dist/components/contextmenu/di.js.map +1 -0
- package/dist/components/contextmenu/helper.js +8 -0
- package/dist/components/contextmenu/helper.js.map +1 -0
- package/dist/components/contextmenu/index.d.ts +2 -0
- package/dist/components/contextmenu/style2.css +154 -0
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
- package/dist/components/file-viewer/previewers/sheet-previewer.js +33 -93
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
- package/dist/components/file-viewer/sheet-parser.js +46 -0
- package/dist/components/file-viewer/sheet-parser.js.map +1 -0
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/number/number.vue.d.ts +1 -1
- package/dist/components/table/node/col.d.ts +5 -0
- package/dist/components/table/node/col.js +6 -0
- package/dist/components/table/node/col.js.map +1 -1
- package/dist/components/table/use-col-resize.js +10 -10
- package/dist/components/table/use-col-resize.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/style.js +1 -1
- package/dist/types/{context-menu.d.ts → contextmenu.d.ts} +12 -10
- package/dist/types/index.d.ts +2 -2
- package/package.json +6 -6
- package/src/components/{context-menu → contextmenu}/api.ts +4 -4
- package/src/components/contextmenu/contextmenu-item.vue +63 -0
- package/src/components/contextmenu/contextmenu-panel.vue +28 -0
- package/src/components/contextmenu/contextmenu-sub.vue +88 -0
- package/src/components/contextmenu/contextmenu.vue +77 -0
- package/src/components/contextmenu/di.ts +13 -0
- package/src/components/contextmenu/helper.ts +5 -0
- package/src/components/contextmenu/index.ts +3 -0
- package/src/components/contextmenu/style.scss +135 -0
- package/src/components/file-viewer/previewers/sheet-previewer.vue +35 -131
- package/src/components/file-viewer/sheet-parser.ts +52 -0
- package/src/components/index.ts +1 -1
- package/src/components/table/node/col.ts +7 -0
- package/src/components/table/use-col-resize.ts +18 -16
- package/src/style.ts +1 -1
- package/src/types/{context-menu.ts → contextmenu.ts} +9 -7
- package/src/types/index.ts +1 -1
- package/dist/components/context-menu/api.d.ts +0 -8
- package/dist/components/context-menu/api.js.map +0 -1
- package/dist/components/context-menu/context-menu-item.js +0 -60
- package/dist/components/context-menu/context-menu-item.js.map +0 -1
- package/dist/components/context-menu/context-menu.js +0 -95
- package/dist/components/context-menu/context-menu.js.map +0 -1
- package/dist/components/context-menu/di.js +0 -6
- package/dist/components/context-menu/di.js.map +0 -1
- package/dist/components/context-menu/index.d.ts +0 -2
- package/dist/components/context-menu/style2.css +0 -52
- package/src/components/context-menu/context-menu-item.vue +0 -67
- package/src/components/context-menu/context-menu.vue +0 -119
- package/src/components/context-menu/di.ts +0 -5
- package/src/components/context-menu/index.ts +0 -3
- package/src/components/context-menu/style.scss +0 -51
- /package/dist/components/{context-menu → contextmenu}/style.d.ts +0 -0
- /package/dist/components/{context-menu → contextmenu}/style.js +0 -0
- /package/src/components/{context-menu → contextmenu}/style.ts +0 -0
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
|
|
21
21
|
<script lang="ts" setup>
|
|
22
22
|
import { bem } from '@veltra/utils'
|
|
23
|
+
import { ListTable } from '@visactor/vtable'
|
|
23
24
|
import { onBeforeUnmount, ref, shallowRef, useTemplateRef, watch } from 'vue'
|
|
24
25
|
|
|
25
26
|
import type { FileViewerItem } from '../../../types/file-viewer'
|
|
27
|
+
import { parseSheetFile, type SheetPreview } from '../sheet-parser'
|
|
26
28
|
|
|
27
29
|
defineOptions({ name: 'FileViewerSheetPreviewer' })
|
|
28
30
|
|
|
@@ -33,73 +35,53 @@ const props = withDefaults(defineProps<{ file: FileViewerItem; maxRows?: number
|
|
|
33
35
|
const emit = defineEmits<{ (e: 'error', err: unknown): void }>()
|
|
34
36
|
|
|
35
37
|
const cls = bem('file-viewer')
|
|
36
|
-
|
|
37
38
|
const container = useTemplateRef<HTMLDivElement>('container')
|
|
38
39
|
const loading = ref(true)
|
|
39
40
|
const truncated = ref(false)
|
|
40
41
|
const totalRows = ref(0)
|
|
41
42
|
const renderedRows = ref(0)
|
|
42
|
-
|
|
43
|
-
interface SheetData {
|
|
44
|
-
name: string
|
|
45
|
-
headers: string[]
|
|
46
|
-
rows: string[][]
|
|
47
|
-
totalCount: number
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const sheets = shallowRef<SheetData[]>([])
|
|
43
|
+
const sheets = shallowRef<SheetPreview[]>([])
|
|
51
44
|
const activeSheetIndex = ref(0)
|
|
52
45
|
|
|
53
46
|
let controller: AbortController | undefined
|
|
54
|
-
let
|
|
47
|
+
let table: ListTable | undefined
|
|
55
48
|
let resizeObserver: ResizeObserver | undefined
|
|
56
49
|
|
|
50
|
+
function releaseTable() {
|
|
51
|
+
table?.release()
|
|
52
|
+
table = undefined
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function renderActive() {
|
|
56
|
+
const sheet = sheets.value[activeSheetIndex.value]
|
|
57
|
+
const el = container.value
|
|
58
|
+
if (!sheet || !el) return
|
|
59
|
+
|
|
60
|
+
releaseTable()
|
|
61
|
+
|
|
62
|
+
const limit = props.maxRows > 0 ? Math.min(props.maxRows, sheet.rows.length) : sheet.rows.length
|
|
63
|
+
totalRows.value = sheet.rows.length
|
|
64
|
+
renderedRows.value = limit
|
|
65
|
+
truncated.value = props.maxRows > 0 && sheet.rows.length > props.maxRows
|
|
66
|
+
|
|
67
|
+
table = new ListTable(el, {
|
|
68
|
+
records: sheet.rows.slice(0, limit),
|
|
69
|
+
columns: sheet.headers.map((title, i) => ({ field: String(i), title, width: 'auto' })),
|
|
70
|
+
widthMode: 'standard'
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
57
74
|
async function load() {
|
|
58
75
|
controller?.abort()
|
|
59
76
|
controller = new AbortController()
|
|
60
|
-
const signal = controller.signal
|
|
61
77
|
loading.value = true
|
|
62
78
|
sheets.value = []
|
|
63
79
|
activeSheetIndex.value = 0
|
|
64
80
|
|
|
65
81
|
try {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (signal.aborted) return
|
|
70
|
-
|
|
71
|
-
if (ext === 'csv') {
|
|
72
|
-
const text = new TextDecoder('utf-8', { fatal: false }).decode(buf)
|
|
73
|
-
const parsed = parseCsv(text).filter((row) => row.some((c) => c.length > 0))
|
|
74
|
-
const headers = parsed[0] ?? []
|
|
75
|
-
const rows = parsed.slice(1)
|
|
76
|
-
sheets.value = [
|
|
77
|
-
{
|
|
78
|
-
name: props.file.name,
|
|
79
|
-
headers: headers.map((h, i) => String(h) || `Column ${i + 1}`),
|
|
80
|
-
rows,
|
|
81
|
-
totalCount: rows.length
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
} else {
|
|
85
|
-
const { readWorkbook } = await import('@cat-kit/excel')
|
|
86
|
-
const workbook = await readWorkbook(new Uint8Array(buf))
|
|
87
|
-
if (signal.aborted) return
|
|
88
|
-
sheets.value = workbook.worksheets.map((ws) => {
|
|
89
|
-
const wsRows = ws.getRows()
|
|
90
|
-
const firstRow = wsRows[0]
|
|
91
|
-
const headers = firstRow ? firstRow.toValues().map((v) => cellToString(v)) : []
|
|
92
|
-
const rows = wsRows.slice(1).map((r) => r.toValues().map(cellToString))
|
|
93
|
-
return {
|
|
94
|
-
name: ws.name,
|
|
95
|
-
headers: headers.map((h, i) => h || `Column ${i + 1}`),
|
|
96
|
-
rows,
|
|
97
|
-
totalCount: rows.length
|
|
98
|
-
}
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
await renderActive()
|
|
82
|
+
sheets.value = await parseSheetFile(props.file, controller.signal)
|
|
83
|
+
if (controller.signal.aborted) return
|
|
84
|
+
renderActive()
|
|
103
85
|
} catch (err) {
|
|
104
86
|
if ((err as { name?: string })?.name === 'AbortError') return
|
|
105
87
|
emit('error', err)
|
|
@@ -108,97 +90,19 @@ async function load() {
|
|
|
108
90
|
}
|
|
109
91
|
}
|
|
110
92
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (typeof v === 'string') return v
|
|
114
|
-
if (typeof v === 'number' || typeof v === 'boolean') return String(v)
|
|
115
|
-
if (v instanceof Date) return v.toLocaleString()
|
|
116
|
-
if (typeof v === 'object' && v !== null && 'formula' in v) {
|
|
117
|
-
const f = v as { formula: string; result?: unknown }
|
|
118
|
-
if (f.result !== undefined && f.result !== null) return cellToString(f.result)
|
|
119
|
-
return `=${f.formula}`
|
|
120
|
-
}
|
|
121
|
-
return String(v)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async function renderActive() {
|
|
125
|
-
const sheet = sheets.value[activeSheetIndex.value]
|
|
126
|
-
if (!sheet || !container.value) return
|
|
127
|
-
|
|
128
|
-
releaseInstance()
|
|
129
|
-
|
|
130
|
-
const limit = props.maxRows > 0 ? Math.min(props.maxRows, sheet.rows.length) : sheet.rows.length
|
|
131
|
-
totalRows.value = sheet.totalCount
|
|
132
|
-
renderedRows.value = limit
|
|
133
|
-
truncated.value = props.maxRows > 0 && sheet.rows.length > props.maxRows
|
|
134
|
-
|
|
135
|
-
const columns = sheet.headers.map((h, i) => ({
|
|
136
|
-
field: 'c' + i,
|
|
137
|
-
title: h,
|
|
138
|
-
width: 'auto' as const
|
|
139
|
-
}))
|
|
140
|
-
|
|
141
|
-
const records: Record<string, string>[] = []
|
|
142
|
-
for (let i = 0; i < limit; i++) {
|
|
143
|
-
const row = sheet.rows[i]
|
|
144
|
-
if (!row) continue
|
|
145
|
-
const record: Record<string, string> = {}
|
|
146
|
-
for (let j = 0; j < columns.length; j++) {
|
|
147
|
-
record['c' + j] = row[j] ?? ''
|
|
148
|
-
}
|
|
149
|
-
records.push(record)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const VTable = await import('@visactor/vtable')
|
|
153
|
-
if (!container.value) return
|
|
154
|
-
|
|
155
|
-
instance = new VTable.ListTable(container.value, {
|
|
156
|
-
records,
|
|
157
|
-
columns,
|
|
158
|
-
widthMode: 'standard',
|
|
159
|
-
heightMode: 'standard',
|
|
160
|
-
defaultRowHeight: 32,
|
|
161
|
-
defaultHeaderRowHeight: 36,
|
|
162
|
-
autoFillWidth: true,
|
|
163
|
-
frozenColCount: 0,
|
|
164
|
-
theme: (VTable.themes.ARCO ?? VTable.themes.DEFAULT).extends({
|
|
165
|
-
defaultStyle: { borderLineWidth: 1 }
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function releaseInstance() {
|
|
171
|
-
if (instance && typeof instance.release === 'function') {
|
|
172
|
-
try {
|
|
173
|
-
instance.release()
|
|
174
|
-
} catch {
|
|
175
|
-
/* noop */
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
instance = undefined
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
watch(
|
|
182
|
-
() => props.file,
|
|
183
|
-
() => load(),
|
|
184
|
-
{ immediate: true }
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
watch(activeSheetIndex, () => renderActive())
|
|
188
|
-
|
|
93
|
+
watch(() => props.file, load, { immediate: true })
|
|
94
|
+
watch(activeSheetIndex, renderActive)
|
|
189
95
|
watch(container, (el) => {
|
|
190
96
|
resizeObserver?.disconnect()
|
|
191
97
|
if (!el) return
|
|
192
|
-
resizeObserver = new ResizeObserver(() =>
|
|
193
|
-
instance?.resize?.()
|
|
194
|
-
})
|
|
98
|
+
resizeObserver = new ResizeObserver(() => table?.resize?.())
|
|
195
99
|
resizeObserver.observe(el)
|
|
196
100
|
})
|
|
197
101
|
|
|
198
102
|
onBeforeUnmount(() => {
|
|
199
103
|
controller?.abort()
|
|
200
104
|
resizeObserver?.disconnect()
|
|
201
|
-
|
|
105
|
+
releaseTable()
|
|
202
106
|
sheets.value = []
|
|
203
107
|
})
|
|
204
108
|
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readWorkbook } from '@cat-kit/excel'
|
|
2
|
+
|
|
3
|
+
import type { FileViewerItem } from '../../types/file-viewer'
|
|
4
|
+
import { getExtension, parseCsv, toArrayBuffer } from './helper'
|
|
5
|
+
|
|
6
|
+
export interface SheetPreview {
|
|
7
|
+
name: string
|
|
8
|
+
headers: string[]
|
|
9
|
+
rows: string[][]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function cellToString(v: unknown): string {
|
|
13
|
+
if (v == null) return ''
|
|
14
|
+
if (typeof v === 'string') return v
|
|
15
|
+
if (typeof v === 'number' || typeof v === 'boolean') return String(v)
|
|
16
|
+
if (v instanceof Date) return v.toLocaleString()
|
|
17
|
+
if (typeof v === 'object' && 'formula' in v) {
|
|
18
|
+
const f = v as { formula: string; result?: unknown }
|
|
19
|
+
return f.result != null ? cellToString(f.result) : `=${f.formula}`
|
|
20
|
+
}
|
|
21
|
+
return JSON.stringify(v)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 解析 CSV / Excel 为表格预览数据 */
|
|
25
|
+
export async function parseSheetFile(
|
|
26
|
+
file: FileViewerItem,
|
|
27
|
+
signal?: AbortSignal
|
|
28
|
+
): Promise<SheetPreview[]> {
|
|
29
|
+
const ext = getExtension(file.name)
|
|
30
|
+
const buf = await toArrayBuffer(file.src, signal)
|
|
31
|
+
if (signal?.aborted) return []
|
|
32
|
+
|
|
33
|
+
if (ext === 'csv') {
|
|
34
|
+
const text = new TextDecoder('utf-8', { fatal: false }).decode(buf)
|
|
35
|
+
const parsed = parseCsv(text).filter((row) => row.some((c) => c.length > 0))
|
|
36
|
+
const headers = (parsed[0] ?? []).map((h, i) => String(h) || `Column ${i + 1}`)
|
|
37
|
+
return [{ name: file.name, headers, rows: parsed.slice(1) }]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const workbook = await readWorkbook(new Uint8Array(buf))
|
|
41
|
+
if (signal?.aborted) return []
|
|
42
|
+
|
|
43
|
+
return workbook.worksheets.map((ws) => {
|
|
44
|
+
const wsRows = ws.getRows()
|
|
45
|
+
const firstRow = wsRows[0]
|
|
46
|
+
const headers = (firstRow ? firstRow.toValues().map(cellToString) : []).map(
|
|
47
|
+
(h, i) => h || `Column ${i + 1}`
|
|
48
|
+
)
|
|
49
|
+
const rows = wsRows.slice(1).map((r) => r.toValues().map(cellToString))
|
|
50
|
+
return { name: ws.name, headers, rows }
|
|
51
|
+
})
|
|
52
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -94,9 +94,16 @@ export class ColumnNode extends TreeNode<TableColumn, ColumnNode> {
|
|
|
94
94
|
return this.data.resizable ?? true
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* 是否在列配置上显式指定了 width,或经表头拖拽锁定。
|
|
99
|
+
* 此类列不参与剩余宽度的均分。
|
|
100
|
+
*/
|
|
101
|
+
explicitWidth: boolean
|
|
102
|
+
|
|
97
103
|
style: Record<string, number> = reactive({})
|
|
98
104
|
|
|
99
105
|
constructor(val: TableColumn, index: number, depth: number, parent?: ColumnNode) {
|
|
100
106
|
super(isReactive(val) ? val : shallowReactive(val), index, depth, parent)
|
|
107
|
+
this.explicitWidth = val.width !== undefined
|
|
101
108
|
}
|
|
102
109
|
}
|
|
@@ -34,22 +34,23 @@ export function useColResize(options: Options): UseColResizeReturned {
|
|
|
34
34
|
|
|
35
35
|
if (!containerWidth || !leafColumns.value.length) return
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
const flexColumns = leafColumns.value.filter((column) => !column.explicitWidth)
|
|
38
|
+
const fixedWidthTotal = leafColumns.value
|
|
39
|
+
.filter((column) => column.explicitWidth)
|
|
40
|
+
.reduce((acc, cur) => acc + (cur.width ?? cur.minWidth!), 0)
|
|
41
|
+
const flexBaseTotal = flexColumns.reduce((acc, cur) => acc + cur.minWidth!, 0)
|
|
42
|
+
const totalBase = fixedWidthTotal + flexBaseTotal
|
|
43
|
+
|
|
44
|
+
// 仅未显式指定 width 的列参与剩余宽度均分;指定了 width 的列保持该宽度。
|
|
45
|
+
if (flexColumns.length > 0 && totalBase < containerWidth) {
|
|
46
|
+
const allocatedWidth = (containerWidth - totalBase) / flexColumns.length
|
|
47
|
+
|
|
48
|
+
flexColumns.forEach((column) => {
|
|
49
|
+
column.width = column.minWidth! + allocatedWidth
|
|
50
|
+
})
|
|
51
|
+
} else {
|
|
52
|
+
flexColumns.forEach((column) => {
|
|
53
|
+
column.data.width = undefined
|
|
53
54
|
})
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -110,6 +111,7 @@ export function useColResize(options: Options): UseColResizeReturned {
|
|
|
110
111
|
originWidth + e.pageX - originX,
|
|
111
112
|
currentResizeColumn!.minWidth!
|
|
112
113
|
)
|
|
114
|
+
currentResizeColumn!.explicitWidth = true
|
|
113
115
|
|
|
114
116
|
showResizeLine.value = false
|
|
115
117
|
currentResizeColumn = null
|
package/src/style.ts
CHANGED
|
@@ -13,7 +13,7 @@ import './components/checkbox/style'
|
|
|
13
13
|
import './components/code-editor/style'
|
|
14
14
|
import './components/collapse/style'
|
|
15
15
|
import './components/condition-editor/style'
|
|
16
|
-
import './components/
|
|
16
|
+
import './components/contextmenu/style'
|
|
17
17
|
import './components/date-panel/style'
|
|
18
18
|
import './components/date-picker/style'
|
|
19
19
|
import './components/date-range-picker/style'
|
|
@@ -4,21 +4,23 @@ import type { Component } from 'vue'
|
|
|
4
4
|
/**
|
|
5
5
|
* 右键菜单项
|
|
6
6
|
*/
|
|
7
|
-
export interface
|
|
7
|
+
export interface ContextmenuItem {
|
|
8
8
|
/** 菜单名称 */
|
|
9
9
|
label: string
|
|
10
10
|
/** 菜单描述 */
|
|
11
11
|
description?: string
|
|
12
12
|
/** 菜单图标 */
|
|
13
13
|
icon?: Component
|
|
14
|
+
/** 子菜单 */
|
|
15
|
+
children?: ContextmenuItem[]
|
|
14
16
|
/** 菜单点击时的回调 */
|
|
15
|
-
callback?: () =>
|
|
17
|
+
callback?: () => any
|
|
16
18
|
/** 是否禁用 */
|
|
17
19
|
disabled?: boolean | (() => boolean)
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/** 鼠标右键菜单组件属性 */
|
|
21
|
-
export interface
|
|
23
|
+
export interface ContextmenuProps extends ComponentProps {
|
|
22
24
|
/** 鼠标位置 */
|
|
23
25
|
mousePosition: { x: number; y: number }
|
|
24
26
|
/**
|
|
@@ -27,16 +29,16 @@ export interface ContextMenuProps extends ComponentProps {
|
|
|
27
29
|
*/
|
|
28
30
|
width?: number | string
|
|
29
31
|
/** 菜单项 */
|
|
30
|
-
menus:
|
|
32
|
+
menus: ContextmenuItem[] | (() => ContextmenuItem[])
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
/** 鼠标右键菜单组件定义的事件 */
|
|
34
|
-
export interface
|
|
36
|
+
export interface ContextmenuEmits {
|
|
35
37
|
(e: 'destroy'): void
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/** 鼠标右键菜单组件暴露的属性和方法(组件内部使用) */
|
|
39
|
-
export interface
|
|
41
|
+
export interface _ContextmenuExposed {}
|
|
40
42
|
|
|
41
43
|
/** 鼠标右键菜单组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
42
|
-
export type
|
|
44
|
+
export type ContextmenuExposed = DeconstructValue<_ContextmenuExposed>
|
package/src/types/index.ts
CHANGED
|
@@ -51,7 +51,7 @@ export * from './menu'
|
|
|
51
51
|
export * from './password-input'
|
|
52
52
|
export * from './date-picker'
|
|
53
53
|
export * from './dropdown'
|
|
54
|
-
export * from './
|
|
54
|
+
export * from './contextmenu'
|
|
55
55
|
export * from './select'
|
|
56
56
|
export * from './radio'
|
|
57
57
|
export * from './checkbox'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":["MContextMenu"],"sources":["../../../src/components/context-menu/api.ts"],"sourcesContent":["import { createVNode, render, type VNode } from 'vue'\n\nimport type { ContextMenuProps } from '../../types'\nimport MContextMenu from './context-menu.vue'\n\nlet node: VNode\n\nexport const contextmenu = {\n pop(options: ContextMenuProps): void {\n if (node) {\n render(null, document.body)\n }\n\n node = createVNode(MContextMenu, {\n ...options,\n onDestroy() {\n render(null, document.body)\n }\n })\n\n render(node, document.body)\n }\n}\n"],"mappings":";;;AAKA,IAAI;AAEJ,MAAa,cAAc,EACzB,IAAI,SAAiC;CACnC,IAAI,MACF,OAAO,MAAM,SAAS,IAAI;CAG5B,OAAO,YAAYA,WAAc;EAC/B,GAAG;EACH,YAAY;GACV,OAAO,MAAM,SAAS,IAAI;EAC5B;CACF,CAAC;CAED,OAAO,MAAM,SAAS,IAAI;AAC5B,EACF"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import _sfc_main$1 from "../icon/icon.js";
|
|
2
|
-
import { ContextMenuDIKey } from "./di.js";
|
|
3
|
-
import { Fragment, computed, createBlock, createElementBlock, createElementVNode, createVNode, defineComponent, inject, normalizeClass, openBlock, resolveDynamicComponent, shallowRef, toDisplayString, unref, withCtx, withDirectives } from "vue";
|
|
4
|
-
import { bem } from "@veltra/utils";
|
|
5
|
-
import { Loading } from "@veltra/icons/normal";
|
|
6
|
-
import { vRipple } from "@veltra/directives";
|
|
7
|
-
//#region src/components/context-menu/context-menu-item.vue
|
|
8
|
-
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
9
|
-
name: "ContextMenuItem",
|
|
10
|
-
__name: "context-menu-item",
|
|
11
|
-
props: { menu: {} },
|
|
12
|
-
emits: ["click-start", "click-end"],
|
|
13
|
-
setup(__props, { emit: __emit }) {
|
|
14
|
-
const emit = __emit;
|
|
15
|
-
const { cls } = inject(ContextMenuDIKey);
|
|
16
|
-
const loading = shallowRef(false);
|
|
17
|
-
const disabled = computed(() => {
|
|
18
|
-
return (typeof __props.menu.disabled === "function" ? __props.menu.disabled() : __props.menu.disabled) ?? false;
|
|
19
|
-
});
|
|
20
|
-
function handleClickMenu() {
|
|
21
|
-
if (disabled.value || loading.value) return;
|
|
22
|
-
emit("click-start");
|
|
23
|
-
loading.value = true;
|
|
24
|
-
const result = __props.menu.callback?.();
|
|
25
|
-
if (result instanceof Promise) return result.then(() => {}).finally(() => {
|
|
26
|
-
emit("click-end");
|
|
27
|
-
loading.value = false;
|
|
28
|
-
});
|
|
29
|
-
loading.value = false;
|
|
30
|
-
emit("click-end");
|
|
31
|
-
}
|
|
32
|
-
return (_ctx, _cache) => {
|
|
33
|
-
return withDirectives((openBlock(), createElementBlock("li", {
|
|
34
|
-
class: normalizeClass([
|
|
35
|
-
unref(cls).e("item"),
|
|
36
|
-
unref(bem).is("disabled", disabled.value),
|
|
37
|
-
unref(bem).is("loading", loading.value),
|
|
38
|
-
unref(cls).em("item", "menu")
|
|
39
|
-
]),
|
|
40
|
-
onClick: handleClickMenu
|
|
41
|
-
}, [loading.value ? (openBlock(), createBlock(unref(_sfc_main$1), {
|
|
42
|
-
key: 0,
|
|
43
|
-
class: normalizeClass(unref(bem).is("loading"))
|
|
44
|
-
}, {
|
|
45
|
-
default: withCtx(() => [createVNode(unref(Loading))]),
|
|
46
|
-
_: 1
|
|
47
|
-
}, 8, ["class"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [__props.menu.icon ? (openBlock(), createBlock(unref(_sfc_main$1), { key: 0 }, {
|
|
48
|
-
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(__props.menu.icon)))]),
|
|
49
|
-
_: 1
|
|
50
|
-
})) : (openBlock(), createElementBlock("i", {
|
|
51
|
-
key: 1,
|
|
52
|
-
class: normalizeClass(unref(cls).e("icon-place"))
|
|
53
|
-
}, null, 2))], 64)), createElementVNode("span", { class: normalizeClass(unref(cls).e("label")) }, toDisplayString(__props.menu.label), 3)], 2)), [[unref(vRipple), !disabled.value && !loading.value]]);
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
//#endregion
|
|
58
|
-
export { _sfc_main as default };
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=context-menu-item.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu-item.js","names":[],"sources":["../../../src/components/context-menu/context-menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('disabled', disabled),\n bem.is('loading', loading),\n cls.em('item', 'menu')\n ]\"\n v-ripple=\"!disabled && !loading\"\n @click=\"handleClickMenu\"\n >\n <u-icon v-if=\"loading\" :class=\"bem.is('loading')\">\n <Loading />\n </u-icon>\n <template v-else>\n <u-icon v-if=\"menu.icon\">\n <component :is=\"menu.icon\" />\n </u-icon>\n <i v-else :class=\"cls.e('icon-place')\"></i>\n </template>\n\n <span :class=\"cls.e('label')\">{{ menu.label }}</span>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef } from 'vue'\n\nimport type { ContextMenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({ name: 'ContextMenuItem' })\n\nconst { menu } = defineProps<{ menu: ContextMenuItem }>()\n\nconst emit = defineEmits<{ (e: 'click-start'): void; (e: 'click-end'): void }>()\n\nconst { cls } = inject(ContextMenuDIKey)!\n\nconst loading = shallowRef(false)\n\nconst disabled = computed(() => {\n return (typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled) ?? false\n})\n\nfunction handleClickMenu() {\n if (disabled.value || loading.value) return\n emit('click-start')\n loading.value = true\n const result = menu.callback?.()\n\n if (result instanceof Promise) {\n return result\n .then(() => {})\n .finally(() => {\n emit('click-end')\n loading.value = false\n })\n }\n loading.value = false\n emit('click-end')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EAuCA,MAAM,OAAO;EAEb,MAAM,EAAE,QAAQ,OAAO,gBAAgB;EAEvC,MAAM,UAAU,WAAW,KAAK;EAEhC,MAAM,WAAW,eAAe;GAC9B,QAAQ,OAAO,QAAA,KAAK,aAAa,aAAa,QAAA,KAAK,SAAS,IAAI,QAAA,KAAK,aAAa;EACpF,CAAC;EAED,SAAS,kBAAkB;GACzB,IAAI,SAAS,SAAS,QAAQ,OAAO;GACrC,KAAK,aAAa;GAClB,QAAQ,QAAQ;GAChB,MAAM,SAAS,QAAA,KAAK,WAAW;GAE/B,IAAI,kBAAkB,SACpB,OAAO,OACJ,WAAW,CAAC,CAAC,EACb,cAAc;IACb,KAAK,WAAW;IAChB,QAAQ,QAAQ;GAClB,CAAC;GAEL,QAAQ,QAAQ;GAChB,KAAK,WAAW;EAClB;;uCAhEE,mBAqBK,MAAA;IApBF,OAAK,eAAA;KAAU,MAAA,GAAA,EAAI,EAAC,MAAA;KAAgB,MAAA,GAAA,EAAI,GAAE,YAAa,SAAA,KAAQ;KAAS,MAAA,GAAA,EAAI,GAAE,WAAY,QAAA,KAAO;KAAS,MAAA,GAAA,EAAI,GAAE,QAAA,MAAA;;IAOhH,SAAO;OAEM,QAAA,SAAA,UAAA,GAAd,YAES,MAAA,WAAA,GAAA;;IAFe,OAAK,eAAE,MAAA,GAAA,EAAI,GAAE,SAAA,CAAA;;2BACxB,CAAX,YAAW,MAAA,OAAA,CAAA,CAAA,CAAA;;qCAEb,mBAKW,UAAA,EAAA,KAAA,EAAA,GAAA,CAJK,QAAA,KAAK,QAAA,UAAA,GAAnB,YAES,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;2BADsB,EAAA,UAAA,GAA7B,YAA6B,wBAAb,QAAA,KAAK,IAAI,CAAA,EAAA,CAAA;;uBAE3B,mBAA2C,KAAA;;IAAhC,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,YAAA,CAAA;wBAGzB,mBAAqD,QAAA,EAA9C,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,OAAA,CAAA,EAAA,GAAA,gBAAc,QAAA,KAAK,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,CAAA,MAAA,OAAA,GAAA,CAbhC,SAAA,SAAQ,CAAK,QAAA,KAAO,CAAA,CAAA"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { ContextMenuDIKey } from "./di.js";
|
|
2
|
-
import _sfc_main$1 from "./context-menu-item.js";
|
|
3
|
-
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, provide, renderList, shallowRef, unref, withCtx, withDirectives } from "vue";
|
|
4
|
-
import { useFallbackProps } from "@veltra/compositions";
|
|
5
|
-
import { bem, withUnit, zIndex } from "@veltra/utils";
|
|
6
|
-
import { vClickOutside } from "@veltra/directives";
|
|
7
|
-
//#region src/components/context-menu/context-menu.vue
|
|
8
|
-
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
9
|
-
name: "ContextMenu",
|
|
10
|
-
__name: "context-menu",
|
|
11
|
-
props: {
|
|
12
|
-
mousePosition: {},
|
|
13
|
-
width: { default: 150 },
|
|
14
|
-
menus: {},
|
|
15
|
-
size: {}
|
|
16
|
-
},
|
|
17
|
-
emits: ["destroy"],
|
|
18
|
-
setup(__props, { emit: __emit }) {
|
|
19
|
-
const props = __props;
|
|
20
|
-
const emit = __emit;
|
|
21
|
-
const { size } = useFallbackProps([props], { size: "default" });
|
|
22
|
-
const cls = bem("context-menu");
|
|
23
|
-
const contextMenuRef = shallowRef();
|
|
24
|
-
const visible = shallowRef(true);
|
|
25
|
-
const computePosition = () => {
|
|
26
|
-
const position = {};
|
|
27
|
-
const { mousePosition } = props;
|
|
28
|
-
const { x, y } = mousePosition;
|
|
29
|
-
if (x > window.innerWidth / 2) position.right = window.innerWidth - x - 1;
|
|
30
|
-
else position.left = x + 1;
|
|
31
|
-
if (y > window.innerHeight / 2) position.bottom = window.innerHeight - y - 1;
|
|
32
|
-
else position.top = y + 1;
|
|
33
|
-
position.transformOrigin = `${position.top ? "top" : "bottom"} ${position.left ? "left" : "right"}`;
|
|
34
|
-
return Object.fromEntries(Object.entries(position).map(([k, v]) => [k, withUnit(v, "px")]));
|
|
35
|
-
};
|
|
36
|
-
const style = computed(() => {
|
|
37
|
-
return {
|
|
38
|
-
width: withUnit(props.width, "px"),
|
|
39
|
-
...computePosition(),
|
|
40
|
-
zIndex: zIndex()
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
const menus = computed(() => {
|
|
44
|
-
const { menus } = props;
|
|
45
|
-
if (typeof menus === "function") return menus();
|
|
46
|
-
return menus;
|
|
47
|
-
});
|
|
48
|
-
const getMenuDisabled = (menu) => {
|
|
49
|
-
return typeof menu.disabled === "function" ? menu.disabled() : menu.disabled;
|
|
50
|
-
};
|
|
51
|
-
function close() {
|
|
52
|
-
visible.value = false;
|
|
53
|
-
}
|
|
54
|
-
let loading = false;
|
|
55
|
-
function handleClickStart() {
|
|
56
|
-
loading = true;
|
|
57
|
-
}
|
|
58
|
-
function handleClickEnd() {
|
|
59
|
-
loading = false;
|
|
60
|
-
close();
|
|
61
|
-
}
|
|
62
|
-
function handleClickOutside() {
|
|
63
|
-
if (loading) return;
|
|
64
|
-
close();
|
|
65
|
-
}
|
|
66
|
-
provide(ContextMenuDIKey, { cls });
|
|
67
|
-
return (_ctx, _cache) => {
|
|
68
|
-
return openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, {
|
|
69
|
-
name: "zoom-in",
|
|
70
|
-
appear: "",
|
|
71
|
-
onAfterLeave: _cache[0] || (_cache[0] = ($event) => emit("destroy"))
|
|
72
|
-
}, {
|
|
73
|
-
default: withCtx(() => [visible.value ? withDirectives((openBlock(), createElementBlock("ul", {
|
|
74
|
-
key: 0,
|
|
75
|
-
class: normalizeClass([unref(cls).b, unref(cls).m(unref(size))]),
|
|
76
|
-
style: normalizeStyle(style.value),
|
|
77
|
-
ref_key: "contextMenuRef",
|
|
78
|
-
ref: contextMenuRef
|
|
79
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(menus.value, (menu) => {
|
|
80
|
-
return openBlock(), createBlock(_sfc_main$1, {
|
|
81
|
-
menu,
|
|
82
|
-
disabled: getMenuDisabled(menu),
|
|
83
|
-
onClickStart: handleClickStart,
|
|
84
|
-
onClickEnd: handleClickEnd
|
|
85
|
-
}, null, 8, ["menu", "disabled"]);
|
|
86
|
-
}), 256))], 6)), [[unref(vClickOutside), handleClickOutside]]) : createCommentVNode("v-if", true)]),
|
|
87
|
-
_: 1
|
|
88
|
-
})]);
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
//#endregion
|
|
93
|
-
export { _sfc_main as default };
|
|
94
|
-
|
|
95
|
-
//# sourceMappingURL=context-menu.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu.js","names":[],"sources":["../../../src/components/context-menu/context-menu.vue"],"sourcesContent":["<template>\n <Teleport to=\"body\">\n <transition name=\"zoom-in\" appear @after-leave=\"emit('destroy')\">\n <ul\n :class=\"[cls.b, cls.m(size)]\"\n :style=\"style\"\n ref=\"contextMenuRef\"\n v-if=\"visible\"\n v-click-outside=\"handleClickOutside\"\n >\n <UContextMenuItem\n v-for=\"menu of menus\"\n :menu=\"menu\"\n :disabled=\"getMenuDisabled(menu)\"\n @click-start=\"handleClickStart\"\n @click-end=\"handleClickEnd\"\n />\n </ul>\n </transition>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { vClickOutside } from '@veltra/directives'\nimport { bem, withUnit, zIndex } from '@veltra/utils'\nimport { computed, provide, shallowRef, type CSSProperties } from 'vue'\n\nimport type {\n ContextMenuEmits,\n ContextMenuItem,\n ContextMenuProps,\n ComponentSize\n} from '../../types'\nimport UContextMenuItem from './context-menu-item.vue'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({ name: 'ContextMenu' })\n\nconst props = withDefaults(defineProps<ContextMenuProps>(), { width: 150 })\n\nconst emit = defineEmits<ContextMenuEmits>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('context-menu')\n\nconst contextMenuRef = shallowRef<HTMLElement>()\n\nconst visible = shallowRef(true)\n\nconst computePosition = () => {\n const position: {\n top?: number\n left?: number\n right?: number\n bottom?: number\n transformOrigin?: string\n } = {}\n\n const { mousePosition } = props\n const { x, y } = mousePosition\n if (x > window.innerWidth / 2) {\n position.right = window.innerWidth - x - 1\n } else {\n position.left = x + 1\n }\n if (y > window.innerHeight / 2) {\n position.bottom = window.innerHeight - y - 1\n } else {\n position.top = y + 1\n }\n\n const positionY = position.top ? 'top' : 'bottom'\n const positionX = position.left ? 'left' : 'right'\n position.transformOrigin = `${positionY} ${positionX}`\n\n return Object.fromEntries(\n Object.entries(position).map(([k, v]) => [k, withUnit(v as number | string | undefined, 'px')])\n ) as CSSProperties\n}\n\nconst style = computed<CSSProperties>(() => {\n return { width: withUnit(props.width, 'px'), ...computePosition(), zIndex: zIndex() }\n})\n\nconst menus = computed(() => {\n const { menus } = props\n if (typeof menus === 'function') {\n return menus()\n }\n return menus\n})\n\nconst getMenuDisabled = (menu: ContextMenuItem) => {\n return typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled\n}\n\nfunction close() {\n visible.value = false\n}\n\nlet loading = false\nfunction handleClickStart() {\n loading = true\n}\n\nfunction handleClickEnd() {\n loading = false\n close()\n}\n\nfunction handleClickOutside() {\n if (loading) return\n close()\n}\n\nprovide(ContextMenuDIKey, { cls })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAuCA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,MAAM,IAAI,cAAc;EAE9B,MAAM,iBAAiB,WAAwB;EAE/C,MAAM,UAAU,WAAW,IAAI;EAE/B,MAAM,wBAAwB;GAC5B,MAAM,WAMF,CAAC;GAEL,MAAM,EAAE,kBAAkB;GAC1B,MAAM,EAAE,GAAG,MAAM;GACjB,IAAI,IAAI,OAAO,aAAa,GAC1B,SAAS,QAAQ,OAAO,aAAa,IAAI;QAEzC,SAAS,OAAO,IAAI;GAEtB,IAAI,IAAI,OAAO,cAAc,GAC3B,SAAS,SAAS,OAAO,cAAc,IAAI;QAE3C,SAAS,MAAM,IAAI;GAKrB,SAAS,kBAAkB,GAFT,SAAS,MAAM,QAAQ,SAED,GADtB,SAAS,OAAO,SAAS;GAG3C,OAAO,OAAO,YACZ,OAAO,QAAQ,QAAQ,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,GAAkC,IAAI,CAAC,CAAC,CAChG;EACF;EAEA,MAAM,QAAQ,eAA8B;GAC1C,OAAO;IAAE,OAAO,SAAS,MAAM,OAAO,IAAI;IAAG,GAAG,gBAAgB;IAAG,QAAQ,OAAO;GAAE;EACtF,CAAC;EAED,MAAM,QAAQ,eAAe;GAC3B,MAAM,EAAE,UAAU;GAClB,IAAI,OAAO,UAAU,YACnB,OAAO,MAAM;GAEf,OAAO;EACT,CAAC;EAED,MAAM,mBAAmB,SAA0B;GACjD,OAAO,OAAO,KAAK,aAAa,aAAa,KAAK,SAAS,IAAI,KAAK;EACtE;EAEA,SAAS,QAAQ;GACf,QAAQ,QAAQ;EAClB;EAEA,IAAI,UAAU;EACd,SAAS,mBAAmB;GAC1B,UAAU;EACZ;EAEA,SAAS,iBAAiB;GACxB,UAAU;GACV,MAAM;EACR;EAEA,SAAS,qBAAqB;GAC5B,IAAI,SAAS;GACb,MAAM;EACR;EAEA,QAAQ,kBAAkB,EAAE,IAAI,CAAC;;uBApH/B,YAkBW,UAAA,EAlBD,IAAG,OAAM,GAAA,CACjB,YAgBa,YAAA;IAhBD,MAAK;IAAU,QAAA;IAAQ,cAAW,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,SAAA;;2BAe7C,CAVG,QAAA,QAAA,gBAAA,UAAA,GAJR,mBAcK,MAAA;;KAbF,OAAK,eAAA,CAAG,MAAA,GAAA,EAAI,GAAG,MAAA,GAAA,EAAI,EAAE,MAAA,IAAA,CAAI,CAAA,CAAA;KACzB,OAAK,eAAE,MAAA,KAAK;cACT;KAAJ,KAAI;0BAIJ,mBAME,UAAA,MAAA,WALe,MAAA,QAAR,SAAI;yBADb,YAME,aAAA;MAJO;MACN,UAAU,gBAAgB,IAAI;MAC9B,cAAa;MACb,YAAW;;6CAPG,kBAAkB,CAAA,CAAA,IAAA,mBAAA,QAAA,IAAA,CAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/context-menu/di.ts"],"sourcesContent":["import type { BEM } from '@veltra/utils'\nimport type { InjectionKey } from 'vue'\n\nexport const ContextMenuDIKey: InjectionKey<{ cls: BEM<'context-menu'> }> =\n Symbol('ContextMenuDIKey')\n"],"mappings":";AAGA,MAAa,mBACX,OAAO,kBAAkB"}
|