panel.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { CreateElement } from 'vue'
  2. import { VxeUI } from '../../../ui'
  3. import XEUtils from 'xe-utils'
  4. import { getFuncText } from '../../../ui/src/utils'
  5. import { getSlotVNs } from '../../../ui/src/vn'
  6. import type { VxeTableConstructor, VxeTablePrivateMethods, TableReactData } from '../../../../types'
  7. const { getIcon, renderEmptyElement } = VxeUI
  8. export default {
  9. name: 'VxeTableMenuPanel',
  10. props: {
  11. ctxMenuStore: Object,
  12. ctxMenuOpts: Object
  13. },
  14. inject: {
  15. $xeTable: {
  16. default: null
  17. }
  18. },
  19. mounted () {
  20. const $xeMenuPanel = this
  21. const $xeTable = $xeMenuPanel.$xeTable as VxeTableConstructor & VxeTablePrivateMethods
  22. const menuOpts = $xeTable.computeMenuOpts
  23. const { transfer } = menuOpts
  24. const el = this.$refs.refElem as HTMLDivElement
  25. if (transfer && el) {
  26. document.body.appendChild(el)
  27. }
  28. },
  29. beforeDestroy () {
  30. const el = this.$refs.refElem as HTMLDivElement
  31. if (el && el.parentNode) {
  32. el.parentNode.removeChild(el)
  33. }
  34. },
  35. render (this: any, h: CreateElement) {
  36. const $xeMenuPanel = this
  37. const $xeTable = $xeMenuPanel.$xeTable as VxeTableConstructor & VxeTablePrivateMethods
  38. const tableReactData = $xeTable as unknown as TableReactData
  39. const { ctxMenuStore } = tableReactData
  40. const menuOpts = $xeTable.computeMenuOpts
  41. const { destroyOnClose } = menuOpts
  42. const { visible, list, className } = ctxMenuStore
  43. return h('div', {
  44. ref: 'refElem',
  45. class: ['vxe-table--context-menu-wrapper', className, {
  46. 'is--visible': visible
  47. }],
  48. style: ctxMenuStore.style
  49. }, (destroyOnClose ? visible : true)
  50. ? list.map((options, gIndex) => {
  51. return options.every((item) => item.visible === false)
  52. ? renderEmptyElement($xeTable)
  53. : h('ul', {
  54. class: 'vxe-context-menu--option-wrapper',
  55. key: gIndex
  56. }, options.map((item, index) => {
  57. const hasChildMenus = item.children && item.children.some((child) => child.visible !== false)
  58. const prefixOpts = Object.assign({}, item.prefixConfig)
  59. const prefixIcon = prefixOpts.icon || item.prefixIcon
  60. const suffixOpts = Object.assign({}, item.suffixConfig)
  61. const suffixIcon = suffixOpts.icon || item.suffixIcon
  62. const menuContent = getFuncText(item.name)
  63. return item.visible === false
  64. ? renderEmptyElement($xeTable)
  65. : h('li', {
  66. class: [item.className, {
  67. 'link--disabled': item.disabled,
  68. 'link--active': item === ctxMenuStore.selected
  69. }],
  70. key: `${gIndex}_${index}`
  71. }, [
  72. h('a', {
  73. class: 'vxe-context-menu--link',
  74. on: {
  75. click (evnt: Event) {
  76. $xeTable.ctxMenuLinkEvent(evnt, item)
  77. },
  78. mouseover (evnt: Event) {
  79. $xeTable.ctxMenuMouseoverEvent(evnt, item)
  80. },
  81. mouseout (evnt: Event) {
  82. $xeTable.ctxMenuMouseoutEvent(evnt, item)
  83. }
  84. }
  85. }, [
  86. h('div', {
  87. class: ['vxe-context-menu--link-prefix', prefixOpts.className || '']
  88. }, [
  89. prefixIcon && XEUtils.isFunction(prefixIcon)
  90. ? h('span', {}, getSlotVNs(prefixIcon.call($xeTable, {})))
  91. : h('i', {
  92. class: prefixIcon
  93. }),
  94. prefixOpts.content ? h('span', {}, `${prefixOpts.content}`) : renderEmptyElement($xeTable)
  95. ]),
  96. h('span', {
  97. class: 'vxe-context-menu--link-content',
  98. attrs: {
  99. title: menuContent
  100. }
  101. }, menuContent),
  102. h('div', {
  103. class: ['vxe-context-menu--link-suffix', suffixOpts.className || '']
  104. }, [
  105. suffixIcon && XEUtils.isFunction(suffixIcon)
  106. ? h('span', {}, getSlotVNs(suffixIcon.call($xeTable, {})))
  107. : h('i', {
  108. class: suffixIcon || (hasChildMenus ? getIcon().TABLE_MENU_OPTIONS : '')
  109. }),
  110. suffixOpts.content ? h('span', `${suffixOpts.content}`) : renderEmptyElement($xeTable)
  111. ])
  112. ]),
  113. hasChildMenus && item.children
  114. ? h('ul', {
  115. class: ['vxe-table--context-menu-clild-wrapper', {
  116. 'is--show': item === ctxMenuStore.selected && ctxMenuStore.showChild
  117. }]
  118. }, item.children.map((child, cIndex) => {
  119. const childPrefixOpts = Object.assign({}, child.prefixConfig)
  120. const childPrefixIcon = childPrefixOpts.icon || child.prefixIcon
  121. const childSuffixOpts = Object.assign({}, child.suffixConfig)
  122. const childSuffixIcon = childSuffixOpts.icon || child.suffixIcon
  123. const childMenuContent = getFuncText(child.name)
  124. return child.visible === false
  125. ? null
  126. : h('li', {
  127. class: [child.className, {
  128. 'link--disabled': child.disabled,
  129. 'link--active': child === ctxMenuStore.selectChild
  130. }],
  131. key: `${gIndex}_${index}_${cIndex}`
  132. }, [
  133. h('a', {
  134. class: 'vxe-context-menu--link',
  135. on: {
  136. click (evnt: Event) {
  137. $xeTable.ctxMenuLinkEvent(evnt, child)
  138. },
  139. mouseover (evnt: Event) {
  140. $xeTable.ctxMenuMouseoverEvent(evnt, item, child)
  141. },
  142. mouseout (evnt: Event) {
  143. $xeTable.ctxMenuMouseoutEvent(evnt, item)
  144. }
  145. }
  146. }, [
  147. h('div', {
  148. class: ['vxe-context-menu--link-prefix', childPrefixOpts.className || '']
  149. }, [
  150. childPrefixIcon && XEUtils.isFunction(childPrefixIcon)
  151. ? h('span', {}, getSlotVNs(childPrefixIcon.call($xeTable, {})))
  152. : h('i', {
  153. class: childPrefixIcon
  154. }),
  155. childPrefixOpts.content ? h('span', `${childPrefixOpts.content}`) : renderEmptyElement($xeTable)
  156. ]),
  157. h('span', {
  158. class: 'vxe-context-menu--link-content',
  159. attrs: {
  160. title: childMenuContent
  161. }
  162. }, childMenuContent),
  163. h('div', {
  164. class: ['vxe-context-menu--link-suffix', childSuffixOpts.className || '']
  165. }, [
  166. childSuffixIcon && XEUtils.isFunction(childSuffixIcon)
  167. ? h('span', {}, getSlotVNs(childSuffixIcon.call($xeTable, {})))
  168. : h('i', {
  169. class: childSuffixIcon
  170. }),
  171. childSuffixOpts.content ? h('span', `${childSuffixOpts.content}`) : renderEmptyElement($xeTable)
  172. ])
  173. ])
  174. ])
  175. }))
  176. : null
  177. ])
  178. }))
  179. })
  180. : [])
  181. }
  182. } as any