vxe-table 4.23.8 → 4.23.9

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 (126) hide show
  1. package/dist/all.esm.js +5715 -3783
  2. package/es/components.d.ts +1 -0
  3. package/es/components.js +2 -7
  4. package/es/grid/src/emits.js +1 -15
  5. package/es/grid/src/grid.js +397 -120
  6. package/es/index.esm.js +1 -0
  7. package/es/index.js +1 -0
  8. package/es/table/module/custom/hook.js +49 -42
  9. package/es/table/module/custom/panel.js +777 -527
  10. package/es/table/module/edit/hook.js +140 -62
  11. package/es/table/module/export/export-panel.js +399 -316
  12. package/es/table/module/export/hook.js +395 -337
  13. package/es/table/module/export/import-panel.js +152 -123
  14. package/es/table/module/filter/hook.js +16 -2
  15. package/es/table/module/filter/panel.js +146 -84
  16. package/es/table/module/keyboard/hook.js +8 -4
  17. package/es/table/module/menu/panel.js +197 -126
  18. package/es/table/render/index.js +151 -98
  19. package/es/table/src/body.js +355 -233
  20. package/es/table/src/cell.js +426 -269
  21. package/es/table/src/columnInfo.js +1 -0
  22. package/es/table/src/footer.js +144 -99
  23. package/es/table/src/group.js +7 -3
  24. package/es/table/src/header.js +229 -172
  25. package/es/table/src/table.js +1503 -1030
  26. package/es/table/src/util.js +15 -19
  27. package/es/toolbar/src/toolbar.js +132 -75
  28. package/es/ui/index.js +1 -1
  29. package/es/ui/src/dom.js +9 -6
  30. package/es/ui/src/log.js +1 -1
  31. package/es/ui/src/utils.d.ts +1 -1
  32. package/lib/components.js +2 -7
  33. package/lib/grid/src/emits.js +1 -15
  34. package/lib/grid/src/grid.js +397 -120
  35. package/lib/index.common.js +1 -0
  36. package/lib/index.js +1 -0
  37. package/lib/index.umd.js +5732 -3800
  38. package/lib/index.umd.min.js +3 -3
  39. package/lib/table/module/custom/hook.js +49 -42
  40. package/lib/table/module/custom/panel.js +777 -527
  41. package/lib/table/module/edit/hook.js +140 -62
  42. package/lib/table/module/export/export-panel.js +399 -316
  43. package/lib/table/module/export/hook.js +395 -337
  44. package/lib/table/module/export/import-panel.js +152 -123
  45. package/lib/table/module/filter/hook.js +16 -2
  46. package/lib/table/module/filter/panel.js +146 -84
  47. package/lib/table/module/keyboard/hook.js +8 -4
  48. package/lib/table/module/menu/panel.js +197 -126
  49. package/lib/table/render/index.js +151 -98
  50. package/lib/table/src/body.js +355 -233
  51. package/lib/table/src/cell.js +426 -269
  52. package/lib/table/src/columnInfo.js +1 -0
  53. package/lib/table/src/footer.js +144 -99
  54. package/lib/table/src/group.js +7 -3
  55. package/lib/table/src/header.js +229 -172
  56. package/lib/table/src/table.js +1471 -1029
  57. package/lib/table/src/util.js +15 -19
  58. package/lib/toolbar/src/toolbar.js +132 -75
  59. package/lib/ui/index.js +1 -1
  60. package/lib/ui/src/dom.js +9 -6
  61. package/lib/ui/src/log.js +1 -1
  62. package/package.json +2 -2
  63. package/packages/colgroup/index.ts +22 -22
  64. package/packages/column/index.ts +22 -22
  65. package/packages/components.ts +41 -44
  66. package/packages/grid/index.ts +18 -18
  67. package/packages/grid/src/emits.ts +5 -19
  68. package/packages/grid/src/grid.ts +2229 -1925
  69. package/packages/grid/src/props.ts +22 -23
  70. package/packages/index.ts +11 -11
  71. package/packages/locale/lang/fr-FR.ts +15 -15
  72. package/packages/locale/lang/it-IT.ts +4 -4
  73. package/packages/locale/lang/uk-UA.ts +1 -1
  74. package/packages/locale/lang/uz-UZ.ts +13 -13
  75. package/packages/locale/lang/zh-CN.ts +907 -907
  76. package/packages/table/index.ts +26 -26
  77. package/packages/table/module/custom/hook.ts +510 -503
  78. package/packages/table/module/custom/panel.ts +2002 -1743
  79. package/packages/table/module/edit/hook.ts +1224 -1131
  80. package/packages/table/module/export/export-panel.ts +697 -611
  81. package/packages/table/module/export/hook.ts +2160 -2059
  82. package/packages/table/module/export/import-panel.ts +319 -279
  83. package/packages/table/module/export/util.ts +25 -24
  84. package/packages/table/module/filter/hook.ts +519 -501
  85. package/packages/table/module/filter/panel.ts +368 -304
  86. package/packages/table/module/keyboard/hook.ts +498 -494
  87. package/packages/table/module/menu/hook.ts +330 -330
  88. package/packages/table/module/menu/panel.ts +272 -201
  89. package/packages/table/module/validator/hook.ts +653 -635
  90. package/packages/table/render/index.ts +1819 -1744
  91. package/packages/table/src/body.ts +1078 -955
  92. package/packages/table/src/cell.ts +1524 -1359
  93. package/packages/table/src/column.ts +192 -192
  94. package/packages/table/src/columnInfo.ts +232 -232
  95. package/packages/table/src/emits.ts +134 -134
  96. package/packages/table/src/footer.ts +425 -380
  97. package/packages/table/src/group.ts +67 -63
  98. package/packages/table/src/header.ts +642 -581
  99. package/packages/table/src/props.ts +336 -336
  100. package/packages/table/src/store.ts +14 -14
  101. package/packages/table/src/table.ts +16011 -15454
  102. package/packages/table/src/use/cell-view.ts +41 -44
  103. package/packages/table/src/use/index.ts +1 -1
  104. package/packages/table/src/util.ts +1206 -1216
  105. package/packages/toolbar/index.ts +18 -18
  106. package/packages/toolbar/src/toolbar.ts +768 -706
  107. package/packages/ui/index.ts +519 -520
  108. package/packages/ui/src/anime.ts +51 -52
  109. package/packages/ui/src/comp.ts +3 -3
  110. package/packages/ui/src/dom.ts +466 -463
  111. package/packages/ui/src/log.ts +19 -19
  112. package/packages/ui/src/utils.ts +66 -66
  113. package/packages/ui/src/vn.ts +55 -55
  114. package/packages/v-x-e-table/index.d.ts +3 -3
  115. package/packages/v-x-e-table/index.ts +3 -3
  116. package/types/all.d.ts +76 -76
  117. package/types/index.d.ts +4 -4
  118. /package/dist/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  119. /package/dist/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  120. /package/dist/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  121. /package/es/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  122. /package/es/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  123. /package/es/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  124. /package/lib/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  125. /package/lib/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  126. /package/lib/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
@@ -1,330 +1,330 @@
1
- import { nextTick } from 'vue'
2
- import XEUtils from 'xe-utils'
3
- import { VxeUI } from '@vxe-ui/core'
4
- import { getDomNode, getAbsolutePos, getEventTargetNode, toCssUnit } from '../../../ui/src/dom'
5
- import { isEnableConf, hasChildrenList, hasEnableConf } from '../../../ui/src/utils'
6
-
7
- import type { VxeComponentStyleType } from 'vxe-pc-ui'
8
- import type { TableMenuMethods, TableMenuPrivateMethods } from '../../../../types'
9
-
10
- const { menus, hooks, globalEvents, GLOBAL_EVENT_KEYS } = VxeUI
11
-
12
- const tableMenuMethodKeys: (keyof TableMenuMethods)[] = ['closeMenu']
13
-
14
- hooks.add('tableMenuModule', {
15
- setupTable ($xeTable) {
16
- const { xID, props, reactData, internalData } = $xeTable
17
- const { refElem, refTableFilter, refTableMenu } = $xeTable.getRefMaps()
18
- const { computeMouseOpts, computeIsContentMenu, computeMenuOpts } = $xeTable.getComputeMaps()
19
-
20
- const $xeGrid = $xeTable.xeGrid
21
- const $xeGantt = $xeTable.xeGantt
22
- const $xeGGWrapper = $xeGrid || $xeGantt
23
-
24
- let menuMethods = {} as TableMenuMethods
25
- let menuPrivateMethods = {} as TableMenuPrivateMethods
26
-
27
- /**
28
- * 显示快捷菜单
29
- */
30
- const handleOpenMenuEvent = (evnt: any, type: 'header' | 'body' | 'footer', params: any) => {
31
- const { ctxMenuStore } = reactData
32
- const isContentMenu = computeIsContentMenu.value
33
- const menuOpts = computeMenuOpts.value
34
- const config = menuOpts[type]
35
- const { zIndex, transfer, width, visibleMethod } = menuOpts
36
- if (config) {
37
- const { options, disabled } = config
38
- if (disabled) {
39
- evnt.preventDefault()
40
- } else if (isContentMenu && options && options.length) {
41
- params.options = options
42
- $xeTable.preventEvent(evnt, 'event.showMenu', params, () => {
43
- if (!visibleMethod || visibleMethod(params)) {
44
- evnt.preventDefault()
45
- $xeTable.updateZindex()
46
- const el = $xeGGWrapper ? $xeGGWrapper.getRefMaps().refElem.value : refElem.value
47
- if (!el) {
48
- return
49
- }
50
- const tableRect = el.getBoundingClientRect()
51
- const { scrollTop, scrollLeft, visibleHeight, visibleWidth } = getDomNode()
52
-
53
- let top = evnt.clientY - tableRect.y
54
- let left = evnt.clientX - tableRect.x
55
- if (transfer) {
56
- top = evnt.clientY + scrollTop
57
- left = evnt.clientX + scrollLeft
58
- }
59
-
60
- const handleVisible = () => {
61
- internalData._currMenuParams = params
62
- const ctxStyle: VxeComponentStyleType = {
63
- zIndex: zIndex || internalData.tZindex,
64
- top: `${top}px`,
65
- left: `${left}px`
66
- }
67
- if (width) {
68
- ctxStyle['--vxe-ui-table-menu-item-width'] = toCssUnit(width)
69
- }
70
- Object.assign(ctxMenuStore, {
71
- visible: true,
72
- list: options,
73
- selected: null,
74
- selectChild: null,
75
- showChild: false,
76
- style: ctxStyle
77
- })
78
- nextTick(() => {
79
- const tableMenu = refTableMenu.value
80
- const ctxElem = tableMenu.getRefMaps().refElem.value
81
- const clientHeight = ctxElem.clientHeight
82
- const clientWidth = ctxElem.clientWidth
83
- const { boundingTop, boundingLeft } = getAbsolutePos(ctxElem)
84
- const offsetTop = boundingTop + clientHeight - visibleHeight
85
- const offsetLeft = boundingLeft + clientWidth - visibleWidth
86
- if (offsetTop > -10) {
87
- ctxMenuStore.style.top = `${Math.max(scrollTop + 2, top - clientHeight - 2)}px`
88
- }
89
- if (offsetLeft > -10) {
90
- ctxMenuStore.style.left = `${Math.max(scrollLeft + 2, left - clientWidth - 2)}px`
91
- }
92
- })
93
- }
94
- const { keyboard, row, column } = params
95
- if (keyboard && row && column) {
96
- $xeTable.scrollToRow(row, column).then(() => {
97
- const cell = $xeTable.getCellElement(row, column)
98
- if (cell) {
99
- const { boundingTop, boundingLeft } = getAbsolutePos(cell)
100
- top = boundingTop + scrollTop + Math.floor(cell.offsetHeight / 2)
101
- left = boundingLeft + scrollLeft + Math.floor(cell.offsetWidth / 2)
102
- }
103
- handleVisible()
104
- })
105
- } else {
106
- handleVisible()
107
- }
108
- } else {
109
- menuMethods.closeMenu()
110
- }
111
- })
112
- }
113
- }
114
- $xeTable.closeFilter()
115
- }
116
-
117
- menuMethods = {
118
- /**
119
- * 关闭快捷菜单
120
- */
121
- closeMenu () {
122
- Object.assign(reactData.ctxMenuStore, {
123
- visible: false,
124
- selected: null,
125
- selectChild: null,
126
- showChild: false
127
- })
128
- return nextTick()
129
- }
130
- }
131
-
132
- menuPrivateMethods = {
133
- /**
134
- * 处理菜单的移动
135
- */
136
- moveCtxMenu (evnt, ctxMenuStore, property, hasOper, operRest, menuList) {
137
- let selectItem
138
- const selectIndex = XEUtils.findIndexOf(menuList, item => ctxMenuStore[property] === item)
139
- if (hasOper) {
140
- if (operRest && hasChildrenList(ctxMenuStore.selected)) {
141
- ctxMenuStore.showChild = true
142
- } else {
143
- ctxMenuStore.showChild = false
144
- ctxMenuStore.selectChild = null
145
- }
146
- } else if (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_UP)) {
147
- for (let len = selectIndex - 1; len >= 0; len--) {
148
- if (menuList[len].visible !== false) {
149
- selectItem = menuList[len]
150
- break
151
- }
152
- }
153
- ctxMenuStore[property] = selectItem || menuList[menuList.length - 1]
154
- } else if (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_DOWN)) {
155
- for (let index = selectIndex + 1; index < menuList.length; index++) {
156
- if (menuList[index].visible !== false) {
157
- selectItem = menuList[index]
158
- break
159
- }
160
- }
161
- ctxMenuStore[property] = selectItem || menuList[0]
162
- } else if (ctxMenuStore[property] && (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ENTER) || globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.SPACEBAR))) {
163
- $xeTable.ctxMenuLinkEvent(evnt, ctxMenuStore[property])
164
- }
165
- },
166
- handleOpenMenuEvent,
167
- /**
168
- * 快捷菜单事件处理
169
- */
170
- handleGlobalContextmenuEvent (evnt) {
171
- const $xeGrid = $xeTable.xeGrid
172
- const $xeGantt = $xeTable.xeGantt
173
-
174
- const { mouseConfig, menuConfig } = props
175
- const { editStore, ctxMenuStore } = reactData
176
- const { visibleColumn } = internalData
177
- const tableFilter = refTableFilter.value
178
- const tableMenu = refTableMenu.value
179
- const mouseOpts = computeMouseOpts.value
180
- const menuOpts = computeMenuOpts.value
181
- const el = refElem.value
182
- const { selected } = editStore
183
- const layoutList = ['header', 'body', 'footer']
184
- if (isEnableConf(menuConfig)) {
185
- if (ctxMenuStore.visible && tableMenu && getEventTargetNode(evnt, tableMenu.getRefMaps().refElem.value).flag) {
186
- evnt.preventDefault()
187
- return
188
- }
189
- if (internalData._keyCtx) {
190
- const type = 'body'
191
- const params: any = { source: 'table', type, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, keyboard: true, columns: visibleColumn.slice(0), $event: evnt }
192
- // 如果开启单元格区域
193
- if (hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.area) {
194
- const activeArea = $xeTable.getActiveCellArea()
195
- if (activeArea && activeArea.row && activeArea.column) {
196
- params.row = activeArea.row
197
- params.column = activeArea.column
198
- handleOpenMenuEvent(evnt, type, params)
199
- return
200
- }
201
- } else if (hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.selected) {
202
- // 如果启用键盘导航且已选中单元格
203
- if (selected.row && selected.column) {
204
- params.row = selected.row
205
- params.column = selected.column
206
- handleOpenMenuEvent(evnt, type, params)
207
- return
208
- }
209
- }
210
- }
211
- // 分别匹配表尾、内容、表尾的快捷菜单
212
- for (let index = 0; index < layoutList.length; index++) {
213
- const layout = layoutList[index] as 'header' | 'body' | 'footer'
214
- const columnTargetNode = getEventTargetNode(evnt, el, `vxe-${layout}--column`, (target: any) => {
215
- // target=td|th,直接向上找 table 去匹配即可
216
- return target.parentNode.parentNode.parentNode.getAttribute('xid') === xID
217
- })
218
- const params: any = { source: 'table', type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: visibleColumn.slice(0), $event: evnt }
219
- if (columnTargetNode.flag) {
220
- const cell = columnTargetNode.targetElem
221
- const columnNodeRest = $xeTable.getColumnNode(cell)
222
- const column = columnNodeRest ? columnNodeRest.item : null
223
- let typePrefix = `${layout}-`
224
- if (column) {
225
- Object.assign(params, { column, columnIndex: $xeTable.getColumnIndex(column), cell })
226
- }
227
- if (layout === 'body') {
228
- const rowNodeRest = $xeTable.getRowNode(cell.parentNode)
229
- const row = rowNodeRest ? rowNodeRest.item : null
230
- typePrefix = ''
231
- if (row) {
232
- params.row = row
233
- params.rowIndex = $xeTable.getRowIndex(row)
234
- }
235
- }
236
- const eventType = `${typePrefix}cell-menu` as 'cell-menu' | 'header-cell-menu' | 'footer-cell-menu'
237
- handleOpenMenuEvent(evnt, layout, params)
238
- $xeTable.dispatchEvent(eventType, params, evnt)
239
- return
240
- } else if (getEventTargetNode(evnt, el, `vxe-table--${layout}-wrapper`, target => target.getAttribute('xid') === xID).flag || (layout === 'body' && getEventTargetNode(evnt, el, 'vxe-table--empty-place-wrapper', target => target.getAttribute('xid') === xID).flag)) {
241
- if (menuOpts.trigger === 'cell') {
242
- evnt.preventDefault()
243
- } else {
244
- handleOpenMenuEvent(evnt, layout, params)
245
- }
246
- return
247
- }
248
- }
249
- }
250
- if (tableFilter && !getEventTargetNode(evnt, tableFilter.getRefMaps().refElem.value).flag) {
251
- $xeTable.closeFilter()
252
- }
253
- menuMethods.closeMenu()
254
- },
255
- ctxMenuMouseoverEvent (evnt, item, child) {
256
- const menuElem = evnt.currentTarget as HTMLDivElement
257
- const { ctxMenuStore } = reactData
258
- evnt.preventDefault()
259
- evnt.stopPropagation()
260
- ctxMenuStore.selected = item
261
- ctxMenuStore.selectChild = child
262
- if (!child) {
263
- ctxMenuStore.showChild = hasChildrenList(item)
264
- if (ctxMenuStore.showChild) {
265
- nextTick(() => {
266
- const childWrapperElem = menuElem.nextElementSibling as HTMLDivElement
267
- if (childWrapperElem) {
268
- const { boundingTop, boundingLeft, visibleHeight, visibleWidth } = getAbsolutePos(menuElem)
269
- const posTop = boundingTop + menuElem.offsetHeight
270
- const posLeft = boundingLeft + menuElem.offsetWidth
271
- let left = ''
272
- let right = ''
273
- // 是否超出右侧
274
- if (posLeft + childWrapperElem.offsetWidth > visibleWidth - 10) {
275
- left = 'auto'
276
- right = `${menuElem.offsetWidth}px`
277
- }
278
- // 是否超出底部
279
- let top = ''
280
- let bottom = ''
281
- if (posTop + childWrapperElem.offsetHeight > visibleHeight - 10) {
282
- top = 'auto'
283
- bottom = '0'
284
- }
285
- childWrapperElem.style.left = left
286
- childWrapperElem.style.right = right
287
- childWrapperElem.style.top = top
288
- childWrapperElem.style.bottom = bottom
289
- }
290
- })
291
- }
292
- }
293
- },
294
- ctxMenuMouseoutEvent (evnt, item) {
295
- const { ctxMenuStore } = reactData
296
- if (!item.children) {
297
- ctxMenuStore.selected = null
298
- }
299
- ctxMenuStore.selectChild = null
300
- },
301
- /**
302
- * 快捷菜单点击事件
303
- */
304
- ctxMenuLinkEvent (evnt, menu) {
305
- const $xeGrid = $xeTable.xeGrid
306
- const $xeGantt = $xeTable.xeGantt
307
-
308
- // 如果一级菜单有配置 code 则允许点击,否则不能点击
309
- if (!menu.loading && !menu.disabled && (menu.code || !menu.children || !menu.children.length)) {
310
- const gMenuOpts = menus.get(menu.code)
311
- const params = Object.assign({}, internalData._currMenuParams, { menu, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, $event: evnt })
312
- const tmMethod = gMenuOpts ? (gMenuOpts.tableMenuMethod || gMenuOpts.menuMethod) : null
313
- if (tmMethod) {
314
- tmMethod(params, evnt)
315
- }
316
- $xeTable.dispatchEvent('menu-click', params, evnt)
317
- menuMethods.closeMenu()
318
- }
319
- }
320
- }
321
-
322
- return { ...menuMethods, ...menuPrivateMethods }
323
- },
324
- setupGrid ($xeGrid) {
325
- return $xeGrid.extendTableMethods(tableMenuMethodKeys)
326
- },
327
- setupGantt ($xeGantt) {
328
- return $xeGantt.extendTableMethods(tableMenuMethodKeys)
329
- }
330
- })
1
+ import { nextTick } from 'vue'
2
+ import XEUtils from 'xe-utils'
3
+ import { VxeUI } from '@vxe-ui/core'
4
+ import { getDomNode, getAbsolutePos, getEventTargetNode, toCssUnit } from '../../../ui/src/dom'
5
+ import { isEnableConf, hasChildrenList, hasEnableConf } from '../../../ui/src/utils'
6
+
7
+ import type { VxeComponentStyleType } from 'vxe-pc-ui'
8
+ import type { TableMenuMethods, TableMenuPrivateMethods } from '../../../../types'
9
+
10
+ const { menus, hooks, globalEvents, GLOBAL_EVENT_KEYS } = VxeUI
11
+
12
+ const tableMenuMethodKeys: (keyof TableMenuMethods)[] = ['closeMenu']
13
+
14
+ hooks.add('tableMenuModule', {
15
+ setupTable($xeTable) {
16
+ const { xID, props, reactData, internalData } = $xeTable
17
+ const { refElem, refTableFilter, refTableMenu } = $xeTable.getRefMaps()
18
+ const { computeMouseOpts, computeIsContentMenu, computeMenuOpts } = $xeTable.getComputeMaps()
19
+
20
+ const $xeGrid = $xeTable.xeGrid
21
+ const $xeGantt = $xeTable.xeGantt
22
+ const $xeGGWrapper = $xeGrid || $xeGantt
23
+
24
+ let menuMethods = {} as TableMenuMethods
25
+ let menuPrivateMethods = {} as TableMenuPrivateMethods
26
+
27
+ /**
28
+ * 显示快捷菜单
29
+ */
30
+ const handleOpenMenuEvent = (evnt: any, type: 'header' | 'body' | 'footer', params: any) => {
31
+ const { ctxMenuStore } = reactData
32
+ const isContentMenu = computeIsContentMenu.value
33
+ const menuOpts = computeMenuOpts.value
34
+ const config = menuOpts[type]
35
+ const { zIndex, transfer, width, visibleMethod } = menuOpts
36
+ if (config) {
37
+ const { options, disabled } = config
38
+ if (disabled) {
39
+ evnt.preventDefault()
40
+ } else if (isContentMenu && options && options.length) {
41
+ params.options = options
42
+ $xeTable.preventEvent(evnt, 'event.showMenu', params, () => {
43
+ if (!visibleMethod || visibleMethod(params)) {
44
+ evnt.preventDefault()
45
+ $xeTable.updateZindex()
46
+ const el = $xeGGWrapper ? $xeGGWrapper.getRefMaps().refElem.value : refElem.value
47
+ if (!el) {
48
+ return
49
+ }
50
+ const tableRect = el.getBoundingClientRect()
51
+ const { scrollTop, scrollLeft, visibleHeight, visibleWidth } = getDomNode()
52
+
53
+ let top = evnt.clientY - tableRect.y
54
+ let left = evnt.clientX - tableRect.x
55
+ if (transfer) {
56
+ top = evnt.clientY + scrollTop
57
+ left = evnt.clientX + scrollLeft
58
+ }
59
+
60
+ const handleVisible = () => {
61
+ internalData._currMenuParams = params
62
+ const ctxStyle: VxeComponentStyleType = {
63
+ zIndex: zIndex || internalData.tZindex,
64
+ top: `${top}px`,
65
+ left: `${left}px`
66
+ }
67
+ if (width) {
68
+ ctxStyle['--vxe-ui-table-menu-item-width'] = toCssUnit(width)
69
+ }
70
+ Object.assign(ctxMenuStore, {
71
+ visible: true,
72
+ list: options,
73
+ selected: null,
74
+ selectChild: null,
75
+ showChild: false,
76
+ style: ctxStyle
77
+ })
78
+ nextTick(() => {
79
+ const tableMenu = refTableMenu.value
80
+ const ctxElem = tableMenu.getRefMaps().refElem.value
81
+ const clientHeight = ctxElem.clientHeight
82
+ const clientWidth = ctxElem.clientWidth
83
+ const { boundingTop, boundingLeft } = getAbsolutePos(ctxElem)
84
+ const offsetTop = boundingTop + clientHeight - visibleHeight
85
+ const offsetLeft = boundingLeft + clientWidth - visibleWidth
86
+ if (offsetTop > -10) {
87
+ ctxMenuStore.style.top = `${Math.max(scrollTop + 2, top - clientHeight - 2)}px`
88
+ }
89
+ if (offsetLeft > -10) {
90
+ ctxMenuStore.style.left = `${Math.max(scrollLeft + 2, left - clientWidth - 2)}px`
91
+ }
92
+ })
93
+ }
94
+ const { keyboard, row, column } = params
95
+ if (keyboard && row && column) {
96
+ $xeTable.scrollToRow(row, column).then(() => {
97
+ const cell = $xeTable.getCellElement(row, column)
98
+ if (cell) {
99
+ const { boundingTop, boundingLeft } = getAbsolutePos(cell)
100
+ top = boundingTop + scrollTop + Math.floor(cell.offsetHeight / 2)
101
+ left = boundingLeft + scrollLeft + Math.floor(cell.offsetWidth / 2)
102
+ }
103
+ handleVisible()
104
+ })
105
+ } else {
106
+ handleVisible()
107
+ }
108
+ } else {
109
+ menuMethods.closeMenu()
110
+ }
111
+ })
112
+ }
113
+ }
114
+ $xeTable.closeFilter()
115
+ }
116
+
117
+ menuMethods = {
118
+ /**
119
+ * 关闭快捷菜单
120
+ */
121
+ closeMenu() {
122
+ Object.assign(reactData.ctxMenuStore, {
123
+ visible: false,
124
+ selected: null,
125
+ selectChild: null,
126
+ showChild: false
127
+ })
128
+ return nextTick()
129
+ }
130
+ }
131
+
132
+ menuPrivateMethods = {
133
+ /**
134
+ * 处理菜单的移动
135
+ */
136
+ moveCtxMenu(evnt, ctxMenuStore, property, hasOper, operRest, menuList) {
137
+ let selectItem
138
+ const selectIndex = XEUtils.findIndexOf(menuList, (item) => ctxMenuStore[property] === item)
139
+ if (hasOper) {
140
+ if (operRest && hasChildrenList(ctxMenuStore.selected)) {
141
+ ctxMenuStore.showChild = true
142
+ } else {
143
+ ctxMenuStore.showChild = false
144
+ ctxMenuStore.selectChild = null
145
+ }
146
+ } else if (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_UP)) {
147
+ for (let len = selectIndex - 1; len >= 0; len--) {
148
+ if (menuList[len].visible !== false) {
149
+ selectItem = menuList[len]
150
+ break
151
+ }
152
+ }
153
+ ctxMenuStore[property] = selectItem || menuList[menuList.length - 1]
154
+ } else if (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_DOWN)) {
155
+ for (let index = selectIndex + 1; index < menuList.length; index++) {
156
+ if (menuList[index].visible !== false) {
157
+ selectItem = menuList[index]
158
+ break
159
+ }
160
+ }
161
+ ctxMenuStore[property] = selectItem || menuList[0]
162
+ } else if (ctxMenuStore[property] && (globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ENTER) || globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.SPACEBAR))) {
163
+ $xeTable.ctxMenuLinkEvent(evnt, ctxMenuStore[property])
164
+ }
165
+ },
166
+ handleOpenMenuEvent,
167
+ /**
168
+ * 快捷菜单事件处理
169
+ */
170
+ handleGlobalContextmenuEvent(evnt) {
171
+ const $xeGrid = $xeTable.xeGrid
172
+ const $xeGantt = $xeTable.xeGantt
173
+
174
+ const { mouseConfig, menuConfig } = props
175
+ const { editStore, ctxMenuStore } = reactData
176
+ const { visibleColumn } = internalData
177
+ const tableFilter = refTableFilter.value
178
+ const tableMenu = refTableMenu.value
179
+ const mouseOpts = computeMouseOpts.value
180
+ const menuOpts = computeMenuOpts.value
181
+ const el = refElem.value
182
+ const { selected } = editStore
183
+ const layoutList = ['header', 'body', 'footer']
184
+ if (isEnableConf(menuConfig)) {
185
+ if (ctxMenuStore.visible && tableMenu && getEventTargetNode(evnt, tableMenu.getRefMaps().refElem.value).flag) {
186
+ evnt.preventDefault()
187
+ return
188
+ }
189
+ if (internalData._keyCtx) {
190
+ const type = 'body'
191
+ const params: any = { source: 'table', type, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, keyboard: true, columns: visibleColumn.slice(0), $event: evnt }
192
+ // 如果开启单元格区域
193
+ if (hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.area) {
194
+ const activeArea = $xeTable.getActiveCellArea()
195
+ if (activeArea && activeArea.row && activeArea.column) {
196
+ params.row = activeArea.row
197
+ params.column = activeArea.column
198
+ handleOpenMenuEvent(evnt, type, params)
199
+ return
200
+ }
201
+ } else if (hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.selected) {
202
+ // 如果启用键盘导航且已选中单元格
203
+ if (selected.row && selected.column) {
204
+ params.row = selected.row
205
+ params.column = selected.column
206
+ handleOpenMenuEvent(evnt, type, params)
207
+ return
208
+ }
209
+ }
210
+ }
211
+ // 分别匹配表尾、内容、表尾的快捷菜单
212
+ for (let index = 0; index < layoutList.length; index++) {
213
+ const layout = layoutList[index] as 'header' | 'body' | 'footer'
214
+ const columnTargetNode = getEventTargetNode(evnt, el, `vxe-${layout}--column`, (target: any) => {
215
+ // target=td|th,直接向上找 table 去匹配即可
216
+ return target.parentNode.parentNode.parentNode.getAttribute('xid') === xID
217
+ })
218
+ const params: any = { source: 'table', type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: visibleColumn.slice(0), $event: evnt }
219
+ if (columnTargetNode.flag) {
220
+ const cell = columnTargetNode.targetElem
221
+ const columnNodeRest = $xeTable.getColumnNode(cell)
222
+ const column = columnNodeRest ? columnNodeRest.item : null
223
+ let typePrefix = `${layout}-`
224
+ if (column) {
225
+ Object.assign(params, { column, columnIndex: $xeTable.getColumnIndex(column), cell })
226
+ }
227
+ if (layout === 'body') {
228
+ const rowNodeRest = $xeTable.getRowNode(cell.parentNode)
229
+ const row = rowNodeRest ? rowNodeRest.item : null
230
+ typePrefix = ''
231
+ if (row) {
232
+ params.row = row
233
+ params.rowIndex = $xeTable.getRowIndex(row)
234
+ }
235
+ }
236
+ const eventType = `${typePrefix}cell-menu` as 'cell-menu' | 'header-cell-menu' | 'footer-cell-menu'
237
+ handleOpenMenuEvent(evnt, layout, params)
238
+ $xeTable.dispatchEvent(eventType, params, evnt)
239
+ return
240
+ } else if (getEventTargetNode(evnt, el, `vxe-table--${layout}-wrapper`, (target) => target.getAttribute('xid') === xID).flag || (layout === 'body' && getEventTargetNode(evnt, el, 'vxe-table--empty-place-wrapper', (target) => target.getAttribute('xid') === xID).flag)) {
241
+ if (menuOpts.trigger === 'cell') {
242
+ evnt.preventDefault()
243
+ } else {
244
+ handleOpenMenuEvent(evnt, layout, params)
245
+ }
246
+ return
247
+ }
248
+ }
249
+ }
250
+ if (tableFilter && !getEventTargetNode(evnt, tableFilter.getRefMaps().refElem.value).flag) {
251
+ $xeTable.closeFilter()
252
+ }
253
+ menuMethods.closeMenu()
254
+ },
255
+ ctxMenuMouseoverEvent(evnt, item, child) {
256
+ const menuElem = evnt.currentTarget as HTMLDivElement
257
+ const { ctxMenuStore } = reactData
258
+ evnt.preventDefault()
259
+ evnt.stopPropagation()
260
+ ctxMenuStore.selected = item
261
+ ctxMenuStore.selectChild = child
262
+ if (!child) {
263
+ ctxMenuStore.showChild = hasChildrenList(item)
264
+ if (ctxMenuStore.showChild) {
265
+ nextTick(() => {
266
+ const childWrapperElem = menuElem.nextElementSibling as HTMLDivElement
267
+ if (childWrapperElem) {
268
+ const { boundingTop, boundingLeft, visibleHeight, visibleWidth } = getAbsolutePos(menuElem)
269
+ const posTop = boundingTop + menuElem.offsetHeight
270
+ const posLeft = boundingLeft + menuElem.offsetWidth
271
+ let left = ''
272
+ let right = ''
273
+ // 是否超出右侧
274
+ if (posLeft + childWrapperElem.offsetWidth > visibleWidth - 10) {
275
+ left = 'auto'
276
+ right = `${menuElem.offsetWidth}px`
277
+ }
278
+ // 是否超出底部
279
+ let top = ''
280
+ let bottom = ''
281
+ if (posTop + childWrapperElem.offsetHeight > visibleHeight - 10) {
282
+ top = 'auto'
283
+ bottom = '0'
284
+ }
285
+ childWrapperElem.style.left = left
286
+ childWrapperElem.style.right = right
287
+ childWrapperElem.style.top = top
288
+ childWrapperElem.style.bottom = bottom
289
+ }
290
+ })
291
+ }
292
+ }
293
+ },
294
+ ctxMenuMouseoutEvent(evnt, item) {
295
+ const { ctxMenuStore } = reactData
296
+ if (!item.children) {
297
+ ctxMenuStore.selected = null
298
+ }
299
+ ctxMenuStore.selectChild = null
300
+ },
301
+ /**
302
+ * 快捷菜单点击事件
303
+ */
304
+ ctxMenuLinkEvent(evnt, menu) {
305
+ const $xeGrid = $xeTable.xeGrid
306
+ const $xeGantt = $xeTable.xeGantt
307
+
308
+ // 如果一级菜单有配置 code 则允许点击,否则不能点击
309
+ if (!menu.loading && !menu.disabled && (menu.code || !menu.children || !menu.children.length)) {
310
+ const gMenuOpts = menus.get(menu.code)
311
+ const params = Object.assign({}, internalData._currMenuParams, { menu, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, $event: evnt })
312
+ const tmMethod = gMenuOpts ? gMenuOpts.tableMenuMethod || gMenuOpts.menuMethod : null
313
+ if (tmMethod) {
314
+ tmMethod(params, evnt)
315
+ }
316
+ $xeTable.dispatchEvent('menu-click', params, evnt)
317
+ menuMethods.closeMenu()
318
+ }
319
+ }
320
+ }
321
+
322
+ return { ...menuMethods, ...menuPrivateMethods }
323
+ },
324
+ setupGrid($xeGrid) {
325
+ return $xeGrid.extendTableMethods(tableMenuMethodKeys)
326
+ },
327
+ setupGantt($xeGantt) {
328
+ return $xeGantt.extendTableMethods(tableMenuMethodKeys)
329
+ }
330
+ })