index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import { createVNode as _createVNode } from "vue";
  4. var __rest = this && this.__rest || function (s, e) {
  5. var t = {};
  6. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  7. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  8. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  9. }
  10. return t;
  11. };
  12. import classNames from '../../_util/classNames';
  13. import { filterEmpty, findDOMNode, flattenChildren, isValidElement } from '../../_util/props-util';
  14. import { watch, shallowRef, Text, computed, defineComponent, isVNode } from 'vue';
  15. import { getPathValue, validateValue } from '../utils/valueUtil';
  16. import { useInjectSlots } from '../../table/context';
  17. import { INTERNAL_COL_DEFINE } from '../utils/legacyUtil';
  18. import { useInjectHover } from '../context/HoverContext';
  19. import { useInjectSticky } from '../context/StickyContext';
  20. import { warning } from '../../vc-util/warning';
  21. import eagerComputed from '../../_util/eagerComputed';
  22. import { customRenderSlot } from '../../_util/vnode';
  23. import { addClass, removeClass } from '../../vc-util/Dom/class';
  24. /** Check if cell is in hover range */
  25. function inHoverRange(cellStartRow, cellRowSpan, startRow, endRow) {
  26. const cellEndRow = cellStartRow + cellRowSpan - 1;
  27. return cellStartRow <= endRow && cellEndRow >= startRow;
  28. }
  29. function isRenderCell(data) {
  30. return data && typeof data === 'object' && !Array.isArray(data) && !isVNode(data);
  31. }
  32. export default defineComponent({
  33. name: 'Cell',
  34. props: ['prefixCls', 'record', 'index', 'renderIndex', 'dataIndex', 'customRender', 'component', 'colSpan', 'rowSpan', 'fixLeft', 'fixRight', 'firstFixLeft', 'lastFixLeft', 'firstFixRight', 'lastFixRight', 'appendNode', 'additionalProps', 'ellipsis', 'align', 'rowType', 'isSticky', 'column', 'cellType', 'transformCellText'],
  35. setup(props, _ref) {
  36. let {
  37. slots
  38. } = _ref;
  39. const contextSlots = useInjectSlots();
  40. const {
  41. onHover,
  42. startRow,
  43. endRow
  44. } = useInjectHover();
  45. const colSpan = computed(() => {
  46. var _a, _b, _c, _d;
  47. return (_c = (_a = props.colSpan) !== null && _a !== void 0 ? _a : (_b = props.additionalProps) === null || _b === void 0 ? void 0 : _b.colSpan) !== null && _c !== void 0 ? _c : (_d = props.additionalProps) === null || _d === void 0 ? void 0 : _d.colspan;
  48. });
  49. const rowSpan = computed(() => {
  50. var _a, _b, _c, _d;
  51. return (_c = (_a = props.rowSpan) !== null && _a !== void 0 ? _a : (_b = props.additionalProps) === null || _b === void 0 ? void 0 : _b.rowSpan) !== null && _c !== void 0 ? _c : (_d = props.additionalProps) === null || _d === void 0 ? void 0 : _d.rowspan;
  52. });
  53. const hovering = eagerComputed(() => {
  54. const {
  55. index
  56. } = props;
  57. return inHoverRange(index, rowSpan.value || 1, startRow.value, endRow.value);
  58. });
  59. const supportSticky = useInjectSticky();
  60. // ====================== Hover =======================
  61. const onMouseenter = (event, mergedRowSpan) => {
  62. var _a;
  63. const {
  64. record,
  65. index,
  66. additionalProps
  67. } = props;
  68. if (record) {
  69. onHover(index, index + mergedRowSpan - 1);
  70. }
  71. (_a = additionalProps === null || additionalProps === void 0 ? void 0 : additionalProps.onMouseenter) === null || _a === void 0 ? void 0 : _a.call(additionalProps, event);
  72. };
  73. const onMouseleave = event => {
  74. var _a;
  75. const {
  76. record,
  77. additionalProps
  78. } = props;
  79. if (record) {
  80. onHover(-1, -1);
  81. }
  82. (_a = additionalProps === null || additionalProps === void 0 ? void 0 : additionalProps.onMouseleave) === null || _a === void 0 ? void 0 : _a.call(additionalProps, event);
  83. };
  84. const getTitle = vnodes => {
  85. const vnode = filterEmpty(vnodes)[0];
  86. if (isVNode(vnode)) {
  87. if (vnode.type === Text) {
  88. return vnode.children;
  89. } else {
  90. return Array.isArray(vnode.children) ? getTitle(vnode.children) : undefined;
  91. }
  92. } else {
  93. return vnode;
  94. }
  95. };
  96. const hoverRef = shallowRef(null);
  97. watch([hovering, () => props.prefixCls, hoverRef], () => {
  98. const cellDom = findDOMNode(hoverRef.value);
  99. if (!cellDom) return;
  100. if (hovering.value) {
  101. addClass(cellDom, `${props.prefixCls}-cell-row-hover`);
  102. } else {
  103. removeClass(cellDom, `${props.prefixCls}-cell-row-hover`);
  104. }
  105. });
  106. return () => {
  107. var _a, _b, _c, _d, _e, _f;
  108. const {
  109. prefixCls,
  110. record,
  111. index,
  112. renderIndex,
  113. dataIndex,
  114. customRender,
  115. component: Component = 'td',
  116. fixLeft,
  117. fixRight,
  118. firstFixLeft,
  119. lastFixLeft,
  120. firstFixRight,
  121. lastFixRight,
  122. appendNode = (_a = slots.appendNode) === null || _a === void 0 ? void 0 : _a.call(slots),
  123. additionalProps = {},
  124. ellipsis,
  125. align,
  126. rowType,
  127. isSticky,
  128. column = {},
  129. cellType
  130. } = props;
  131. const cellPrefixCls = `${prefixCls}-cell`;
  132. // ==================== Child Node ====================
  133. let cellProps;
  134. let childNode;
  135. const children = (_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots);
  136. if (validateValue(children) || cellType === 'header') {
  137. childNode = children;
  138. } else {
  139. const value = getPathValue(record, dataIndex);
  140. // Customize render node
  141. childNode = value;
  142. if (customRender) {
  143. const renderData = customRender({
  144. text: value,
  145. value,
  146. record,
  147. index,
  148. renderIndex,
  149. column: column.__originColumn__
  150. });
  151. if (isRenderCell(renderData)) {
  152. if (process.env.NODE_ENV !== 'production') {
  153. warning(false, '`columns.customRender` return cell props is deprecated with perf issue, please use `customCell` instead.');
  154. }
  155. childNode = renderData.children;
  156. cellProps = renderData.props;
  157. } else {
  158. childNode = renderData;
  159. }
  160. }
  161. if (!(INTERNAL_COL_DEFINE in column) && cellType === 'body' && contextSlots.value.bodyCell && !((_c = column.slots) === null || _c === void 0 ? void 0 : _c.customRender)) {
  162. const child = customRenderSlot(contextSlots.value, 'bodyCell', {
  163. text: value,
  164. value,
  165. record,
  166. index,
  167. column: column.__originColumn__
  168. }, () => {
  169. const fallback = childNode === undefined ? value : childNode;
  170. return [typeof fallback === 'object' && isValidElement(fallback) || typeof fallback !== 'object' ? fallback : null];
  171. });
  172. childNode = flattenChildren(child);
  173. }
  174. /** maybe we should @deprecated */
  175. if (props.transformCellText) {
  176. childNode = props.transformCellText({
  177. text: childNode,
  178. record,
  179. index,
  180. column: column.__originColumn__
  181. });
  182. }
  183. }
  184. // Not crash if final `childNode` is not validate VueNode
  185. if (typeof childNode === 'object' && !Array.isArray(childNode) && !isVNode(childNode)) {
  186. childNode = null;
  187. }
  188. if (ellipsis && (lastFixLeft || firstFixRight)) {
  189. const _childNode = function () {
  190. return childNode;
  191. }();
  192. childNode = _createVNode("span", {
  193. "class": `${cellPrefixCls}-content`
  194. }, [childNode]);
  195. }
  196. if (Array.isArray(childNode) && childNode.length === 1) {
  197. childNode = childNode[0];
  198. }
  199. const _g = cellProps || {},
  200. {
  201. colSpan: cellColSpan,
  202. rowSpan: cellRowSpan,
  203. style: cellStyle,
  204. class: cellClassName
  205. } = _g,
  206. restCellProps = __rest(_g, ["colSpan", "rowSpan", "style", "class"]);
  207. const mergedColSpan = (_d = cellColSpan !== undefined ? cellColSpan : colSpan.value) !== null && _d !== void 0 ? _d : 1;
  208. const mergedRowSpan = (_e = cellRowSpan !== undefined ? cellRowSpan : rowSpan.value) !== null && _e !== void 0 ? _e : 1;
  209. if (mergedColSpan === 0 || mergedRowSpan === 0) {
  210. return null;
  211. }
  212. // ====================== Fixed =======================
  213. const fixedStyle = {};
  214. const isFixLeft = typeof fixLeft === 'number' && supportSticky.value;
  215. const isFixRight = typeof fixRight === 'number' && supportSticky.value;
  216. if (isFixLeft) {
  217. fixedStyle.position = 'sticky';
  218. fixedStyle.left = `${fixLeft}px`;
  219. }
  220. if (isFixRight) {
  221. fixedStyle.position = 'sticky';
  222. fixedStyle.right = `${fixRight}px`;
  223. }
  224. // ====================== Align =======================
  225. const alignStyle = {};
  226. if (align) {
  227. alignStyle.textAlign = align;
  228. }
  229. // ====================== Render ======================
  230. let title;
  231. const ellipsisConfig = ellipsis === true ? {
  232. showTitle: true
  233. } : ellipsis;
  234. if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) {
  235. if (typeof childNode === 'string' || typeof childNode === 'number') {
  236. title = childNode.toString();
  237. } else if (isVNode(childNode)) {
  238. title = getTitle([childNode]);
  239. }
  240. }
  241. const componentProps = _extends(_extends(_extends({
  242. title
  243. }, restCellProps), additionalProps), {
  244. colSpan: mergedColSpan !== 1 ? mergedColSpan : null,
  245. rowSpan: mergedRowSpan !== 1 ? mergedRowSpan : null,
  246. class: classNames(cellPrefixCls, {
  247. [`${cellPrefixCls}-fix-left`]: isFixLeft && supportSticky.value,
  248. [`${cellPrefixCls}-fix-left-first`]: firstFixLeft && supportSticky.value,
  249. [`${cellPrefixCls}-fix-left-last`]: lastFixLeft && supportSticky.value,
  250. [`${cellPrefixCls}-fix-right`]: isFixRight && supportSticky.value,
  251. [`${cellPrefixCls}-fix-right-first`]: firstFixRight && supportSticky.value,
  252. [`${cellPrefixCls}-fix-right-last`]: lastFixRight && supportSticky.value,
  253. [`${cellPrefixCls}-ellipsis`]: ellipsis,
  254. [`${cellPrefixCls}-with-append`]: appendNode,
  255. [`${cellPrefixCls}-fix-sticky`]: (isFixLeft || isFixRight) && isSticky && supportSticky.value
  256. }, additionalProps.class, cellClassName),
  257. onMouseenter: e => {
  258. onMouseenter(e, mergedRowSpan);
  259. },
  260. onMouseleave,
  261. style: [additionalProps.style, alignStyle, fixedStyle, cellStyle]
  262. });
  263. return _createVNode(Component, _objectSpread(_objectSpread({}, componentProps), {}, {
  264. "ref": hoverRef
  265. }), {
  266. default: () => [appendNode, childNode, (_f = slots.dragHandle) === null || _f === void 0 ? void 0 : _f.call(slots)]
  267. });
  268. };
  269. }
  270. });