vxe-table 4.23.7 → 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 (148) hide show
  1. package/dist/all.esm.js +5859 -4018
  2. package/es/colgroup/index.js +1 -1
  3. package/es/column/index.js +1 -1
  4. package/es/components.d.ts +3 -0
  5. package/es/components.js +4 -8
  6. package/es/grid/index.js +1 -1
  7. package/es/grid/src/emits.js +1 -15
  8. package/es/grid/src/grid.js +398 -121
  9. package/es/grid/src/props.js +1 -1
  10. package/es/index.esm.js +6 -0
  11. package/es/index.js +6 -0
  12. package/es/table/index.js +1 -1
  13. package/es/table/module/custom/hook.js +50 -43
  14. package/es/table/module/custom/panel.js +778 -528
  15. package/es/table/module/edit/hook.js +141 -63
  16. package/es/table/module/export/export-panel.js +400 -317
  17. package/es/table/module/export/hook.js +396 -338
  18. package/es/table/module/export/import-panel.js +153 -124
  19. package/es/table/module/filter/hook.js +17 -3
  20. package/es/table/module/filter/panel.js +147 -85
  21. package/es/table/module/keyboard/hook.js +9 -5
  22. package/es/table/module/menu/hook.js +1 -1
  23. package/es/table/module/menu/panel.js +198 -127
  24. package/es/table/module/validator/hook.js +1 -1
  25. package/es/table/render/index.js +152 -99
  26. package/es/table/src/body.js +356 -234
  27. package/es/table/src/cell.js +427 -270
  28. package/es/table/src/columnInfo.js +2 -1
  29. package/es/table/src/footer.js +145 -100
  30. package/es/table/src/group.js +7 -3
  31. package/es/table/src/header.js +230 -173
  32. package/es/table/src/props.js +1 -1
  33. package/es/table/src/table.js +1504 -1031
  34. package/es/table/src/util.js +15 -19
  35. package/es/toolbar/index.js +1 -1
  36. package/es/toolbar/src/toolbar.js +133 -76
  37. package/es/ui/index.d.ts +0 -1
  38. package/es/ui/index.js +1 -2
  39. package/es/ui/src/dom.js +9 -6
  40. package/es/ui/src/log.js +1 -1
  41. package/es/ui/src/utils.d.ts +1 -1
  42. package/es/v-x-e-table/index.d.ts +0 -1
  43. package/es/v-x-e-table/index.js +0 -1
  44. package/lib/colgroup/index.js +5 -5
  45. package/lib/column/index.js +5 -5
  46. package/lib/components.js +8 -12
  47. package/lib/grid/index.js +4 -4
  48. package/lib/grid/src/emits.js +1 -15
  49. package/lib/grid/src/grid.js +419 -142
  50. package/lib/grid/src/props.js +2 -2
  51. package/lib/index.common.js +6 -0
  52. package/lib/index.js +6 -0
  53. package/lib/index.umd.js +5825 -3945
  54. package/lib/index.umd.min.js +3 -3
  55. package/lib/table/index.js +5 -5
  56. package/lib/table/module/custom/hook.js +51 -44
  57. package/lib/table/module/custom/panel.js +790 -540
  58. package/lib/table/module/edit/hook.js +142 -64
  59. package/lib/table/module/export/export-panel.js +406 -323
  60. package/lib/table/module/export/hook.js +419 -361
  61. package/lib/table/module/export/import-panel.js +157 -128
  62. package/lib/table/module/filter/hook.js +18 -4
  63. package/lib/table/module/filter/panel.js +149 -87
  64. package/lib/table/module/keyboard/hook.js +10 -6
  65. package/lib/table/module/menu/hook.js +2 -2
  66. package/lib/table/module/menu/panel.js +199 -128
  67. package/lib/table/module/validator/hook.js +2 -2
  68. package/lib/table/render/index.js +153 -100
  69. package/lib/table/src/body.js +357 -235
  70. package/lib/table/src/cell.js +428 -271
  71. package/lib/table/src/columnInfo.js +3 -2
  72. package/lib/table/src/footer.js +146 -101
  73. package/lib/table/src/group.js +7 -3
  74. package/lib/table/src/header.js +231 -174
  75. package/lib/table/src/props.js +2 -2
  76. package/lib/table/src/table.js +1487 -1045
  77. package/lib/table/src/util.js +15 -19
  78. package/lib/toolbar/index.js +4 -4
  79. package/lib/toolbar/src/toolbar.js +135 -78
  80. package/lib/ui/index.js +1 -3
  81. package/lib/ui/src/dom.js +9 -6
  82. package/lib/ui/src/log.js +1 -1
  83. package/lib/v-x-e-table/index.js +0 -2
  84. package/package.json +8 -3
  85. package/packages/colgroup/index.ts +22 -22
  86. package/packages/column/index.ts +22 -22
  87. package/packages/components.ts +41 -43
  88. package/packages/grid/index.ts +18 -18
  89. package/packages/grid/src/emits.ts +5 -19
  90. package/packages/grid/src/grid.ts +2229 -1925
  91. package/packages/grid/src/props.ts +22 -23
  92. package/packages/index.ts +11 -4
  93. package/packages/locale/lang/fr-FR.ts +15 -15
  94. package/packages/locale/lang/it-IT.ts +4 -4
  95. package/packages/locale/lang/uk-UA.ts +1 -1
  96. package/packages/locale/lang/uz-UZ.ts +13 -13
  97. package/packages/locale/lang/zh-CN.ts +907 -907
  98. package/packages/table/index.ts +26 -26
  99. package/packages/table/module/custom/hook.ts +510 -503
  100. package/packages/table/module/custom/panel.ts +2002 -1743
  101. package/packages/table/module/edit/hook.ts +1224 -1131
  102. package/packages/table/module/export/export-panel.ts +697 -611
  103. package/packages/table/module/export/hook.ts +2160 -2059
  104. package/packages/table/module/export/import-panel.ts +319 -279
  105. package/packages/table/module/export/util.ts +25 -24
  106. package/packages/table/module/filter/hook.ts +519 -501
  107. package/packages/table/module/filter/panel.ts +368 -304
  108. package/packages/table/module/keyboard/hook.ts +498 -494
  109. package/packages/table/module/menu/hook.ts +330 -330
  110. package/packages/table/module/menu/panel.ts +272 -201
  111. package/packages/table/module/validator/hook.ts +653 -635
  112. package/packages/table/render/index.ts +1819 -1744
  113. package/packages/table/src/body.ts +1078 -955
  114. package/packages/table/src/cell.ts +1524 -1359
  115. package/packages/table/src/column.ts +192 -192
  116. package/packages/table/src/columnInfo.ts +232 -232
  117. package/packages/table/src/emits.ts +134 -134
  118. package/packages/table/src/footer.ts +425 -380
  119. package/packages/table/src/group.ts +67 -63
  120. package/packages/table/src/header.ts +642 -581
  121. package/packages/table/src/props.ts +336 -336
  122. package/packages/table/src/store.ts +14 -14
  123. package/packages/table/src/table.ts +16011 -15454
  124. package/packages/table/src/use/cell-view.ts +41 -44
  125. package/packages/table/src/use/index.ts +1 -1
  126. package/packages/table/src/util.ts +1206 -1216
  127. package/packages/toolbar/index.ts +18 -18
  128. package/packages/toolbar/src/toolbar.ts +768 -706
  129. package/packages/ui/index.ts +519 -521
  130. package/packages/ui/src/anime.ts +51 -52
  131. package/packages/ui/src/comp.ts +3 -3
  132. package/packages/ui/src/dom.ts +466 -463
  133. package/packages/ui/src/log.ts +19 -19
  134. package/packages/ui/src/utils.ts +66 -66
  135. package/packages/ui/src/vn.ts +55 -55
  136. package/packages/v-x-e-table/index.d.ts +3 -4
  137. package/packages/v-x-e-table/index.ts +3 -4
  138. package/types/all.d.ts +76 -76
  139. package/types/index.d.ts +4 -4
  140. /package/dist/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  141. /package/dist/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  142. /package/dist/{iconfont.1792979665397.woff2 → iconfont.1793009263429.woff2} +0 -0
  143. /package/es/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  144. /package/es/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  145. /package/es/{iconfont.1792979665397.woff2 → iconfont.1793009263429.woff2} +0 -0
  146. /package/lib/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  147. /package/lib/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  148. /package/lib/{iconfont.1792979665397.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 '../../../ui'
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
+ })