Table.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import { Fragment as _Fragment, createVNode as _createVNode, resolveDirective as _resolveDirective } from "vue";
  4. import Header from './Header/Header';
  5. import Body from './Body';
  6. import useColumns from './hooks/useColumns';
  7. import { useLayoutState, useTimeoutLock } from './hooks/useFrame';
  8. import { getPathValue, mergeObject, validateValue, getColumnsKey } from './utils/valueUtil';
  9. import useStickyOffsets from './hooks/useStickyOffsets';
  10. import ColGroup from './ColGroup';
  11. import Panel from './Panel';
  12. import Footer from './Footer';
  13. import { findAllChildrenKeys, renderExpandIcon } from './utils/expandUtil';
  14. import { getCellFixedInfo } from './utils/fixUtil';
  15. import StickyScrollBar from './stickyScrollBar';
  16. import useSticky from './hooks/useSticky';
  17. import FixedHolder from './FixedHolder';
  18. import { onUpdated, computed, defineComponent, nextTick, onMounted, reactive, ref, shallowRef, toRef, toRefs, watch, watchEffect } from 'vue';
  19. import { warning } from '../vc-util/warning';
  20. import { reactivePick } from '../_util/reactivePick';
  21. import useState from '../_util/hooks/useState';
  22. import { toPx } from '../_util/util';
  23. import isVisible from '../vc-util/Dom/isVisible';
  24. import { getTargetScrollBarSize } from '../_util/getScrollBarSize';
  25. import classNames from '../_util/classNames';
  26. import VCResizeObserver from '../vc-resize-observer';
  27. import { useProvideTable } from './context/TableContext';
  28. import { useProvideBody } from './context/BodyContext';
  29. import { useProvideResize } from './context/ResizeContext';
  30. import { useProvideSticky } from './context/StickyContext';
  31. import pickAttrs from '../_util/pickAttrs';
  32. import { useProvideExpandedRow } from './context/ExpandedRowContext';
  33. // Used for conditions cache
  34. const EMPTY_DATA = [];
  35. // Used for customize scroll
  36. const EMPTY_SCROLL_TARGET = {};
  37. export const INTERNAL_HOOKS = 'rc-table-internal-hook';
  38. export default defineComponent({
  39. name: 'VcTable',
  40. inheritAttrs: false,
  41. props: ['prefixCls', 'data', 'columns', 'rowKey', 'tableLayout', 'scroll', 'rowClassName', 'title', 'footer', 'id', 'showHeader', 'components', 'customRow', 'customHeaderRow', 'direction', 'expandFixed', 'expandColumnWidth', 'expandedRowKeys', 'defaultExpandedRowKeys', 'expandedRowRender', 'expandRowByClick', 'expandIcon', 'onExpand', 'onExpandedRowsChange', 'onUpdate:expandedRowKeys', 'defaultExpandAllRows', 'indentSize', 'expandIconColumnIndex', 'expandedRowClassName', 'childrenColumnName', 'rowExpandable', 'sticky', 'transformColumns', 'internalHooks', 'internalRefs', 'canExpandable', 'onUpdateInternalRefs', 'transformCellText'],
  42. emits: ['expand', 'expandedRowsChange', 'updateInternalRefs', 'update:expandedRowKeys'],
  43. setup(props, _ref) {
  44. let {
  45. attrs,
  46. slots,
  47. emit
  48. } = _ref;
  49. const mergedData = computed(() => props.data || EMPTY_DATA);
  50. const hasData = computed(() => !!mergedData.value.length);
  51. // ==================== Customize =====================
  52. const mergedComponents = computed(() => mergeObject(props.components, {}));
  53. const getComponent = (path, defaultComponent) => getPathValue(mergedComponents.value, path) || defaultComponent;
  54. const getRowKey = computed(() => {
  55. const rowKey = props.rowKey;
  56. if (typeof rowKey === 'function') {
  57. return rowKey;
  58. }
  59. return record => {
  60. const key = record && record[rowKey];
  61. if (process.env.NODE_ENV !== 'production') {
  62. warning(key !== undefined, 'Each record in table should have a unique `key` prop, or set `rowKey` to an unique primary key.');
  63. }
  64. return key;
  65. };
  66. });
  67. // ====================== Expand ======================
  68. const mergedExpandIcon = computed(() => props.expandIcon || renderExpandIcon);
  69. const mergedChildrenColumnName = computed(() => props.childrenColumnName || 'children');
  70. const expandableType = computed(() => {
  71. if (props.expandedRowRender) {
  72. return 'row';
  73. }
  74. /* eslint-disable no-underscore-dangle */
  75. /**
  76. * Fix https://github.com/ant-design/ant-design/issues/21154
  77. * This is a workaround to not to break current behavior.
  78. * We can remove follow code after final release.
  79. *
  80. * To other developer:
  81. * Do not use `__PARENT_RENDER_ICON__` in prod since we will remove this when refactor
  82. */
  83. if (props.canExpandable || mergedData.value.some(record => record && typeof record === 'object' && record[mergedChildrenColumnName.value])) {
  84. return 'nest';
  85. }
  86. /* eslint-enable */
  87. return false;
  88. });
  89. const innerExpandedKeys = shallowRef([]);
  90. const stop = watchEffect(() => {
  91. if (props.defaultExpandedRowKeys) {
  92. innerExpandedKeys.value = props.defaultExpandedRowKeys;
  93. }
  94. if (props.defaultExpandAllRows) {
  95. innerExpandedKeys.value = findAllChildrenKeys(mergedData.value, getRowKey.value, mergedChildrenColumnName.value);
  96. }
  97. });
  98. // defalutXxxx 仅仅第一次生效
  99. stop();
  100. const mergedExpandedKeys = computed(() => new Set(props.expandedRowKeys || innerExpandedKeys.value || []));
  101. const onTriggerExpand = record => {
  102. const key = getRowKey.value(record, mergedData.value.indexOf(record));
  103. let newExpandedKeys;
  104. const hasKey = mergedExpandedKeys.value.has(key);
  105. if (hasKey) {
  106. mergedExpandedKeys.value.delete(key);
  107. newExpandedKeys = [...mergedExpandedKeys.value];
  108. } else {
  109. newExpandedKeys = [...mergedExpandedKeys.value, key];
  110. }
  111. innerExpandedKeys.value = newExpandedKeys;
  112. emit('expand', !hasKey, record);
  113. emit('update:expandedRowKeys', newExpandedKeys);
  114. emit('expandedRowsChange', newExpandedKeys);
  115. };
  116. // Warning if use `expandedRowRender` and nest children in the same time
  117. if (process.env.NODE_ENV !== 'production' && props.expandedRowRender && mergedData.value.some(record => {
  118. return Array.isArray(record === null || record === void 0 ? void 0 : record[mergedChildrenColumnName.value]);
  119. })) {
  120. warning(false, '`expandedRowRender` should not use with nested Table');
  121. }
  122. const componentWidth = ref(0);
  123. const [columns, flattenColumns] = useColumns(_extends(_extends({}, toRefs(props)), {
  124. // children,
  125. expandable: computed(() => !!props.expandedRowRender),
  126. expandedKeys: mergedExpandedKeys,
  127. getRowKey,
  128. onTriggerExpand,
  129. expandIcon: mergedExpandIcon
  130. }), computed(() => props.internalHooks === INTERNAL_HOOKS ? props.transformColumns : null));
  131. const columnContext = computed(() => ({
  132. columns: columns.value,
  133. flattenColumns: flattenColumns.value
  134. }));
  135. // ====================== Scroll ======================
  136. const fullTableRef = ref();
  137. const scrollHeaderRef = ref();
  138. const scrollBodyRef = ref();
  139. const scrollBodySizeInfo = ref({
  140. scrollWidth: 0,
  141. clientWidth: 0
  142. });
  143. const scrollSummaryRef = ref();
  144. const [pingedLeft, setPingedLeft] = useState(false);
  145. const [pingedRight, setPingedRight] = useState(false);
  146. const [colsWidths, updateColsWidths] = useLayoutState(new Map());
  147. // Convert map to number width
  148. const colsKeys = computed(() => getColumnsKey(flattenColumns.value));
  149. const colWidths = computed(() => colsKeys.value.map(columnKey => colsWidths.value.get(columnKey)));
  150. const columnCount = computed(() => flattenColumns.value.length);
  151. const stickyOffsets = useStickyOffsets(colWidths, columnCount, toRef(props, 'direction'));
  152. const fixHeader = computed(() => props.scroll && validateValue(props.scroll.y));
  153. const horizonScroll = computed(() => props.scroll && validateValue(props.scroll.x) || Boolean(props.expandFixed));
  154. const fixColumn = computed(() => horizonScroll.value && flattenColumns.value.some(_ref2 => {
  155. let {
  156. fixed
  157. } = _ref2;
  158. return fixed;
  159. }));
  160. // Sticky
  161. const stickyRef = ref();
  162. const stickyState = useSticky(toRef(props, 'sticky'), toRef(props, 'prefixCls'));
  163. const summaryFixedInfos = reactive({});
  164. const fixFooter = computed(() => {
  165. const info = Object.values(summaryFixedInfos)[0];
  166. return (fixHeader.value || stickyState.value.isSticky) && info;
  167. });
  168. const summaryCollect = (uniKey, fixed) => {
  169. if (fixed) {
  170. summaryFixedInfos[uniKey] = fixed;
  171. } else {
  172. delete summaryFixedInfos[uniKey];
  173. }
  174. };
  175. // Scroll
  176. const scrollXStyle = ref({});
  177. const scrollYStyle = ref({});
  178. const scrollTableStyle = ref({});
  179. watchEffect(() => {
  180. if (fixHeader.value) {
  181. scrollYStyle.value = {
  182. overflowY: 'scroll',
  183. maxHeight: toPx(props.scroll.y)
  184. };
  185. }
  186. if (horizonScroll.value) {
  187. scrollXStyle.value = {
  188. overflowX: 'auto'
  189. };
  190. // When no vertical scrollbar, should hide it
  191. // https://github.com/ant-design/ant-design/pull/20705
  192. // https://github.com/ant-design/ant-design/issues/21879
  193. if (!fixHeader.value) {
  194. scrollYStyle.value = {
  195. overflowY: 'hidden'
  196. };
  197. }
  198. scrollTableStyle.value = {
  199. width: props.scroll.x === true ? 'auto' : toPx(props.scroll.x),
  200. minWidth: '100%'
  201. };
  202. }
  203. });
  204. const onColumnResize = (columnKey, width) => {
  205. if (isVisible(fullTableRef.value)) {
  206. updateColsWidths(widths => {
  207. if (widths.get(columnKey) !== width) {
  208. const newWidths = new Map(widths);
  209. newWidths.set(columnKey, width);
  210. return newWidths;
  211. }
  212. return widths;
  213. });
  214. }
  215. };
  216. const [setScrollTarget, getScrollTarget] = useTimeoutLock(null);
  217. function forceScroll(scrollLeft, target) {
  218. if (!target) {
  219. return;
  220. }
  221. if (typeof target === 'function') {
  222. target(scrollLeft);
  223. return;
  224. }
  225. const domTarget = target.$el || target;
  226. if (domTarget.scrollLeft !== scrollLeft) {
  227. // eslint-disable-next-line no-param-reassign
  228. domTarget.scrollLeft = scrollLeft;
  229. }
  230. }
  231. const onScroll = _ref3 => {
  232. let {
  233. currentTarget,
  234. scrollLeft
  235. } = _ref3;
  236. var _a;
  237. const isRTL = props.direction === 'rtl';
  238. const mergedScrollLeft = typeof scrollLeft === 'number' ? scrollLeft : currentTarget.scrollLeft;
  239. const compareTarget = currentTarget || EMPTY_SCROLL_TARGET;
  240. if (!getScrollTarget() || getScrollTarget() === compareTarget) {
  241. setScrollTarget(compareTarget);
  242. forceScroll(mergedScrollLeft, scrollHeaderRef.value);
  243. forceScroll(mergedScrollLeft, scrollBodyRef.value);
  244. forceScroll(mergedScrollLeft, scrollSummaryRef.value);
  245. forceScroll(mergedScrollLeft, (_a = stickyRef.value) === null || _a === void 0 ? void 0 : _a.setScrollLeft);
  246. }
  247. if (currentTarget) {
  248. const {
  249. scrollWidth,
  250. clientWidth
  251. } = currentTarget;
  252. if (isRTL) {
  253. setPingedLeft(-mergedScrollLeft < scrollWidth - clientWidth);
  254. setPingedRight(-mergedScrollLeft > 0);
  255. } else {
  256. setPingedLeft(mergedScrollLeft > 0);
  257. setPingedRight(mergedScrollLeft < scrollWidth - clientWidth);
  258. }
  259. }
  260. };
  261. const triggerOnScroll = () => {
  262. if (horizonScroll.value && scrollBodyRef.value) {
  263. onScroll({
  264. currentTarget: scrollBodyRef.value
  265. });
  266. } else {
  267. setPingedLeft(false);
  268. setPingedRight(false);
  269. }
  270. };
  271. let timtout;
  272. const updateWidth = width => {
  273. if (width !== componentWidth.value) {
  274. triggerOnScroll();
  275. componentWidth.value = fullTableRef.value ? fullTableRef.value.offsetWidth : width;
  276. }
  277. };
  278. const onFullTableResize = _ref4 => {
  279. let {
  280. width
  281. } = _ref4;
  282. clearTimeout(timtout);
  283. if (componentWidth.value === 0) {
  284. updateWidth(width);
  285. return;
  286. }
  287. timtout = setTimeout(() => {
  288. updateWidth(width);
  289. }, 100);
  290. };
  291. watch([horizonScroll, () => props.data, () => props.columns], () => {
  292. if (horizonScroll.value) {
  293. triggerOnScroll();
  294. }
  295. }, {
  296. flush: 'post'
  297. });
  298. const [scrollbarSize, setScrollbarSize] = useState(0);
  299. useProvideSticky();
  300. onMounted(() => {
  301. nextTick(() => {
  302. var _a, _b;
  303. triggerOnScroll();
  304. setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.value).width);
  305. scrollBodySizeInfo.value = {
  306. scrollWidth: ((_a = scrollBodyRef.value) === null || _a === void 0 ? void 0 : _a.scrollWidth) || 0,
  307. clientWidth: ((_b = scrollBodyRef.value) === null || _b === void 0 ? void 0 : _b.clientWidth) || 0
  308. };
  309. });
  310. });
  311. onUpdated(() => {
  312. nextTick(() => {
  313. var _a, _b;
  314. const scrollWidth = ((_a = scrollBodyRef.value) === null || _a === void 0 ? void 0 : _a.scrollWidth) || 0;
  315. const clientWidth = ((_b = scrollBodyRef.value) === null || _b === void 0 ? void 0 : _b.clientWidth) || 0;
  316. if (scrollBodySizeInfo.value.scrollWidth !== scrollWidth || scrollBodySizeInfo.value.clientWidth !== clientWidth) {
  317. scrollBodySizeInfo.value = {
  318. scrollWidth,
  319. clientWidth
  320. };
  321. }
  322. });
  323. });
  324. watchEffect(() => {
  325. if (props.internalHooks === INTERNAL_HOOKS && props.internalRefs) {
  326. props.onUpdateInternalRefs({
  327. body: scrollBodyRef.value ? scrollBodyRef.value.$el || scrollBodyRef.value : null
  328. });
  329. }
  330. }, {
  331. flush: 'post'
  332. });
  333. // Table layout
  334. const mergedTableLayout = computed(() => {
  335. if (props.tableLayout) {
  336. return props.tableLayout;
  337. }
  338. // https://github.com/ant-design/ant-design/issues/25227
  339. // When scroll.x is max-content, no need to fix table layout
  340. // it's width should stretch out to fit content
  341. if (fixColumn.value) {
  342. return props.scroll.x === 'max-content' ? 'auto' : 'fixed';
  343. }
  344. if (fixHeader.value || stickyState.value.isSticky || flattenColumns.value.some(_ref5 => {
  345. let {
  346. ellipsis
  347. } = _ref5;
  348. return ellipsis;
  349. })) {
  350. return 'fixed';
  351. }
  352. return 'auto';
  353. });
  354. const emptyNode = () => {
  355. var _a;
  356. return hasData.value ? null : ((_a = slots.emptyText) === null || _a === void 0 ? void 0 : _a.call(slots)) || 'No Data';
  357. };
  358. useProvideTable(reactive(_extends(_extends({}, toRefs(reactivePick(props, 'prefixCls', 'direction', 'transformCellText'))), {
  359. getComponent,
  360. scrollbarSize,
  361. fixedInfoList: computed(() => flattenColumns.value.map((_, colIndex) => getCellFixedInfo(colIndex, colIndex, flattenColumns.value, stickyOffsets.value, props.direction))),
  362. isSticky: computed(() => stickyState.value.isSticky),
  363. summaryCollect
  364. })));
  365. useProvideBody(reactive(_extends(_extends({}, toRefs(reactivePick(props, 'rowClassName', 'expandedRowClassName', 'expandRowByClick', 'expandedRowRender', 'expandIconColumnIndex', 'indentSize'))), {
  366. columns,
  367. flattenColumns,
  368. tableLayout: mergedTableLayout,
  369. expandIcon: mergedExpandIcon,
  370. expandableType,
  371. onTriggerExpand
  372. })));
  373. useProvideResize({
  374. onColumnResize
  375. });
  376. useProvideExpandedRow({
  377. componentWidth,
  378. fixHeader,
  379. fixColumn,
  380. horizonScroll
  381. });
  382. // Body
  383. const bodyTable = () => _createVNode(Body, {
  384. "data": mergedData.value,
  385. "measureColumnWidth": fixHeader.value || horizonScroll.value || stickyState.value.isSticky,
  386. "expandedKeys": mergedExpandedKeys.value,
  387. "rowExpandable": props.rowExpandable,
  388. "getRowKey": getRowKey.value,
  389. "customRow": props.customRow,
  390. "childrenColumnName": mergedChildrenColumnName.value
  391. }, {
  392. emptyNode
  393. });
  394. const bodyColGroup = () => _createVNode(ColGroup, {
  395. "colWidths": flattenColumns.value.map(_ref6 => {
  396. let {
  397. width
  398. } = _ref6;
  399. return width;
  400. }),
  401. "columns": flattenColumns.value
  402. }, null);
  403. return () => {
  404. var _a;
  405. const {
  406. prefixCls,
  407. scroll,
  408. tableLayout,
  409. direction,
  410. // Additional Part
  411. title = slots.title,
  412. footer = slots.footer,
  413. // Customize
  414. id,
  415. showHeader,
  416. customHeaderRow
  417. } = props;
  418. const {
  419. isSticky,
  420. offsetHeader,
  421. offsetSummary,
  422. offsetScroll,
  423. stickyClassName,
  424. container
  425. } = stickyState.value;
  426. const TableComponent = getComponent(['table'], 'table');
  427. const customizeScrollBody = getComponent(['body']);
  428. const summaryNode = (_a = slots.summary) === null || _a === void 0 ? void 0 : _a.call(slots, {
  429. pageData: mergedData.value
  430. });
  431. let groupTableNode = () => null;
  432. // Header props
  433. const headerProps = {
  434. colWidths: colWidths.value,
  435. columCount: flattenColumns.value.length,
  436. stickyOffsets: stickyOffsets.value,
  437. customHeaderRow,
  438. fixHeader: fixHeader.value,
  439. scroll
  440. };
  441. if (process.env.NODE_ENV !== 'production' && typeof customizeScrollBody === 'function' && hasData.value && !fixHeader.value) {
  442. warning(false, '`components.body` with render props is only work on `scroll.y`.');
  443. }
  444. if (fixHeader.value || isSticky) {
  445. // >>>>>> Fixed Header
  446. let bodyContent = () => null;
  447. if (typeof customizeScrollBody === 'function') {
  448. bodyContent = () => customizeScrollBody(mergedData.value, {
  449. scrollbarSize: scrollbarSize.value,
  450. ref: scrollBodyRef,
  451. onScroll
  452. });
  453. headerProps.colWidths = flattenColumns.value.map((_ref7, index) => {
  454. let {
  455. width
  456. } = _ref7;
  457. const colWidth = index === columns.value.length - 1 ? width - scrollbarSize.value : width;
  458. if (typeof colWidth === 'number' && !Number.isNaN(colWidth)) {
  459. return colWidth;
  460. }
  461. warning(false, 'When use `components.body` with render props. Each column should have a fixed `width` value.');
  462. return 0;
  463. });
  464. } else {
  465. bodyContent = () => _createVNode("div", {
  466. "style": _extends(_extends({}, scrollXStyle.value), scrollYStyle.value),
  467. "onScroll": onScroll,
  468. "ref": scrollBodyRef,
  469. "class": classNames(`${prefixCls}-body`)
  470. }, [_createVNode(TableComponent, {
  471. "style": _extends(_extends({}, scrollTableStyle.value), {
  472. tableLayout: mergedTableLayout.value
  473. })
  474. }, {
  475. default: () => [bodyColGroup(), bodyTable(), !fixFooter.value && summaryNode && _createVNode(Footer, {
  476. "stickyOffsets": stickyOffsets.value,
  477. "flattenColumns": flattenColumns.value
  478. }, {
  479. default: () => [summaryNode]
  480. })]
  481. })]);
  482. }
  483. // Fixed holder share the props
  484. const fixedHolderProps = _extends(_extends(_extends({
  485. noData: !mergedData.value.length,
  486. maxContentScroll: horizonScroll.value && scroll.x === 'max-content'
  487. }, headerProps), columnContext.value), {
  488. direction,
  489. stickyClassName,
  490. onScroll
  491. });
  492. groupTableNode = () => _createVNode(_Fragment, null, [showHeader !== false && _createVNode(FixedHolder, _objectSpread(_objectSpread({}, fixedHolderProps), {}, {
  493. "stickyTopOffset": offsetHeader,
  494. "class": `${prefixCls}-header`,
  495. "ref": scrollHeaderRef
  496. }), {
  497. default: fixedHolderPassProps => _createVNode(_Fragment, null, [_createVNode(Header, fixedHolderPassProps, null), fixFooter.value === 'top' && _createVNode(Footer, fixedHolderPassProps, {
  498. default: () => [summaryNode]
  499. })])
  500. }), bodyContent(), fixFooter.value && fixFooter.value !== 'top' && _createVNode(FixedHolder, _objectSpread(_objectSpread({}, fixedHolderProps), {}, {
  501. "stickyBottomOffset": offsetSummary,
  502. "class": `${prefixCls}-summary`,
  503. "ref": scrollSummaryRef
  504. }), {
  505. default: fixedHolderPassProps => _createVNode(Footer, fixedHolderPassProps, {
  506. default: () => [summaryNode]
  507. })
  508. }), isSticky && scrollBodyRef.value && _createVNode(StickyScrollBar, {
  509. "ref": stickyRef,
  510. "offsetScroll": offsetScroll,
  511. "scrollBodyRef": scrollBodyRef,
  512. "onScroll": onScroll,
  513. "container": container,
  514. "scrollBodySizeInfo": scrollBodySizeInfo.value
  515. }, null)]);
  516. } else {
  517. // >>>>>> Unique table
  518. groupTableNode = () => _createVNode("div", {
  519. "style": _extends(_extends({}, scrollXStyle.value), scrollYStyle.value),
  520. "class": classNames(`${prefixCls}-content`),
  521. "onScroll": onScroll,
  522. "ref": scrollBodyRef
  523. }, [_createVNode(TableComponent, {
  524. "style": _extends(_extends({}, scrollTableStyle.value), {
  525. tableLayout: mergedTableLayout.value
  526. })
  527. }, {
  528. default: () => [bodyColGroup(), showHeader !== false && _createVNode(Header, _objectSpread(_objectSpread({}, headerProps), columnContext.value), null), bodyTable(), summaryNode && _createVNode(Footer, {
  529. "stickyOffsets": stickyOffsets.value,
  530. "flattenColumns": flattenColumns.value
  531. }, {
  532. default: () => [summaryNode]
  533. })]
  534. })]);
  535. }
  536. const ariaProps = pickAttrs(attrs, {
  537. aria: true,
  538. data: true
  539. });
  540. const fullTable = () => _createVNode("div", _objectSpread(_objectSpread({}, ariaProps), {}, {
  541. "class": classNames(prefixCls, {
  542. [`${prefixCls}-rtl`]: direction === 'rtl',
  543. [`${prefixCls}-ping-left`]: pingedLeft.value,
  544. [`${prefixCls}-ping-right`]: pingedRight.value,
  545. [`${prefixCls}-layout-fixed`]: tableLayout === 'fixed',
  546. [`${prefixCls}-fixed-header`]: fixHeader.value,
  547. /** No used but for compatible */
  548. [`${prefixCls}-fixed-column`]: fixColumn.value,
  549. [`${prefixCls}-scroll-horizontal`]: horizonScroll.value,
  550. [`${prefixCls}-has-fix-left`]: flattenColumns.value[0] && flattenColumns.value[0].fixed,
  551. [`${prefixCls}-has-fix-right`]: flattenColumns.value[columnCount.value - 1] && flattenColumns.value[columnCount.value - 1].fixed === 'right',
  552. [attrs.class]: attrs.class
  553. }),
  554. "style": attrs.style,
  555. "id": id,
  556. "ref": fullTableRef
  557. }), [title && _createVNode(Panel, {
  558. "class": `${prefixCls}-title`
  559. }, {
  560. default: () => [title(mergedData.value)]
  561. }), _createVNode("div", {
  562. "class": `${prefixCls}-container`
  563. }, [groupTableNode()]), footer && _createVNode(Panel, {
  564. "class": `${prefixCls}-footer`
  565. }, {
  566. default: () => [footer(mergedData.value)]
  567. })]);
  568. if (horizonScroll.value) {
  569. return _createVNode(VCResizeObserver, {
  570. "onResize": onFullTableResize
  571. }, {
  572. default: fullTable
  573. });
  574. }
  575. return fullTable();
  576. };
  577. }
  578. });