vxe-table 4.18.4 → 4.18.6

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