render-helper.mjs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import { inject, computed, h } from 'vue';
  2. import { merge } from 'lodash-unified';
  3. import { getRowIdentity } from '../util.mjs';
  4. import { TABLE_INJECTION_KEY } from '../tokens.mjs';
  5. import useEvents from './events-helper.mjs';
  6. import useStyles from './styles-helper.mjs';
  7. import TdWrapper from './td-wrapper.mjs';
  8. import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
  9. import { isBoolean, isPropAbsent } from '../../../../utils/types.mjs';
  10. function useRender(props) {
  11. const parent = inject(TABLE_INJECTION_KEY);
  12. const ns = useNamespace("table");
  13. const {
  14. handleDoubleClick,
  15. handleClick,
  16. handleContextMenu,
  17. handleMouseEnter,
  18. handleMouseLeave,
  19. handleCellMouseEnter,
  20. handleCellMouseLeave,
  21. tooltipContent,
  22. tooltipTrigger
  23. } = useEvents(props);
  24. const {
  25. getRowStyle,
  26. getRowClass,
  27. getCellStyle,
  28. getCellClass,
  29. getSpan,
  30. getColspanRealWidth
  31. } = useStyles(props);
  32. const firstDefaultColumnIndex = computed(() => {
  33. return props.store.states.columns.value.findIndex(({ type }) => type === "default");
  34. });
  35. const getKeyOfRow = (row, index) => {
  36. const rowKey = parent.props.rowKey;
  37. if (rowKey) {
  38. return getRowIdentity(row, rowKey);
  39. }
  40. return index;
  41. };
  42. const rowRender = (row, $index, treeRowData, expanded = false) => {
  43. const { tooltipEffect, tooltipOptions, store } = props;
  44. const { indent, columns } = store.states;
  45. const rowClasses = getRowClass(row, $index);
  46. let display = true;
  47. if (treeRowData) {
  48. rowClasses.push(ns.em("row", `level-${treeRowData.level}`));
  49. display = treeRowData.display;
  50. }
  51. const displayStyle = display ? null : { display: "none" };
  52. return h("tr", {
  53. style: [displayStyle, getRowStyle(row, $index)],
  54. class: rowClasses,
  55. key: getKeyOfRow(row, $index),
  56. onDblclick: ($event) => handleDoubleClick($event, row),
  57. onClick: ($event) => handleClick($event, row),
  58. onContextmenu: ($event) => handleContextMenu($event, row),
  59. onMouseenter: () => handleMouseEnter($index),
  60. onMouseleave: handleMouseLeave
  61. }, columns.value.map((column, cellIndex) => {
  62. const { rowspan, colspan } = getSpan(row, column, $index, cellIndex);
  63. if (!rowspan || !colspan) {
  64. return null;
  65. }
  66. const columnData = Object.assign({}, column);
  67. columnData.realWidth = getColspanRealWidth(columns.value, colspan, cellIndex);
  68. const data = {
  69. store: props.store,
  70. _self: props.context || parent,
  71. column: columnData,
  72. row,
  73. $index,
  74. cellIndex,
  75. expanded
  76. };
  77. if (cellIndex === firstDefaultColumnIndex.value && treeRowData) {
  78. data.treeNode = {
  79. indent: treeRowData.level * indent.value,
  80. level: treeRowData.level
  81. };
  82. if (isBoolean(treeRowData.expanded)) {
  83. data.treeNode.expanded = treeRowData.expanded;
  84. if ("loading" in treeRowData) {
  85. data.treeNode.loading = treeRowData.loading;
  86. }
  87. if ("noLazyChildren" in treeRowData) {
  88. data.treeNode.noLazyChildren = treeRowData.noLazyChildren;
  89. }
  90. }
  91. }
  92. const baseKey = `${getKeyOfRow(row, $index)},${cellIndex}`;
  93. const patchKey = columnData.columnKey || columnData.rawColumnKey || "";
  94. const mergedTooltipOptions = column.showOverflowTooltip && merge({
  95. effect: tooltipEffect
  96. }, tooltipOptions, column.showOverflowTooltip);
  97. return h(TdWrapper, {
  98. style: getCellStyle($index, cellIndex, row, column),
  99. class: getCellClass($index, cellIndex, row, column, colspan - 1),
  100. key: `${patchKey}${baseKey}`,
  101. rowspan,
  102. colspan,
  103. onMouseenter: ($event) => handleCellMouseEnter($event, row, mergedTooltipOptions),
  104. onMouseleave: handleCellMouseLeave
  105. }, {
  106. default: () => cellChildren(cellIndex, column, data)
  107. });
  108. }));
  109. };
  110. const cellChildren = (cellIndex, column, data) => {
  111. return column.renderCell(data);
  112. };
  113. const wrappedRowRender = (row, $index) => {
  114. const store = props.store;
  115. const { isRowExpanded, assertRowKey } = store;
  116. const { treeData, lazyTreeNodeMap, childrenColumnName, rowKey } = store.states;
  117. const columns = store.states.columns.value;
  118. const hasExpandColumn = columns.some(({ type }) => type === "expand");
  119. if (hasExpandColumn) {
  120. const expanded = isRowExpanded(row);
  121. const tr = rowRender(row, $index, void 0, expanded);
  122. const renderExpanded = parent.renderExpanded;
  123. if (!renderExpanded) {
  124. console.error("[Element Error]renderExpanded is required.");
  125. return tr;
  126. }
  127. const rows = [[tr]];
  128. if (parent.props.preserveExpandedContent || expanded) {
  129. rows[0].push(h("tr", {
  130. key: `expanded-row__${tr.key}`,
  131. style: { display: expanded ? "" : "none" }
  132. }, [
  133. h("td", {
  134. colspan: columns.length,
  135. class: `${ns.e("cell")} ${ns.e("expanded-cell")}`
  136. }, [renderExpanded({ row, $index, store, expanded })])
  137. ]));
  138. }
  139. return rows;
  140. } else if (Object.keys(treeData.value).length) {
  141. assertRowKey();
  142. const key = getRowIdentity(row, rowKey.value);
  143. let cur = treeData.value[key];
  144. let treeRowData = null;
  145. if (cur) {
  146. treeRowData = {
  147. expanded: cur.expanded,
  148. level: cur.level,
  149. display: true
  150. };
  151. if (isBoolean(cur.lazy)) {
  152. if (isBoolean(cur.loaded) && cur.loaded) {
  153. treeRowData.noLazyChildren = !(cur.children && cur.children.length);
  154. }
  155. treeRowData.loading = cur.loading;
  156. }
  157. }
  158. const tmp = [rowRender(row, $index, treeRowData)];
  159. if (cur) {
  160. let i = 0;
  161. const traverse = (children, parent2) => {
  162. if (!(children && children.length && parent2))
  163. return;
  164. children.forEach((node) => {
  165. const innerTreeRowData = {
  166. display: parent2.display && parent2.expanded,
  167. level: parent2.level + 1,
  168. expanded: false,
  169. noLazyChildren: false,
  170. loading: false
  171. };
  172. const childKey = getRowIdentity(node, rowKey.value);
  173. if (isPropAbsent(childKey)) {
  174. throw new Error("For nested data item, row-key is required.");
  175. }
  176. cur = { ...treeData.value[childKey] };
  177. if (cur) {
  178. innerTreeRowData.expanded = cur.expanded;
  179. cur.level = cur.level || innerTreeRowData.level;
  180. cur.display = !!(cur.expanded && innerTreeRowData.display);
  181. if (isBoolean(cur.lazy)) {
  182. if (isBoolean(cur.loaded) && cur.loaded) {
  183. innerTreeRowData.noLazyChildren = !(cur.children && cur.children.length);
  184. }
  185. innerTreeRowData.loading = cur.loading;
  186. }
  187. }
  188. i++;
  189. tmp.push(rowRender(node, $index + i, innerTreeRowData));
  190. if (cur) {
  191. const nodes2 = lazyTreeNodeMap.value[childKey] || node[childrenColumnName.value];
  192. traverse(nodes2, cur);
  193. }
  194. });
  195. };
  196. cur.display = true;
  197. const nodes = lazyTreeNodeMap.value[key] || row[childrenColumnName.value];
  198. traverse(nodes, cur);
  199. }
  200. return tmp;
  201. } else {
  202. return rowRender(row, $index, void 0);
  203. }
  204. };
  205. return {
  206. wrappedRowRender,
  207. tooltipContent,
  208. tooltipTrigger
  209. };
  210. }
  211. export { useRender as default };
  212. //# sourceMappingURL=render-helper.mjs.map