diff --git a/.fatherrc.ts b/.fatherrc.ts index 205e08f0d..96268ae1e 100644 --- a/.fatherrc.ts +++ b/.fatherrc.ts @@ -1,10 +1,5 @@ import { defineConfig } from 'father'; export default defineConfig({ - platform: 'browser', - cjs: { output: 'lib' }, - esm: { - output: 'es', - alias: { 'rc-util/lib': 'rc-util/es' }, - }, -}); \ No newline at end of file + plugins: ['@rc-component/father-plugin'], +}); diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a13a97238..bd2a5f2e9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -108,6 +108,6 @@ jobs: key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} - name: coverage - run: npm test -- --coverage && bash <(curl -s https://codecov.io/bash) + run: npm run coverage && bash <(curl -s https://codecov.io/bash) needs: setup diff --git a/.gitignore b/.gitignore index 2c1b5ee4b..3111e398c 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ package-lock.json es/ .storybook .doc -!tests/__mocks__/rc-util/lib +!__mocks__/rc-util/lib examples/debug.tsx .history ~* @@ -42,4 +42,4 @@ examples/debug.tsx .umi-production .umi-test .env.local -.dumi \ No newline at end of file +.dumi diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..e48fbe548 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,11 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - init: npm install && npm run compile + command: npm run start + + diff --git a/README.md b/README.md index 25773c0c5..e068329fe 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ npm start ## Example -https://table.react-component.now.sh/ +https://table-react-component.vercel.app/ ## Usage @@ -115,6 +115,7 @@ React.render(<Table columns={columns} data={data} />, mountNode); | columns | Object[] | | The columns config of table, see table below | | components | Object | | Override table elements, see [#171](https://github.com/react-component/table/pull/171) for more details | | sticky | boolean \| {offsetHeader?: number, offsetScroll?: number, getContainer?: () => Window \| HTMLElement } | false | stick header and scroll bar | +| summary | (data: readonly RecordType[]) => React.ReactNode | - | `summary` attribute in `table` component is used to define the summary row. | ## Column Props @@ -129,11 +130,29 @@ React.render(<Table columns={columns} data={data} />, mountNode); | fixed | String \| Boolean | | this column will be fixed when table scroll horizontally: true or 'left' or 'right' | | align | String | | specify how cell content is aligned | | ellipsis | Boolean | | specify whether cell content be ellipsized | -| rowScope | 'row' \| 'rowgroup' | | Set scope attribute for all cells in this column | +| rowScope | 'row' \| 'rowgroup' | | Set scope attribute for all cells in this column | | onCell | Function(record, index) | | Set custom props per each cell. | | onHeaderCell | Function(record) | | Set custom props per each header cell. | | render | Function(value, row, index) | | The render function of cell, has three params: the text of this cell, the record of this row, the index of this row, it's return an object:{ children: value, props: { colSpan: 1, rowSpan:1 } } ==> 'children' is the text of this cell, props is some setting of this cell, eg: 'colspan' set td colspan, 'rowspan' set td rowspan | +## Summary Props + +### Table.Summary + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| key | String | | key of this summary | +| fixed | boolean \| 'top' \| 'bottom' | - | `true` fixes the summary row at the bottom of the table. `top` fixes the summary row at the top of the table, while `bottom` fixes it at the bottom. `undefined` or `false` makes the summary row scrollable along with the table. | + +### Table.Summary.Row + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| key | String | | key of this summary | +| className | String | - | className of this summary row | +| style | React.CSSProperties | - | style of this summary row | +| onClick | (e?: React.MouseEvent\<HTMLElement>) => void | - | The `onClick` attribute in `Table.Summary.Row` component can be used to set a click event handler for the summary row. | + ## License rc-table is released under the MIT license. diff --git a/tests/__mocks__/rc-util/lib/getScrollBarSize.ts b/__mocks__/rc-util/lib/getScrollBarSize.ts similarity index 100% rename from tests/__mocks__/rc-util/lib/getScrollBarSize.ts rename to __mocks__/rc-util/lib/getScrollBarSize.ts diff --git a/assets/index.less b/assets/index.less index ee168f9d3..f00920ba6 100644 --- a/assets/index.less +++ b/assets/index.less @@ -1,3 +1,5 @@ +@import 'virtual.less'; + @tablePrefixCls: rc-table; @text-color: #666; @font-size-base: 12px; @@ -55,9 +57,11 @@ // ================== Cell ================== &-cell { + background: #f4f4f4; + &-fix-left, &-fix-right { - z-index: 1; + z-index: 2; } &-fix-right:last-child:not(&-fix-sticky) { @@ -137,7 +141,7 @@ } &&-row-hover { - background: rgba(255, 0, 0, 0.05); + background: #fff4f4; } } @@ -284,6 +288,13 @@ border-bottom: 0; } + // ================= Caption ================== + &-caption { + padding: @cell-padding; + border-right: @border; + border-bottom: @border; + } + // ================= Footer ================= &-footer { padding: @cell-padding; diff --git a/assets/virtual.less b/assets/virtual.less new file mode 100644 index 000000000..e1f7ca52e --- /dev/null +++ b/assets/virtual.less @@ -0,0 +1,30 @@ +@import (reference) 'index.less'; + +.@{tablePrefixCls}-tbody-virtual { + * { + box-sizing: border-box; + } + + @border: 1px solid @border-color; + border-left: @border; + + .@{tablePrefixCls}-row { + display: flex; + box-sizing: border-box; + width: 100%; + } + + .@{tablePrefixCls}-row-extra { + .@{tablePrefixCls}-cell { + background: rgba(200, 200, 255) !important; + } + } + + .@{tablePrefixCls}-cell { + flex: 0 0 var(--virtual-width); + width: var(--virtual-width); + padding: 8px 16px; + border-right: @border; + border-bottom: @border; + } +} diff --git a/docs/demo/click-summary-row.md b/docs/demo/click-summary-row.md new file mode 100644 index 000000000..85ef862ed --- /dev/null +++ b/docs/demo/click-summary-row.md @@ -0,0 +1,8 @@ +--- +title: click-summary-row +nav: + title: Demo + path: /demo +--- + +<code src="../examples/click-summary-row.tsx"></code> diff --git a/docs/demo/virtual-columns.md b/docs/demo/virtual-columns.md new file mode 100644 index 000000000..c8637675e --- /dev/null +++ b/docs/demo/virtual-columns.md @@ -0,0 +1,8 @@ +--- +title: Virtual Columns +nav: + title: Demo + path: /demo +--- + +<code src="../examples/virtual-columns.tsx"></code> diff --git a/docs/demo/virtual.md b/docs/demo/virtual.md new file mode 100644 index 000000000..b9372a03b --- /dev/null +++ b/docs/demo/virtual.md @@ -0,0 +1,8 @@ +--- +title: Virtual +nav: + title: Demo + path: /demo +--- + +<code src="../examples/virtual.tsx"></code> diff --git a/docs/examples/click-summary-row.tsx b/docs/examples/click-summary-row.tsx new file mode 100644 index 000000000..e5b64c0e7 --- /dev/null +++ b/docs/examples/click-summary-row.tsx @@ -0,0 +1,54 @@ +/* eslint-disable no-console,func-names,react/no-multi-comp, no-nested-ternary */ +import type { ColumnType } from '@/interface'; +import Table from 'rc-table'; +import React from 'react'; +import '../../assets/index.less'; + +interface RecordType { + a: string; + b?: string; + c?: string; + d: number; + key: string; +} + +const columns: ColumnType<RecordType>[] = [ + { title: 'title1', dataIndex: 'a', key: 'a' }, + { title: 'title2', dataIndex: 'b', key: 'b' }, + { title: 'title3', dataIndex: 'c', key: 'c' }, + { title: 'title4', dataIndex: 'd', key: 'd' }, +]; + +const data: RecordType[] = [ + { a: 'cdd', b: 'edd12221', d: 3, key: '2' }, + { a: '133', c: 'edd12221', d: 2, key: '3' }, + { a: '133', c: 'edd12221', d: 2, key: '4' }, +]; + +const Demo = () => { + return ( + <div style={{ width: 800 }}> + <Table + columns={columns} + data={data} + summary={() => ( + <Table.Summary> + <Table.Summary.Row + onClick={e => { + e.stopPropagation(); + alert('click summary row will trigger the click event'); + }} + > + <Table.Summary.Cell index={0} /> + <Table.Summary.Cell index={1}>Summary</Table.Summary.Cell> + <Table.Summary.Cell index={3}>Content</Table.Summary.Cell> + <Table.Summary.Cell index={11}>Right</Table.Summary.Cell> + </Table.Summary.Row> + </Table.Summary> + )} + /> + </div> + ); +}; + +export default Demo; diff --git a/docs/examples/colspan-rowspan.tsx b/docs/examples/colspan-rowspan.tsx index d78ab1a8f..c2c830a9c 100644 --- a/docs/examples/colspan-rowspan.tsx +++ b/docs/examples/colspan-rowspan.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Table from 'rc-table'; import '../../assets/index.less'; -import { ColumnsType, RenderedCell } from '@/interface'; +import type { ColumnsType } from '@/interface'; interface RecordType { a?: string; diff --git a/docs/examples/fixedColumns.tsx b/docs/examples/fixedColumns.tsx index 273b980c8..fb1df6711 100644 --- a/docs/examples/fixedColumns.tsx +++ b/docs/examples/fixedColumns.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import type { ColumnType } from 'rc-table'; import Table from 'rc-table'; +import React from 'react'; import '../../assets/index.less'; -import { ColumnType } from '@/interface'; interface RecordType { a: string; diff --git a/docs/examples/fixedColumnsAndHeader.tsx b/docs/examples/fixedColumnsAndHeader.tsx index 8ef158c9e..022658c90 100644 --- a/docs/examples/fixedColumnsAndHeader.tsx +++ b/docs/examples/fixedColumnsAndHeader.tsx @@ -1,8 +1,6 @@ import React from 'react'; import Table from 'rc-table'; import '../../assets/index.less'; -import { ColumnsType } from '@/interface'; -import { useCheckbox } from './utils/useInput'; const columns = [ { diff --git a/docs/examples/scrollY.tsx b/docs/examples/scrollY.tsx index 83fc60691..8b30845f5 100644 --- a/docs/examples/scrollY.tsx +++ b/docs/examples/scrollY.tsx @@ -1,5 +1,5 @@ +import Table, { type Reference } from 'rc-table'; import React from 'react'; -import Table from 'rc-table'; import '../../assets/index.less'; const data = []; @@ -12,51 +12,63 @@ for (let i = 0; i < 10; i += 1) { }); } -class Demo extends React.Component { - state = { - showBody: true, - }; +const Test = () => { + const tblRef = React.useRef<Reference>(); + const [showBody, setShowBody] = React.useState(true); - toggleBody = () => { - this.setState(({ showBody }) => ({ showBody: !showBody })); + const toggleBody = () => { + setShowBody(!showBody); }; - render() { - const { showBody } = this.state; - const columns = [ - { title: 'title1', key: 'a', dataIndex: 'a', width: 100 }, - { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, - { title: 'title3', key: 'c', dataIndex: 'c', width: 200 }, - { - title: ( - <a onClick={this.toggleBody} href="#"> - {this.state.showBody ? '隐藏' : '显示'}体 - </a> - ), - key: 'x', - width: 200, - render() { - return <a href="#">Operations</a>; - }, + const columns = [ + { title: 'title1', key: 'a', dataIndex: 'a', width: 100 }, + { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, + { title: 'title3', key: 'c', dataIndex: 'c', width: 200 }, + { + title: ( + <a onClick={toggleBody} href="#"> + {showBody ? '隐藏' : '显示'}体 + </a> + ), + key: 'x', + width: 200, + render() { + return <a href="#">Operations</a>; }, - ]; - return ( + }, + ]; + + return ( + <div> + <h2>scroll body table</h2> + <button + onClick={() => { + tblRef.current?.scrollTo({ + top: 9999, + }); + }} + > + Scroll To End + </button> + <button + onClick={() => { + tblRef.current?.scrollTo({ + key: 9, + }); + }} + > + Scroll To key 9 + </button> <Table + ref={tblRef} columns={columns} data={data} scroll={{ y: 300 }} rowKey={record => record.key} - onRow={(record, index) => ({ style: { backgroundColor: "red" } })} + onRow={(record, index) => ({ style: { backgroundColor: 'red' } })} /> - ); - } -} - -const Test = () => ( - <div> - <h2>scroll body table</h2> - <Demo /> - </div> -); + </div> + ); +}; export default Test; diff --git a/docs/examples/virtual-columns.tsx b/docs/examples/virtual-columns.tsx new file mode 100644 index 000000000..b762ed4d7 --- /dev/null +++ b/docs/examples/virtual-columns.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import '../../assets/index.less'; +import { VirtualTable } from '../../src'; +import type { ColumnsType } from '../../src/interface'; + +interface RecordType { + a: string; + b?: string; + c?: string; +} + +const columns1: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', width: 100 }, + { + title: 'title13', + dataIndex: 'c', + }, +]; + +const columns2: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', width: 100 }, +]; + +const columns3: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 500 }, + { title: 'title2', dataIndex: 'b', width: 500 }, +]; + +const data: RecordType[] = new Array(4 * 10000).fill(null).map((_, index) => ({ + a: `a${index}`, + b: `b${index}`, + c: `c${index}`, +})); + +const Demo = () => { + const [columns, setColumns] = React.useState(columns1); + + return ( + <div style={{ width: 800, padding: `0 64px` }}> + <label> + <input type="radio" checked={columns === columns1} onChange={() => setColumns(columns1)} /> + Fill Rest + </label> + <label> + <input type="radio" checked={columns === columns2} onChange={() => setColumns(columns2)} /> + Stretch + </label> + <label> + <input type="radio" checked={columns === columns3} onChange={() => setColumns(columns3)} /> + Over Size + </label> + + <VirtualTable + getContainerWidth={(_, w) => w - 1} + columns={columns} + scroll={{ y: 200 }} + data={data} + rowKey="a" + /> + </div> + ); +}; + +export default Demo; diff --git a/docs/examples/virtual.tsx b/docs/examples/virtual.tsx new file mode 100644 index 000000000..b15d25515 --- /dev/null +++ b/docs/examples/virtual.tsx @@ -0,0 +1,245 @@ +import React from 'react'; +import '../../assets/index.less'; +import { VirtualTable } from '../../src'; +import type { ColumnsType, Reference } from '../../src/interface'; + +interface RecordType { + a: string; + b?: string; + c?: string; + d: number; + indexKey: string; +} + +const columns: ColumnsType = [ + // { title: 'title1', dataIndex: 'a', key: 'a', width: 100,}, + // { title: 'title1', dataIndex: 'a', key: 'a', width: 100, }, + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left', ellipsis: true }, + { + title: 'title3', + dataIndex: 'c', + key: 'c', + onCell: (_, index) => { + if (index % 4 === 0) { + return { + rowSpan: 3, + }; + } + + if (index % 4 === 3) { + return { + rowSpan: 1, + colSpan: 3, + }; + } + + return { + rowSpan: 0, + }; + }, + }, + { + title: 'title4', + key: 'd', + children: [ + // Children columns + { + title: 'title4-1', + dataIndex: 'b', + onCell: (_, index) => { + if (index % 4 === 0) { + return { + colSpan: 3, + }; + } + + if (index % 4 === 3) { + return { + colSpan: 0, + }; + } + }, + }, + { + title: 'title4-2', + dataIndex: 'b', + onCell: (_, index) => { + if (index % 4 === 0 || index % 4 === 3) { + return { + colSpan: 0, + }; + } + }, + }, + ], + }, + { + title: 'title6', + dataIndex: 'b', + key: 'f', + onCell: (_, index) => { + if (index % 4 === 0) { + return { + rowSpan: 0, + colSpan: 0, + }; + } + + if (index % 4 === 1) { + return { + rowSpan: 3, + }; + } + + return { + rowSpan: 0, + }; + }, + }, + { + title: ( + <div> + title7 + <br /> + <br /> + <br /> + Hello world! + </div> + ), + dataIndex: 'bk', + key: 'g', + }, + { + title: 'title8', + dataIndex: 'b', + onCell: (_, index) => { + if (index % 2 === 0) { + return { + rowSpan: 2, + colSpan: 2, + }; + } + + return { + rowSpan: 0, + }; + }, + }, + { + title: 'title9 i', + dataIndex: 'b', + key: 'i', + onCell: () => ({ + colSpan: 0, + }), + }, + { title: 'title10', dataIndex: 'b', key: 'j' }, + { + title: 'title11', + dataIndex: 'b', + key: 'k', + width: 50, + fixed: 'right', + onCell: (_, index) => { + return { + rowSpan: index % 2 === 0 ? 2 : 0, + // colSpan: 2, + }; + }, + }, + { + title: 'title12', + dataIndex: 'b', + key: 'l', + width: 100, + fixed: 'right', + onCell: () => { + return { + // colSpan: 0, + }; + }, + }, +]; + +export function cleanOnCell(cols: any = []) { + cols.forEach(col => { + delete (col as any).onCell; + + cleanOnCell((col as any).children); + }); +} +cleanOnCell(columns); + +const data: RecordType[] = new Array(4 * 10000).fill(null).map((_, index) => ({ + a: `a${index}`, + b: `b${index}`, + c: `c${index}`, + d: index, + bk: <strong>Hello</strong>, + indexKey: `${index}`, + // children: [ + // { + // indexKey: `${index}-1`, + // }, + // { + // indexKey: `${index}-2`, + // }, + // ], +})); + +const Demo = () => { + const tblRef = React.useRef<Reference>(); + + return ( + <div style={{ width: 800, padding: `0 64px` }}> + <button + onClick={() => { + tblRef.current?.scrollTo({ + top: 9999999999999, + }); + }} + > + Scroll To End + </button> + + <button + onClick={() => { + tblRef.current?.scrollTo({ + index: data.length - 1, + }); + }} + > + Scroll To Key + </button> + + <VirtualTable + columns={columns} + // expandedRowRender={({ b, c }) => b || c} + scroll={{ x: 1300, y: 200 }} + data={data} + // data={[]} + rowKey="indexKey" + expandable={{ + expandedRowRender: () => 2333, + columnWidth: 60, + expandedRowClassName: () => 'good-one', + }} + // onRow={() => ({ className: 'rowed' })} + rowClassName="nice-try" + getContainerWidth={(ele, width) => { + // Minus border + const borderWidth = getComputedStyle( + ele.querySelector('.rc-virtual-list'), + ).borderInlineStartWidth; + const mergedWidth = width - parseInt(borderWidth, 10); + + return mergedWidth; + }} + ref={tblRef} + /> + </div> + ); +}; + +export default Demo; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 86627c33b..000000000 --- a/jest.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - setupFiles: ['./tests/setup.js'], - snapshotSerializers: [require.resolve('enzyme-to-json/serializer')], -}; diff --git a/package.json b/package.json index bff90a751..675ad1bc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-table", - "version": "7.30.3", + "version": "7.36.0", "description": "table ui component for react", "engines": { "node": ">=8.x" @@ -40,8 +40,8 @@ "compile": "father build && lessc assets/index.less assets/index.css", "deploy": "npm run docs:build && npm run docs:deploy", "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", - "test": "rc-test", - "coverage": "rc-test --coverage", + "test": "vitest", + "coverage": "vitest run --coverage", "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish", "lint": "eslint src/ --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", @@ -54,18 +54,23 @@ }, "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/context": "^1.3.0", + "@rc-component/context": "^1.4.0", "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", - "rc-util": "^5.27.1" + "rc-util": "^5.37.0", + "rc-virtual-list": "^3.11.1" }, "devDependencies": { + "@rc-component/father-plugin": "^1.0.2", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^12.1.5", "@types/enzyme": "^3.10.5", - "@types/jest": "^28.1.2", "@types/react": "^17.0.35", "@types/react-dom": "^18.0.5", "@types/responselike": "^1.0.0", + "@types/testing-library__jest-dom": "^5.14.5", "@umijs/fabric": "^3.0.0", + "@vitest/coverage-c8": "^0.31.0", "cross-env": "^7.0.0", "dumi": "^2.1.3", "enzyme": "^3.1.0", @@ -78,13 +83,13 @@ "husky": "^8.0.3", "immutability-helper": "^3.0.0", "less": "^4.1.3", + "jsdom": "^22.0.0", "lint-staged": "^13.1.0", "np": "^7.0.0", "prettier": "^2.0.1", "rc-animate": "^3.0.0", "rc-dropdown": "~4.0.1", "rc-menu": "~9.6.0", - "rc-test": "^7.0.2", "rc-tooltip": "^5.2.1", "react": "^16.0.0", "react-dnd": "^2.5.4", @@ -95,7 +100,8 @@ "react-window": "^1.8.5", "regenerator-runtime": "^0.13.7", "styled-components": "^5.0.1", - "typescript": "^4.8.4" + "typescript": "^4.8.4", + "vitest": "^0.31.0" }, "lint-staged": { "**/*.{js,jsx,tsx,ts,md,json}": [ @@ -103,4 +109,4 @@ "git add" ] } -} \ No newline at end of file +} diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index 88d86e197..928d3b808 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -1,17 +1,10 @@ -import { responseImmutable, useContext } from '@rc-component/context'; import classNames from 'classnames'; import * as React from 'react'; import Cell from '../Cell'; -import TableContext from '../context/TableContext'; +import { responseImmutable } from '../context/TableContext'; import devRenderTimes from '../hooks/useRenderTimes'; -import type { - ColumnType, - CustomizeComponent, - GetComponentProps, - GetRowKey, - Key, -} from '../interface'; -import { getColumnsKey } from '../utils/valueUtil'; +import useRowInfo from '../hooks/useRowInfo'; +import type { ColumnType, CustomizeComponent, GetRowKey } from '../interface'; import ExpandedRow from './ExpandedRow'; export interface BodyRowProps<RecordType> { @@ -20,18 +13,77 @@ export interface BodyRowProps<RecordType> { renderIndex: number; className?: string; style?: React.CSSProperties; - expandedKeys: Set<Key>; rowComponent: CustomizeComponent; cellComponent: CustomizeComponent; scopeCellComponent: CustomizeComponent; - onRow: GetComponentProps<RecordType>; - rowExpandable: (record: RecordType) => boolean; indent?: number; rowKey: React.Key; getRowKey: GetRowKey<RecordType>; - childrenColumnName: string; } +// ================================================================================== +// == getCellProps == +// ================================================================================== +export function getCellProps<RecordType>( + rowInfo: ReturnType<typeof useRowInfo<RecordType>>, + column: ColumnType<RecordType>, + colIndex: number, + indent: number, + index: number, +) { + const { + record, + prefixCls, + columnsKey, + fixedInfoList, + expandIconColumnIndex, + nestExpandable, + indentSize, + expandIcon, + expanded, + hasNestChildren, + onTriggerExpand, + } = rowInfo; + + const key = columnsKey[colIndex]; + const fixedInfo = fixedInfoList[colIndex]; + + // ============= Used for nest expandable ============= + let appendCellNode: React.ReactNode; + if (colIndex === (expandIconColumnIndex || 0) && nestExpandable) { + appendCellNode = ( + <> + <span + style={{ paddingLeft: `${indentSize * indent}px` }} + className={`${prefixCls}-row-indent indent-level-${indent}`} + /> + {expandIcon({ + prefixCls, + expanded, + expandable: hasNestChildren, + record, + onExpand: onTriggerExpand, + })} + </> + ); + } + + let additionalCellProps: React.TdHTMLAttributes<HTMLElement>; + if (column.onCell) { + additionalCellProps = column.onCell(record, index); + } + + return { + key, + fixedInfo, + appendCellNode, + additionalCellProps: additionalCellProps || {}, + }; +} + +// ================================================================================== +// == getCellProps == +// ================================================================================== function BodyRow<RecordType extends { children?: readonly RecordType[] }>( props: BodyRowProps<RecordType>, ) { @@ -46,137 +98,58 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>( index, renderIndex, rowKey, - rowExpandable, - expandedKeys, - onRow, indent = 0, rowComponent: RowComponent, cellComponent, scopeCellComponent, - childrenColumnName, } = props; + const rowInfo = useRowInfo(record, rowKey, index, indent); const { prefixCls, - fixedInfoList, flattenColumns, - expandableType, - expandRowByClick, - onTriggerExpand, - rowClassName, expandedRowClassName, - indentSize, - expandIcon, expandedRowRender, - expandIconColumnIndex, - } = useContext(TableContext, [ - 'prefixCls', - 'fixedInfoList', - 'flattenColumns', - 'expandableType', - 'expandRowByClick', - 'onTriggerExpand', - 'rowClassName', - 'expandedRowClassName', - 'indentSize', - 'expandIcon', - 'expandedRowRender', - 'expandIconColumnIndex', - ]); - const [expandRended, setExpandRended] = React.useState(false); + rowProps, + + // Misc + expanded, + rowSupportExpand, + } = rowInfo; + + // Force render expand row if expanded before + const expandedRef = React.useRef(false); + expandedRef.current ||= expanded; if (process.env.NODE_ENV !== 'production') { devRenderTimes(props); } - const expanded = expandedKeys && expandedKeys.has(rowKey); - - React.useEffect(() => { - if (expanded) { - setExpandRended(true); - } - }, [expanded]); - - const rowSupportExpand = expandableType === 'row' && (!rowExpandable || rowExpandable(record)); - // Only when row is not expandable and `children` exist in record - const nestExpandable = expandableType === 'nest'; - const hasNestChildren = childrenColumnName && record && record[childrenColumnName]; - const mergedExpandable = rowSupportExpand || nestExpandable; - - // ======================== Expandable ========================= - const onExpandRef = React.useRef(onTriggerExpand); - onExpandRef.current = onTriggerExpand; - - const onInternalTriggerExpand = (...args: Parameters<typeof onTriggerExpand>) => { - onExpandRef.current(...args); - }; - - // =========================== onRow =========================== - const additionalProps = onRow?.(record, index); - - const onClick: React.MouseEventHandler<HTMLElement> = (event, ...args) => { - if (expandRowByClick && mergedExpandable) { - onInternalTriggerExpand(record, event); - } - - additionalProps?.onClick?.(event, ...args); - }; - // ======================== Base tr row ======================== - let computeRowClassName: string; - if (typeof rowClassName === 'string') { - computeRowClassName = rowClassName; - } else if (typeof rowClassName === 'function') { - computeRowClassName = rowClassName(record, index, indent); - } - - const columnsKey = getColumnsKey(flattenColumns); const baseRowNode = ( <RowComponent - {...additionalProps} + {...rowProps} data-row-key={rowKey} className={classNames( className, `${prefixCls}-row`, `${prefixCls}-row-level-${indent}`, - computeRowClassName, - additionalProps && additionalProps.className, + rowProps?.className, )} style={{ ...style, - ...(additionalProps ? additionalProps.style : null), + ...rowProps?.style, }} - onClick={onClick} > {flattenColumns.map((column: ColumnType<RecordType>, colIndex) => { const { render, dataIndex, className: columnClassName } = column; - const key = columnsKey[colIndex]; - const fixedInfo = fixedInfoList[colIndex]; - - // ============= Used for nest expandable ============= - let appendCellNode: React.ReactNode; - if (colIndex === (expandIconColumnIndex || 0) && nestExpandable) { - appendCellNode = ( - <> - <span - style={{ paddingLeft: `${indentSize * indent}px` }} - className={`${prefixCls}-row-indent indent-level-${indent}`} - /> - {expandIcon({ - prefixCls, - expanded, - expandable: hasNestChildren, - record, - onExpand: onInternalTriggerExpand, - })} - </> - ); - } - - let additionalCellProps: React.HTMLAttributes<HTMLElement>; - if (column.onCell) { - additionalCellProps = column.onCell(record, index); - } + const { key, fixedInfo, appendCellNode, additionalCellProps } = getCellProps( + rowInfo, + column, + colIndex, + indent, + index, + ); return ( <Cell @@ -193,7 +166,6 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>( dataIndex={dataIndex} render={render} shouldCellUpdate={column.shouldCellUpdate} - expanded={appendCellNode && expanded} {...fixedInfo} appendNode={appendCellNode} additionalProps={additionalCellProps} @@ -205,7 +177,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>( // ======================== Expand Row ========================= let expandRowNode: React.ReactElement; - if (rowSupportExpand && (expandRended || expanded)) { + if (rowSupportExpand && (expandedRef.current || expanded)) { const expandContent = expandedRowRender(record, index, indent + 1, expanded); const computedExpandedRowClassName = expandedRowClassName && expandedRowClassName(record, index, indent); diff --git a/src/Body/ExpandedRow.tsx b/src/Body/ExpandedRow.tsx index daa1fc15b..22cb4032a 100644 --- a/src/Body/ExpandedRow.tsx +++ b/src/Body/ExpandedRow.tsx @@ -40,7 +40,7 @@ function ExpandedRow(props: ExpandedRowProps) { // Cache render node let contentNode = children; - if (isEmpty ? horizonScroll : fixColumn) { + if (isEmpty ? horizonScroll && componentWidth : fixColumn) { contentNode = ( <div style={{ @@ -51,7 +51,7 @@ function ExpandedRow(props: ExpandedRowProps) { }} className={`${prefixCls}-expanded-row-fixed`} > - {componentWidth !== 0 && contentNode} + {contentNode} </div> ); } diff --git a/src/Body/index.tsx b/src/Body/index.tsx index 489ead4a8..1a3c77a13 100644 --- a/src/Body/index.tsx +++ b/src/Body/index.tsx @@ -1,11 +1,10 @@ -import { responseImmutable, useContext } from '@rc-component/context'; +import { useContext } from '@rc-component/context'; import * as React from 'react'; import type { PerfRecord } from '../context/PerfContext'; import PerfContext from '../context/PerfContext'; -import TableContext from '../context/TableContext'; +import TableContext, { responseImmutable } from '../context/TableContext'; import useFlattenRecords from '../hooks/useFlattenRecords'; import devRenderTimes from '../hooks/useRenderTimes'; -import type { GetComponentProps, GetRowKey, Key } from '../interface'; import { getColumnsKey } from '../utils/valueUtil'; import BodyRow from './BodyRow'; import ExpandedRow from './ExpandedRow'; @@ -13,13 +12,7 @@ import MeasureRow from './MeasureRow'; export interface BodyProps<RecordType> { data: readonly RecordType[]; - getRowKey: GetRowKey<RecordType>; measureColumnWidth: boolean; - expandedKeys: Set<Key>; - onRow: GetComponentProps<RecordType>; - rowExpandable: (record: RecordType) => boolean; - emptyNode: React.ReactNode; - childrenColumnName: string; } function Body<RecordType>(props: BodyProps<RecordType>) { @@ -27,22 +20,26 @@ function Body<RecordType>(props: BodyProps<RecordType>) { devRenderTimes(props); } + const { data, measureColumnWidth } = props; + const { - data, + prefixCls, + getComponent, + onColumnResize, + flattenColumns, getRowKey, - measureColumnWidth, expandedKeys, - onRow, - rowExpandable, - emptyNode, childrenColumnName, - } = props; - - const { prefixCls, getComponent, onColumnResize, flattenColumns } = useContext(TableContext, [ + emptyNode, + } = useContext(TableContext, [ 'prefixCls', 'getComponent', 'onColumnResize', 'flattenColumns', + 'getRowKey', + 'expandedKeys', + 'childrenColumnName', + 'emptyNode', ]); const flattenData: { record: RecordType; indent: number; index: number }[] = @@ -76,11 +73,7 @@ function Body<RecordType>(props: BodyProps<RecordType>) { rowComponent={trComponent} cellComponent={tdComponent} scopeCellComponent={thComponent} - expandedKeys={expandedKeys} - onRow={onRow} getRowKey={getRowKey} - rowExpandable={rowExpandable} - childrenColumnName={childrenColumnName} indent={indent} /> ); diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index ce727f7ef..27f552690 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -143,13 +143,12 @@ function Cell<RecordType>(props: CellProps<RecordType>) { } if (isFixRight) { fixedStyle.position = 'sticky'; - fixedStyle.right = fixRight as number; } // ================ RowSpan & ColSpan ================= - const mergedColSpan = legacyCellProps?.colSpan ?? colSpan ?? additionalProps.colSpan ?? 1; - const mergedRowSpan = legacyCellProps?.rowSpan ?? rowSpan ?? additionalProps.rowSpan ?? 1; + const mergedColSpan = legacyCellProps?.colSpan ?? additionalProps.colSpan ?? colSpan ?? 1; + const mergedRowSpan = legacyCellProps?.rowSpan ?? additionalProps.rowSpan ?? rowSpan ?? 1; // ====================== Hover ======================= const [hovering, onHover] = useHoverState(index, mergedRowSpan); @@ -212,9 +211,9 @@ function Cell<RecordType>(props: CellProps<RecordType>) { } const mergedStyle = { + ...fixedStyle, ...additionalProps.style, ...alignStyle, - ...fixedStyle, ...legacyCellProps?.style, }; diff --git a/src/Cell/useCellRender.ts b/src/Cell/useCellRender.ts index acae182a6..825e6c343 100644 --- a/src/Cell/useCellRender.ts +++ b/src/Cell/useCellRender.ts @@ -1,4 +1,3 @@ -import { useImmutableMark } from '@rc-component/context'; import useMemo from 'rc-util/lib/hooks/useMemo'; import isEqual from 'rc-util/lib/isEqual'; import getValue from 'rc-util/lib/utils/get'; @@ -7,6 +6,7 @@ import * as React from 'react'; import PerfContext from '../context/PerfContext'; import type { CellType, ColumnType, DataIndex, RenderedCell } from '../interface'; import { validateValue } from '../utils/valueUtil'; +import { useImmutableMark } from '../context/TableContext'; function isRenderCell<RecordType>( data: React.ReactNode | RenderedCell<RecordType>, diff --git a/src/FixedHolder/index.tsx b/src/FixedHolder/index.tsx index 7d60c7ea0..b7e48ce7f 100644 --- a/src/FixedHolder/index.tsx +++ b/src/FixedHolder/index.tsx @@ -96,7 +96,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>( // Check if all flattenColumns has width const allFlattenColumnsWithWidth = React.useMemo( - () => flattenColumns.every(column => column.width >= 0), + () => flattenColumns.every(column => column.width), [flattenColumns], ); diff --git a/src/Footer/Row.tsx b/src/Footer/Row.tsx index 0ca5457ea..541e0e553 100644 --- a/src/Footer/Row.tsx +++ b/src/Footer/Row.tsx @@ -4,6 +4,7 @@ export interface FooterRowProps { children?: React.ReactNode; className?: string; style?: React.CSSProperties; + onClick?: (e?: React.MouseEvent<HTMLElement>) => void; } export default function FooterRow({ children, ...props }: FooterRowProps) { diff --git a/src/Footer/index.tsx b/src/Footer/index.tsx index 73c2b51ce..c2e5986a7 100644 --- a/src/Footer/index.tsx +++ b/src/Footer/index.tsx @@ -1,6 +1,6 @@ -import { responseImmutable, useContext } from '@rc-component/context'; +import { useContext } from '@rc-component/context'; import * as React from 'react'; -import TableContext from '../context/TableContext'; +import TableContext, { responseImmutable } from '../context/TableContext'; import devRenderTimes from '../hooks/useRenderTimes'; import type { ColumnsType, ColumnType, StickyOffsets } from '../interface'; import Summary from './Summary'; @@ -32,7 +32,7 @@ function Footer<RecordType>(props: FooterProps<RecordType>) { stickyOffsets, flattenColumns, scrollColumnIndex: scrollColumn?.scrollbar ? lastColumnIndex : null, - columns + columns, }), [scrollColumn, flattenColumns, lastColumnIndex, stickyOffsets, columns], ); diff --git a/src/Header/Header.tsx b/src/Header/Header.tsx index 6ec22086b..d7466d503 100644 --- a/src/Header/Header.tsx +++ b/src/Header/Header.tsx @@ -1,6 +1,6 @@ -import { responseImmutable, useContext } from '@rc-component/context'; +import { useContext } from '@rc-component/context'; import * as React from 'react'; -import TableContext from '../context/TableContext'; +import TableContext, { responseImmutable } from '../context/TableContext'; import devRenderTimes from '../hooks/useRenderTimes'; import type { CellType, diff --git a/src/Table.tsx b/src/Table.tsx index 8e74719e8..7b7751554 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -24,7 +24,6 @@ * - All expanded props, move into expandable */ -import { makeImmutable } from '@rc-component/context'; import type { CompareProps } from '@rc-component/context/lib/Immutable'; import classNames from 'classnames'; import ResizeObserver from 'rc-resize-observer'; @@ -38,8 +37,8 @@ import warning from 'rc-util/lib/warning'; import * as React from 'react'; import Body from './Body'; import ColGroup from './ColGroup'; -import { EXPAND_COLUMN } from './constant'; -import TableContext from './context/TableContext'; +import { EXPAND_COLUMN, INTERNAL_HOOKS } from './constant'; +import TableContext, { makeImmutable } from './context/TableContext'; import type { FixedHeaderProps } from './FixedHolder'; import FixedHolder from './FixedHolder'; import Footer, { FooterComponents } from './Footer'; @@ -65,6 +64,7 @@ import type { GetRowKey, LegacyExpandableProps, PanelRender, + Reference, RowClassName, TableComponents, TableLayout, @@ -76,14 +76,14 @@ import Column from './sugar/Column'; import ColumnGroup from './sugar/ColumnGroup'; import { getColumnsKey, validateValue } from './utils/valueUtil'; +export const DEFAULT_PREFIX = 'rc-table'; + // Used for conditions cache const EMPTY_DATA = []; // Used for customize scroll const EMPTY_SCROLL_TARGET = {}; -export const INTERNAL_HOOKS = 'rc-table-internal-hook'; - export interface TableProps<RecordType = unknown> extends Omit<LegacyExpandableProps<RecordType>, 'showExpandColumn'> { prefixCls?: string; @@ -92,7 +92,7 @@ export interface TableProps<RecordType = unknown> children?: React.ReactNode; data?: readonly RecordType[]; columns?: ColumnsType<RecordType>; - rowKey?: string | GetRowKey<RecordType>; + rowKey?: string | keyof RecordType | GetRowKey<RecordType>; tableLayout?: TableLayout; // Fixed Columns @@ -107,7 +107,7 @@ export interface TableProps<RecordType = unknown> // Additional Part footer?: PanelRender<RecordType>; summary?: (data: readonly RecordType[]) => React.ReactNode; - caption?: string | React.ReactNode; + caption?: React.ReactNode; // Customize id?: string; @@ -119,6 +119,8 @@ export interface TableProps<RecordType = unknown> direction?: Direction; + sticky?: boolean | TableSticky; + // =================================== Internal =================================== /** * @private Internal usage, may remove by refactor. Should always use `columns` instead. @@ -135,6 +137,23 @@ export interface TableProps<RecordType = unknown> // Used for antd table transform column with additional column transformColumns?: (columns: ColumnsType<RecordType>) => ColumnsType<RecordType>; + /** + * @private Internal usage, may remove by refactor. + * + * !!! DO NOT USE IN PRODUCTION ENVIRONMENT !!! + */ + // Force trade scrollbar as 0 size. + // Force column to be average width if not set + tailor?: boolean; + + /** + * @private Internal usage, may remove by refactor. + * + * !!! DO NOT USE IN PRODUCTION ENVIRONMENT !!! + */ + // Pass the way to get real width. e.g. exclude the border width + getContainerWidth?: (ele: HTMLElement, width: number) => number; + /** * @private Internal usage, may remove by refactor. * @@ -143,18 +162,19 @@ export interface TableProps<RecordType = unknown> internalRefs?: { body: React.MutableRefObject<HTMLDivElement>; }; - - sticky?: boolean | TableSticky; } function defaultEmpty() { return 'No Data'; } -function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<RecordType>) { +function Table<RecordType extends DefaultRecordType>( + tableProps: TableProps<RecordType>, + ref: React.Ref<Reference>, +) { const props = { rowKey: 'key', - prefixCls: 'rc-table', + prefixCls: DEFAULT_PREFIX, emptyText: defaultEmpty, ...tableProps, }; @@ -188,6 +208,8 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco internalHooks, transformColumns, internalRefs, + tailor, + getContainerWidth, sticky, } = props; @@ -195,6 +217,8 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco const mergedData = data || EMPTY_DATA; const hasData = !!mergedData.length; + const useInternalHooks = internalHooks === INTERNAL_HOOKS; + // ===================== Warning ====================== if (process.env.NODE_ENV !== 'production') { [ @@ -237,6 +261,8 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco }; }, [rowKey]); + const customizeScrollBody = getComponent(['body']) as CustomizeScrollBody<RecordType>; + // ====================== Hover ======================= const [startRow, endRow, onHover] = useHover(); @@ -251,9 +277,10 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco ] = useExpand(props, mergedData, getRowKey); // ====================== Column ====================== + const scrollX = scroll?.x; const [componentWidth, setComponentWidth] = React.useState(0); - const [columns, flattenColumns] = useColumns( + const [columns, flattenColumns, flattenScrollX] = useColumns( { ...props, ...expandableConfig, @@ -266,9 +293,12 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco expandIcon: mergedExpandIcon, expandIconColumnIndex: expandableConfig.expandIconColumnIndex, direction, + scrollWidth: useInternalHooks && tailor && typeof scrollX === 'number' ? scrollX : null, + clientWidth: componentWidth, }, - internalHooks === INTERNAL_HOOKS ? transformColumns : null, + useInternalHooks ? transformColumns : null, ); + const mergedScrollX = flattenScrollX ?? scrollX; const columnContext = React.useMemo( () => ({ @@ -278,11 +308,37 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco [columns, flattenColumns], ); - // ====================== Scroll ====================== + // ======================= Refs ======================= const fullTableRef = React.useRef<HTMLDivElement>(); const scrollHeaderRef = React.useRef<HTMLDivElement>(); const scrollBodyRef = React.useRef<HTMLDivElement>(); const scrollBodyContainerRef = React.useRef<HTMLDivElement>(); + + React.useImperativeHandle(ref, () => { + return { + nativeElement: fullTableRef.current, + scrollTo: config => { + if (scrollBodyRef.current instanceof HTMLElement) { + // Native scroll + const { index, top, key } = config; + + if (top) { + scrollBodyRef.current?.scrollTo({ + top, + }); + } else { + const mergedKey = key ?? getRowKey(mergedData[index]); + scrollBodyRef.current.querySelector(`[data-row-key="${mergedKey}"]`)?.scrollIntoView(); + } + } else if ((scrollBodyRef.current as any)?.scrollTo) { + // Pass to proxy + (scrollBodyRef.current as any).scrollTo(config); + } + }, + }; + }); + + // ====================== Scroll ====================== const scrollSummaryRef = React.useRef<HTMLDivElement>(); const [pingedLeft, setPingedLeft] = React.useState(false); const [pingedRight, setPingedRight] = React.useState(false); @@ -294,7 +350,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco const colWidths = React.useMemo(() => pureColWidths, [pureColWidths.join('_')]); const stickyOffsets = useStickyOffsets(colWidths, flattenColumns.length, direction); const fixHeader = scroll && validateValue(scroll.y); - const horizonScroll = (scroll && validateValue(scroll.x)) || Boolean(expandableConfig.fixed); + const horizonScroll = (scroll && validateValue(mergedScrollX)) || Boolean(expandableConfig.fixed); const fixColumn = horizonScroll && flattenColumns.some(({ fixed }) => fixed); // Sticky @@ -331,7 +387,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco scrollYStyle = { overflowY: 'hidden' }; } scrollTableStyle = { - width: scroll?.x === true ? 'auto' : scroll?.x, + width: mergedScrollX === true ? 'auto' : mergedScrollX, minWidth: '100%', }; } @@ -386,8 +442,9 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco forceScroll(mergedScrollLeft, stickyRef.current?.setScrollLeft); } - if (currentTarget) { - const { scrollWidth, clientWidth } = currentTarget; + const measureTarget = currentTarget || scrollHeaderRef.current; + if (measureTarget) { + const { scrollWidth, clientWidth } = measureTarget; // There is no space to scroll if (scrollWidth === clientWidth) { setPingedLeft(false); @@ -415,9 +472,14 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco }; const onFullTableResize = ({ width }) => { - if (width !== componentWidth) { + let mergedWidth = fullTableRef.current ? fullTableRef.current.offsetWidth : width; + if (useInternalHooks && getContainerWidth && fullTableRef.current) { + mergedWidth = getContainerWidth(fullTableRef.current, mergedWidth) || mergedWidth; + } + + if (mergedWidth !== componentWidth) { triggerOnScroll(); - setComponentWidth(fullTableRef.current ? fullTableRef.current.offsetWidth : width); + setComponentWidth(mergedWidth); } }; @@ -439,17 +501,19 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco const [supportSticky, setSupportSticky] = React.useState(true); // Only IE not support, we mark as support first React.useEffect(() => { - if (scrollBodyRef.current instanceof Element) { - setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width); - } else { - setScrollbarSize(getTargetScrollBarSize(scrollBodyContainerRef.current).width); + if (!tailor || !useInternalHooks) { + if (scrollBodyRef.current instanceof Element) { + setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width); + } else { + setScrollbarSize(getTargetScrollBarSize(scrollBodyContainerRef.current).width); + } } setSupportSticky(isStyleSupport('position', 'sticky')); }, []); // ================== INTERNAL HOOKS ================== React.useEffect(() => { - if (internalHooks === INTERNAL_HOOKS && internalRefs) { + if (useInternalHooks && internalRefs) { internalRefs.body.current = scrollBodyRef.current; } }); @@ -485,7 +549,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco // When scroll.x is max-content, no need to fix table layout // it's width should stretch out to fit content if (fixColumn) { - return scroll?.x === 'max-content' ? 'auto' : 'fixed'; + return mergedScrollX === 'max-content' ? 'auto' : 'fixed'; } if (fixHeader || isSticky || flattenColumns.some(({ ellipsis }) => ellipsis)) { return 'fixed'; @@ -519,16 +583,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco // Body const bodyTable = ( - <Body - data={mergedData} - measureColumnWidth={fixHeader || horizonScroll || isSticky} - expandedKeys={mergedExpandedKeys} - rowExpandable={expandableConfig.rowExpandable} - getRowKey={getRowKey} - onRow={onRow} - emptyNode={emptyNode} - childrenColumnName={mergedChildrenColumnName} - /> + <Body data={mergedData} measureColumnWidth={fixHeader || horizonScroll || isSticky} /> ); const bodyColGroup = ( @@ -540,17 +595,6 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco <caption className={`${prefixCls}-caption`}>{caption}</caption> ) : undefined; - const customizeScrollBody = getComponent(['body']) as CustomizeScrollBody<RecordType>; - - if ( - process.env.NODE_ENV !== 'production' && - typeof customizeScrollBody === 'function' && - hasData && - !fixHeader - ) { - warning(false, '`components.body` with render props is only work on `scroll.y`.'); - } - const dataProps = pickAttrs(props, { data: true }); const ariaProps = pickAttrs(props, { aria: true }); @@ -566,15 +610,18 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco }); headerProps.colWidths = flattenColumns.map(({ width }, index) => { - const colWidth = index === columns.length - 1 ? (width as number) - scrollbarSize : width; + const colWidth = + index === flattenColumns.length - 1 ? (width as number) - scrollbarSize : width; if (typeof colWidth === 'number' && !Number.isNaN(colWidth)) { return colWidth; } - warning( - false, - 'When use `components.body` with render props. Each column should have a fixed `width` value.', - ); + if (process.env.NODE_ENV !== 'production') { + warning( + props.columns.length === 0, + 'When use `components.body` with render props. Each column should have a fixed `width` value.', + ); + } return 0; }) as number[]; } else { @@ -599,7 +646,11 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco {bodyColGroup} {bodyTable} {!fixFooter && summaryNode && ( - <Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns} columns={columns}> + <Footer + stickyOffsets={stickyOffsets} + flattenColumns={flattenColumns} + columns={columns} + > {summaryNode} </Footer> )} @@ -611,7 +662,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco // Fixed holder share the props const fixedHolderProps = { noData: !mergedData.length, - maxContentScroll: horizonScroll && scroll.x === 'max-content', + maxContentScroll: horizonScroll && mergedScrollX === 'max-content', ...headerProps, ...columnContext, direction, @@ -648,7 +699,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco </FixedHolder> )} - {isSticky && ( + {isSticky && scrollBodyRef.current && scrollBodyRef.current instanceof Element && ( <StickyScrollBar ref={stickyRef} offsetScroll={offsetScroll} @@ -726,6 +777,9 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco const TableContextValue = React.useMemo( () => ({ + // Scroll + scrollX: mergedScrollX, + // Table prefixCls, getComponent, @@ -741,7 +795,6 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco horizonScroll, // Body - tableLayout: mergedTableLayout, rowClassName, expandedRowClassName: expandableConfig.expandedRowClassName, @@ -753,6 +806,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco expandIconColumnIndex: expandableConfig.expandIconColumnIndex, indentSize: expandableConfig.indentSize, allColumnsFixedLeft: flattenColumns.every(col => col.fixed === 'left'), + emptyNode, // Column columns, @@ -763,8 +817,17 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco hoverStartRow: startRow, hoverEndRow: endRow, onHover, + rowExpandable: expandableConfig.rowExpandable, + onRow, + + getRowKey, + expandedKeys: mergedExpandedKeys, + childrenColumnName: mergedChildrenColumnName, }), [ + // Scroll + mergedScrollX, + // Table prefixCls, getComponent, @@ -790,6 +853,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco onTriggerExpand, expandableConfig.expandIconColumnIndex, expandableConfig.indentSize, + emptyNode, // Column columns, @@ -800,19 +864,38 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco startRow, endRow, onHover, + expandableConfig.rowExpandable, + onRow, + + getRowKey, + mergedExpandedKeys, + mergedChildrenColumnName, ], ); return <TableContext.Provider value={TableContextValue}>{fullTable}</TableContext.Provider>; } -export function genTable(shouldTriggerRender?: CompareProps<typeof Table>): typeof Table { - return makeImmutable(Table, shouldTriggerRender); +export type ForwardGenericTable = (<RecordType extends DefaultRecordType = any>( + props: TableProps<RecordType> & { ref?: React.Ref<Reference> }, +) => React.ReactElement) & { + displayName?: string; +}; + +const RefTable = React.forwardRef(Table) as ForwardGenericTable; + +if (process.env.NODE_ENV !== 'production') { + RefTable.displayName = 'Table'; +} + +export function genTable(shouldTriggerRender?: CompareProps<typeof Table>) { + return makeImmutable(RefTable, shouldTriggerRender) as ForwardGenericTable; } const ImmutableTable = genTable(); type ImmutableTableType = typeof ImmutableTable & { EXPAND_COLUMN: typeof EXPAND_COLUMN; + INTERNAL_HOOKS: typeof INTERNAL_HOOKS; Column: typeof Column; ColumnGroup: typeof ColumnGroup; Summary: typeof FooterComponents; @@ -820,6 +903,8 @@ type ImmutableTableType = typeof ImmutableTable & { (ImmutableTable as ImmutableTableType).EXPAND_COLUMN = EXPAND_COLUMN; +(ImmutableTable as ImmutableTableType).INTERNAL_HOOKS = INTERNAL_HOOKS; + (ImmutableTable as ImmutableTableType).Column = Column; (ImmutableTable as ImmutableTableType).ColumnGroup = ColumnGroup; diff --git a/src/VirtualTable/BodyGrid.tsx b/src/VirtualTable/BodyGrid.tsx new file mode 100644 index 000000000..5ea75945c --- /dev/null +++ b/src/VirtualTable/BodyGrid.tsx @@ -0,0 +1,256 @@ +import { useContext } from '@rc-component/context'; +import classNames from 'classnames'; +import VirtualList, { type ListProps, type ListRef } from 'rc-virtual-list'; +import * as React from 'react'; +import Cell from '../Cell'; +import TableContext, { responseImmutable } from '../context/TableContext'; +import useFlattenRecords, { type FlattenData } from '../hooks/useFlattenRecords'; +import type { ColumnType, OnCustomizeScroll, ScrollConfig } from '../interface'; +import BodyLine from './BodyLine'; +import { GridContext, StaticContext } from './context'; + +export interface GridProps<RecordType = any> { + data: RecordType[]; + onScroll: OnCustomizeScroll; +} + +export interface GridRef { + scrollLeft: number; + scrollTo?: (scrollConfig: ScrollConfig) => void; +} + +const Grid = React.forwardRef<GridRef, GridProps>((props, ref) => { + const { data, onScroll } = props; + + const { + flattenColumns, + onColumnResize, + getRowKey, + expandedKeys, + prefixCls, + childrenColumnName, + emptyNode, + scrollX, + } = useContext(TableContext, [ + 'flattenColumns', + 'onColumnResize', + 'getRowKey', + 'prefixCls', + 'expandedKeys', + 'childrenColumnName', + 'emptyNode', + 'scrollX', + ]); + const { sticky, scrollY, listItemHeight } = useContext(StaticContext); + + // =========================== Ref ============================ + const listRef = React.useRef<ListRef>(); + + // =========================== Data =========================== + const flattenData = useFlattenRecords(data, childrenColumnName, expandedKeys, getRowKey); + + // ========================== Column ========================== + const columnsWidth = React.useMemo<[key: React.Key, width: number, total: number][]>(() => { + let total = 0; + return flattenColumns.map(({ width, key }) => { + total += width as number; + return [key, width as number, total]; + }); + }, [flattenColumns]); + + const columnsOffset = React.useMemo<number[]>( + () => columnsWidth.map(colWidth => colWidth[2]), + [columnsWidth], + ); + + React.useEffect(() => { + columnsWidth.forEach(([key, width]) => { + onColumnResize(key, width); + }); + }, [columnsWidth]); + + // =========================== Ref ============================ + React.useImperativeHandle(ref, () => { + const obj = { + scrollTo: (config: ScrollConfig) => { + listRef.current?.scrollTo(config); + }, + } as unknown as GridRef; + + Object.defineProperty(obj, 'scrollLeft', { + get: () => listRef.current?.getScrollInfo().x || 0, + + set: (value: number) => { + listRef.current?.scrollTo({ + left: value, + }); + }, + }); + + return obj; + }); + + // ======================= Col/Row Span ======================= + const getRowSpan = (column: ColumnType<any>, index: number): number => { + const record = flattenData[index]?.record; + const { onCell } = column; + + if (onCell) { + const cellProps = onCell(record, index) as React.TdHTMLAttributes<HTMLElement>; + return cellProps?.rowSpan ?? 1; + } + return 1; + }; + + const extraRender: ListProps<any>['extraRender'] = info => { + const { start, end, getSize, offsetY } = info; + + // Do nothing if no data + if (end < 0) { + return null; + } + + // Find first rowSpan column + let firstRowSpanColumns = flattenColumns.filter( + // rowSpan is 0 + column => getRowSpan(column, start) === 0, + ); + + let startIndex = start; + for (let i = start; i >= 0; i -= 1) { + firstRowSpanColumns = firstRowSpanColumns.filter(column => getRowSpan(column, i) === 0); + + if (!firstRowSpanColumns.length) { + startIndex = i; + break; + } + } + + // Find last rowSpan column + let lastRowSpanColumns = flattenColumns.filter( + // rowSpan is not 1 + column => getRowSpan(column, end) !== 1, + ); + + let endIndex = end; + for (let i = end; i < flattenData.length; i += 1) { + lastRowSpanColumns = lastRowSpanColumns.filter(column => getRowSpan(column, i) !== 1); + + if (!lastRowSpanColumns.length) { + endIndex = Math.max(i - 1, end); + break; + } + } + + // Collect the line who has rowSpan + const spanLines: number[] = []; + + for (let i = startIndex; i <= endIndex; i += 1) { + const item = flattenData[i]; + + // This code will never reach, just incase + if (!item) { + continue; + } + + if (flattenColumns.some(column => getRowSpan(column, i) > 1)) { + spanLines.push(i); + } + } + + // Patch extra line on the page + const nodes: React.ReactElement[] = spanLines.map(index => { + const item = flattenData[index]; + + const rowKey = getRowKey(item.record, index); + + const getHeight = (rowSpan: number) => { + const endItemIndex = index + rowSpan - 1; + const endItemKey = getRowKey(flattenData[endItemIndex].record, endItemIndex); + + const sizeInfo = getSize(rowKey, endItemKey); + return sizeInfo.bottom - sizeInfo.top; + }; + + const sizeInfo = getSize(rowKey); + + return ( + <BodyLine + key={index} + data={item} + rowKey={rowKey} + index={index} + style={{ + top: -offsetY + sizeInfo.top, + }} + extra + getHeight={getHeight} + /> + ); + }); + + return nodes; + }; + + // ========================= Context ========================== + const gridContext = React.useMemo(() => ({ columnsOffset }), [columnsOffset]); + + // ========================== Render ========================== + const tblPrefixCls = `${prefixCls}-tbody`; + + let bodyContent: React.ReactNode; + if (flattenData.length) { + // ========================== Sticky Scroll Bar ========================== + const horizontalScrollBarStyle: React.CSSProperties = {}; + if (sticky) { + horizontalScrollBarStyle.position = 'sticky'; + horizontalScrollBarStyle.bottom = 0; + if (typeof sticky === 'object' && sticky.offsetScroll) { + horizontalScrollBarStyle.bottom = sticky.offsetScroll; + } + } + + bodyContent = ( + <VirtualList<FlattenData<any>> + fullHeight={false} + ref={listRef} + styles={{ horizontalScrollBar: horizontalScrollBarStyle }} + className={classNames(tblPrefixCls, `${tblPrefixCls}-virtual`)} + height={scrollY} + itemHeight={listItemHeight || 24} + data={flattenData} + itemKey={item => getRowKey(item.record)} + scrollWidth={scrollX as number} + onVirtualScroll={({ x }) => { + onScroll({ + scrollLeft: x, + }); + }} + extraRender={extraRender} + > + {(item, index, itemProps) => { + const rowKey = getRowKey(item.record, index); + return <BodyLine data={item} rowKey={rowKey} index={index} {...itemProps} />; + }} + </VirtualList> + ); + } else { + bodyContent = ( + <div className={classNames(`${prefixCls}-placeholder`)}> + <Cell component="div" prefixCls={prefixCls}> + {emptyNode} + </Cell> + </div> + ); + } + + return <GridContext.Provider value={gridContext}>{bodyContent}</GridContext.Provider>; +}); + +const ResponseGrid = responseImmutable(Grid); + +if (process.env.NODE_ENV !== 'production') { + ResponseGrid.displayName = 'ResponseGrid'; +} + +export default ResponseGrid; diff --git a/src/VirtualTable/BodyLine.tsx b/src/VirtualTable/BodyLine.tsx new file mode 100644 index 000000000..d4e20cce1 --- /dev/null +++ b/src/VirtualTable/BodyLine.tsx @@ -0,0 +1,133 @@ +import { useContext } from '@rc-component/context'; +import classNames from 'classnames'; +import * as React from 'react'; +import Cell from '../Cell'; +import TableContext, { responseImmutable } from '../context/TableContext'; +import type { FlattenData } from '../hooks/useFlattenRecords'; +import useRowInfo from '../hooks/useRowInfo'; +import VirtualCell from './VirtualCell'; + +export interface BodyLineProps<RecordType = any> { + data: FlattenData<RecordType>; + index: number; + className?: string; + style?: React.CSSProperties; + rowKey: React.Key; + + /** Render cell only when it has `rowSpan > 1` */ + extra?: boolean; + getHeight?: (rowSpan: number) => number; +} + +const BodyLine = React.forwardRef<HTMLDivElement, BodyLineProps>((props, ref) => { + const { data, index, className, rowKey, style, extra, getHeight, ...restProps } = props; + const { record, indent, index: renderIndex } = data; + + const { scrollX, flattenColumns, prefixCls, fixColumn, componentWidth } = useContext( + TableContext, + ['prefixCls', 'flattenColumns', 'fixColumn', 'componentWidth', 'scrollX'], + ); + + const rowInfo = useRowInfo(record, rowKey, index, indent); + + // ========================== Expand ========================== + const { rowSupportExpand, expanded, rowProps, expandedRowRender, expandedRowClassName } = rowInfo; + + let expandRowNode: React.ReactElement; + if (rowSupportExpand && expanded) { + const expandContent = expandedRowRender(record, index, indent + 1, expanded); + const computedExpandedRowClassName = expandedRowClassName?.(record, index, indent); + + let additionalProps: React.TdHTMLAttributes<HTMLElement> = {}; + if (fixColumn) { + additionalProps = { + style: { + ['--virtual-width' as any]: `${componentWidth}px`, + }, + }; + } + + const rowCellCls = `${prefixCls}-expanded-row-cell`; + + expandRowNode = ( + <div + className={classNames( + `${prefixCls}-expanded-row`, + `${prefixCls}-expanded-row-level-${indent + 1}`, + computedExpandedRowClassName, + )} + > + <Cell + component="div" + prefixCls={prefixCls} + className={classNames(rowCellCls, { + [`${rowCellCls}-fixed`]: fixColumn, + })} + additionalProps={additionalProps} + > + {expandContent} + </Cell> + </div> + ); + } + + // ========================== Render ========================== + + const rowStyle: React.CSSProperties = { + ...style, + width: scrollX as number, + }; + + if (extra) { + rowStyle.position = 'absolute'; + rowStyle.pointerEvents = 'none'; + } + + const rowNode = ( + <div + {...rowProps} + {...restProps} + ref={rowSupportExpand ? null : ref} + className={classNames(className, `${prefixCls}-row`, rowProps?.className, { + [`${prefixCls}-row-extra`]: extra, + })} + style={{ ...rowStyle, ...rowProps?.style }} + > + {flattenColumns.map((column, colIndex) => { + return ( + <VirtualCell + key={colIndex} + rowInfo={rowInfo} + column={column} + colIndex={colIndex} + indent={indent} + index={index} + renderIndex={renderIndex} + record={record} + inverse={extra} + getHeight={getHeight} + /> + ); + })} + </div> + ); + + if (rowSupportExpand) { + return ( + <div ref={ref}> + {rowNode} + {expandRowNode} + </div> + ); + } + + return rowNode; +}); + +const ResponseBodyLine = responseImmutable(BodyLine); + +if (process.env.NODE_ENV !== 'production') { + ResponseBodyLine.displayName = 'BodyLine'; +} + +export default ResponseBodyLine; diff --git a/src/VirtualTable/VirtualCell.tsx b/src/VirtualTable/VirtualCell.tsx new file mode 100644 index 000000000..d5d5a62d0 --- /dev/null +++ b/src/VirtualTable/VirtualCell.tsx @@ -0,0 +1,137 @@ +import { useContext } from '@rc-component/context'; +import classNames from 'classnames'; +import * as React from 'react'; +import { getCellProps } from '../Body/BodyRow'; +import Cell from '../Cell'; +import type useRowInfo from '../hooks/useRowInfo'; +import type { ColumnType } from '../interface'; +import { GridContext } from './context'; + +export interface VirtualCellProps<RecordType> { + rowInfo: ReturnType<typeof useRowInfo>; + column: ColumnType<RecordType>; + colIndex: number; + indent: number; + index: number; + /** Used for `column.render` */ + renderIndex: number; + record: RecordType; + + // Follow props is used for RowSpanVirtualCell only + style?: React.CSSProperties; + className?: string; + + /** Render cell only when it has `rowSpan > 1` */ + inverse?: boolean; + getHeight?: (rowSpan: number) => number; +} + +/** + * Return the width of the column by `colSpan`. + * When `colSpan` is `0` will be trade as `1`. + */ +export function getColumnWidth(colIndex: number, colSpan: number, columnsOffset: number[]) { + const mergedColSpan = colSpan || 1; + return columnsOffset[colIndex + mergedColSpan] - (columnsOffset[colIndex] || 0); +} + +function VirtualCell<RecordType = any>(props: VirtualCellProps<RecordType>) { + const { + rowInfo, + column, + colIndex, + indent, + index, + renderIndex, + record, + style, + className, + inverse, + getHeight, + } = props; + + const { render, dataIndex, className: columnClassName, width: colWidth } = column; + + const { columnsOffset } = useContext(GridContext, ['columnsOffset']); + + const { key, fixedInfo, appendCellNode, additionalCellProps } = getCellProps( + rowInfo, + column, + colIndex, + indent, + index, + ); + + const { style: cellStyle, colSpan = 1, rowSpan = 1 } = additionalCellProps; + + // ========================= ColWidth ========================= + // column width + const startColIndex = colIndex - 1; + const concatColWidth = getColumnWidth(startColIndex, colSpan, columnsOffset); + + // margin offset + const marginOffset = colSpan > 1 ? (colWidth as number) - concatColWidth : 0; + + // ========================== Style =========================== + const mergedStyle: React.CSSProperties = { + ...cellStyle, + ...style, + flex: `0 0 ${concatColWidth}px`, + width: `${concatColWidth}px`, + marginRight: marginOffset, + pointerEvents: 'auto', + }; + + // When `colSpan` or `rowSpan` is `0`, should skip render. + const needHide = React.useMemo(() => { + if (inverse) { + return rowSpan <= 1; + } else { + return colSpan === 0 || rowSpan === 0 || rowSpan > 1; + } + }, [rowSpan, colSpan, inverse]); + + // 0 rowSpan or colSpan should not render + if (needHide) { + mergedStyle.visibility = 'hidden'; + } else if (inverse) { + mergedStyle.height = getHeight?.(rowSpan); + } + const mergedRender = needHide ? () => null : render; + + // ========================== Render ========================== + const cellSpan: React.TdHTMLAttributes<HTMLElement> = {}; + + // Virtual should reset `colSpan` & `rowSpan` + if (rowSpan === 0 || colSpan === 0) { + cellSpan.rowSpan = 1; + cellSpan.colSpan = 1; + } + + return ( + <Cell + className={classNames(columnClassName, className)} + ellipsis={column.ellipsis} + align={column.align} + scope={column.rowScope} + component="div" + prefixCls={rowInfo.prefixCls} + key={key} + record={record} + index={index} + renderIndex={renderIndex} + dataIndex={dataIndex} + render={mergedRender} + shouldCellUpdate={column.shouldCellUpdate} + {...fixedInfo} + appendNode={appendCellNode} + additionalProps={{ + ...additionalCellProps, + style: mergedStyle, + ...cellSpan, + }} + /> + ); +} + +export default VirtualCell; diff --git a/src/VirtualTable/context.ts b/src/VirtualTable/context.ts new file mode 100644 index 000000000..097658a90 --- /dev/null +++ b/src/VirtualTable/context.ts @@ -0,0 +1,16 @@ +import { createContext } from '@rc-component/context'; +import type { TableSticky } from '../interface'; + +export interface StaticContextProps { + scrollY: number; + listItemHeight: number; + sticky: boolean | TableSticky; +} + +export const StaticContext = createContext<StaticContextProps>(null); + +export interface GridContextProps { + columnsOffset: number[]; +} + +export const GridContext = createContext<GridContextProps>(null); diff --git a/src/VirtualTable/index.tsx b/src/VirtualTable/index.tsx new file mode 100644 index 000000000..eb59f7ff1 --- /dev/null +++ b/src/VirtualTable/index.tsx @@ -0,0 +1,102 @@ +import type { CompareProps } from '@rc-component/context/lib/Immutable'; +import classNames from 'classnames'; +import { warning } from 'rc-util'; +import * as React from 'react'; +import { INTERNAL_HOOKS } from '../constant'; +import { makeImmutable } from '../context/TableContext'; +import type { CustomizeScrollBody, Reference } from '../interface'; +import Table, { DEFAULT_PREFIX, type TableProps } from '../Table'; +import Grid from './BodyGrid'; +import { StaticContext } from './context'; + +const renderBody: CustomizeScrollBody<any> = (rawData, props) => { + const { ref, onScroll } = props; + + return <Grid ref={ref} data={rawData as any} onScroll={onScroll} />; +}; + +export interface VirtualTableProps<RecordType> extends Omit<TableProps<RecordType>, 'scroll'> { + scroll: { + x?: number; + y: number; + }; + listItemHeight?: number; +} + +function VirtualTable<RecordType>(props: VirtualTableProps<RecordType>, ref: React.Ref<Reference>) { + const { + columns, + scroll, + sticky, + prefixCls = DEFAULT_PREFIX, + className, + listItemHeight, + components, + } = props; + + let { x: scrollX, y: scrollY } = scroll || {}; + + // Fill scrollX + if (typeof scrollX !== 'number') { + if (process.env.NODE_ENV !== 'production') { + warning(!scrollX, '`scroll.x` in virtual table must be number.'); + } + + scrollX = 1; + } + + // Fill scrollY + if (typeof scrollY !== 'number') { + scrollY = 500; + + if (process.env.NODE_ENV !== 'production') { + warning(false, '`scroll.y` in virtual table must be number.'); + } + } + + // ========================= Context ========================== + const context = React.useMemo( + () => ({ sticky, scrollY, listItemHeight }), + [sticky, scrollY, listItemHeight], + ); + + // ========================== Render ========================== + return ( + <StaticContext.Provider value={context}> + <Table + {...props} + className={classNames(className, `${prefixCls}-virtual`)} + scroll={{ + ...scroll, + x: scrollX, + }} + components={{ + ...components, + body: renderBody, + }} + columns={columns} + internalHooks={INTERNAL_HOOKS} + tailor + ref={ref} + /> + </StaticContext.Provider> + ); +} + +export type ForwardGenericVirtualTable = (<RecordType>( + props: TableProps<RecordType> & { ref?: React.Ref<Reference> }, +) => React.ReactElement) & { + displayName?: string; +}; + +const RefVirtualTable = React.forwardRef(VirtualTable) as ForwardGenericVirtualTable; + +if (process.env.NODE_ENV !== 'production') { + RefVirtualTable.displayName = 'VirtualTable'; +} + +export function genVirtualTable(shouldTriggerRender?: CompareProps<typeof Table>) { + return makeImmutable(RefVirtualTable, shouldTriggerRender) as ForwardGenericVirtualTable; +} + +export default genVirtualTable(); diff --git a/src/constant.ts b/src/constant.ts index 41d96e197..a851b0810 100644 --- a/src/constant.ts +++ b/src/constant.ts @@ -1 +1,3 @@ export const EXPAND_COLUMN = {} as const; + +export const INTERNAL_HOOKS = 'rc-table-internal-hook'; diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index 5f9129036..ee5eeae2a 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -1,4 +1,4 @@ -import { createContext } from '@rc-component/context'; +import { createContext, createImmutable } from '@rc-component/context'; import type { ColumnsType, ColumnType, @@ -6,6 +6,8 @@ import type { ExpandableType, ExpandedRowRender, GetComponent, + GetComponentProps, + GetRowKey, RenderExpandIcon, RowClassName, TableLayout, @@ -13,7 +15,13 @@ import type { } from '../interface'; import type { FixedInfo } from '../utils/fixUtil'; +const { makeImmutable, responseImmutable, useImmutableMark } = createImmutable(); +export { makeImmutable, responseImmutable, useImmutableMark }; + export interface TableContextProps<RecordType = any> { + // Scroll + scrollX: number | string | true; + // Table prefixCls: string; getComponent: GetComponent; @@ -30,6 +38,8 @@ export interface TableContextProps<RecordType = any> { // Body rowClassName: string | RowClassName<RecordType>; expandedRowClassName: RowClassName<RecordType>; + onRow?: GetComponentProps<RecordType>; + emptyNode?: React.ReactNode; tableLayout: TableLayout; @@ -51,6 +61,11 @@ export interface TableContextProps<RecordType = any> { hoverStartRow: number; hoverEndRow: number; onHover: (start: number, end: number) => void; + rowExpandable: (record: RecordType) => boolean; + + expandedKeys: Set<React.Key>; + getRowKey: GetRowKey<RecordType>; + childrenColumnName: string; } const TableContext = createContext<TableContextProps>(); diff --git a/src/hooks/useColumns.tsx b/src/hooks/useColumns/index.tsx similarity index 82% rename from src/hooks/useColumns.tsx rename to src/hooks/useColumns/index.tsx index 457b7a8c8..52cc445fd 100644 --- a/src/hooks/useColumns.tsx +++ b/src/hooks/useColumns/index.tsx @@ -1,19 +1,20 @@ -import * as React from 'react'; -import warning from 'rc-util/lib/warning'; import toArray from 'rc-util/lib/Children/toArray'; +import warning from 'rc-util/lib/warning'; +import * as React from 'react'; +import { EXPAND_COLUMN } from '../../constant'; import type { + ColumnGroupType, ColumnsType, ColumnType, + Direction, FixedType, - Key, GetRowKey, - TriggerEventHandler, + Key, RenderExpandIcon, - ColumnGroupType, - Direction, -} from '../interface'; -import { INTERNAL_COL_DEFINE } from '../utils/legacyUtil'; -import { EXPAND_COLUMN } from '../constant'; + TriggerEventHandler, +} from '../../interface'; +import { INTERNAL_COL_DEFINE } from '../../utils/legacyUtil'; +import useWidthColumns from './useWidthColumns'; export function convertChildrenToColumns<RecordType>( children: React.ReactNode, @@ -35,31 +36,37 @@ export function convertChildrenToColumns<RecordType>( }); } -function flatColumns<RecordType>(columns: ColumnsType<RecordType>): ColumnType<RecordType>[] { - return columns.reduce((list, column) => { - const { fixed } = column; - - // Convert `fixed='true'` to `fixed='left'` instead - const parsedFixed = fixed === true ? 'left' : fixed; +function flatColumns<RecordType>( + columns: ColumnsType<RecordType>, + parentKey = 'key', +): ColumnType<RecordType>[] { + return columns + .filter(column => column && typeof column === 'object') + .reduce((list, column, index) => { + const { fixed } = column; + // Convert `fixed='true'` to `fixed='left'` instead + const parsedFixed = fixed === true ? 'left' : fixed; + const mergedKey = `${parentKey}-${index}`; - const subColumns = (column as ColumnGroupType<RecordType>).children; - if (subColumns && subColumns.length > 0) { + const subColumns = (column as ColumnGroupType<RecordType>).children; + if (subColumns && subColumns.length > 0) { + return [ + ...list, + ...flatColumns(subColumns, mergedKey).map(subColum => ({ + fixed: parsedFixed, + ...subColum, + })), + ]; + } return [ ...list, - ...flatColumns(subColumns).map(subColum => ({ + { + key: mergedKey, + ...column, fixed: parsedFixed, - ...subColum, - })), + }, ]; - } - return [ - ...list, - { - ...column, - fixed: parsedFixed, - }, - ]; - }, []); + }, []); } function warningFixed(flattenColumns: readonly { fixed?: FixedType }[]) { @@ -124,6 +131,8 @@ function useColumns<RecordType>( expandRowByClick, columnWidth, fixed, + scrollWidth, + clientWidth, }: { prefixCls?: string; columns?: ColumnsType<RecordType>; @@ -139,10 +148,16 @@ function useColumns<RecordType>( direction?: Direction; expandRowByClick?: boolean; columnWidth?: number | string; + clientWidth: number; fixed?: FixedType; + scrollWidth?: number; }, transformColumns: (columns: ColumnsType<RecordType>) => ColumnsType<RecordType>, -): [ColumnsType<RecordType>, readonly ColumnType<RecordType>[]] { +): [ + columns: ColumnsType<RecordType>, + flattenColumns: readonly ColumnType<RecordType>[], + realScrollWidth: undefined | number, +] { const baseColumns = React.useMemo<ColumnsType<RecordType>>( () => columns || convertChildrenToColumns(children), [columns, children], @@ -257,12 +272,21 @@ function useColumns<RecordType>( return revertForRtl(flatColumns(mergedColumns)); } return flatColumns(mergedColumns); - }, [mergedColumns, direction]); + }, [mergedColumns, direction, scrollWidth]); + // Only check out of production since it's waste for each render if (process.env.NODE_ENV !== 'production') { warningFixed(direction === 'rtl' ? flattenColumns.slice().reverse() : flattenColumns); } - return [mergedColumns, flattenColumns]; + + // ========================= FillWidth ======================== + const [filledColumns, realScrollWidth] = useWidthColumns( + flattenColumns, + scrollWidth, + clientWidth, + ); + + return [mergedColumns, filledColumns, realScrollWidth]; } export default useColumns; diff --git a/src/hooks/useColumns/useWidthColumns.tsx b/src/hooks/useColumns/useWidthColumns.tsx new file mode 100644 index 000000000..fb5f2d885 --- /dev/null +++ b/src/hooks/useColumns/useWidthColumns.tsx @@ -0,0 +1,92 @@ +import * as React from 'react'; +import type { ColumnsType } from '../../interface'; + +function parseColWidth(totalWidth: number, width: string | number = '') { + if (typeof width === 'number') { + return width; + } + + if (width.endsWith('%')) { + return (totalWidth * parseFloat(width)) / 100; + } + return null; +} + +/** + * Fill all column with width + */ +export default function useWidthColumns( + flattenColumns: ColumnsType<any>, + scrollWidth: number, + clientWidth: number, +) { + return React.useMemo<[columns: ColumnsType<any>, realScrollWidth: number]>(() => { + // Fill width if needed + if (scrollWidth && scrollWidth > 0) { + let totalWidth = 0; + let missWidthCount = 0; + + // collect not given width column + flattenColumns.forEach((col: any) => { + const colWidth = parseColWidth(scrollWidth, col.width); + + if (colWidth) { + totalWidth += colWidth; + } else { + missWidthCount += 1; + } + }); + + // Fill width + const maxFitWidth = Math.max(scrollWidth, clientWidth); + let restWidth = Math.max(maxFitWidth - totalWidth, missWidthCount); + let restCount = missWidthCount; + const avgWidth = restWidth / missWidthCount; + + let realTotal = 0; + + const filledColumns = flattenColumns.map((col: any) => { + const clone = { + ...col, + }; + + const colWidth = parseColWidth(scrollWidth, clone.width); + + if (colWidth) { + clone.width = colWidth; + } else { + const colAvgWidth = Math.floor(avgWidth); + + clone.width = restCount === 1 ? restWidth : colAvgWidth; + + restWidth -= colAvgWidth; + restCount -= 1; + } + + realTotal += clone.width; + + return clone; + }); + + // If realTotal is less than clientWidth, + // We need extend column width + if (realTotal < maxFitWidth) { + const scale = maxFitWidth / realTotal; + + restWidth = maxFitWidth; + + filledColumns.forEach((col: any, index) => { + const colWidth = Math.floor(col.width * scale); + + col.width = index === filledColumns.length - 1 ? restWidth : colWidth; + + restWidth -= colWidth; + }); + } + + return [filledColumns, Math.max(realTotal, maxFitWidth)]; + } + + return [flattenColumns, scrollWidth]; + }, [flattenColumns, scrollWidth, clientWidth]); +} diff --git a/src/hooks/useExpand.ts b/src/hooks/useExpand.ts index d75df4ef0..514008d57 100644 --- a/src/hooks/useExpand.ts +++ b/src/hooks/useExpand.ts @@ -1,5 +1,6 @@ import warning from 'rc-util/lib/warning'; import * as React from 'react'; +import { INTERNAL_HOOKS } from '../constant'; import type { ExpandableConfig, ExpandableType, @@ -9,12 +10,11 @@ import type { TriggerEventHandler, } from '../interface'; import type { TableProps } from '../Table'; -import { INTERNAL_HOOKS } from '../Table'; import { findAllChildrenKeys, renderExpandIcon } from '../utils/expandUtil'; import { getExpandableProps } from '../utils/legacyUtil'; export default function useExpand<RecordType>( - props: TableProps, + props: TableProps<RecordType>, mergedData: readonly RecordType[], getRowKey: GetRowKey<RecordType>, ): [ diff --git a/src/hooks/useFixedInfo.ts b/src/hooks/useFixedInfo.ts index 9f05c8711..bafef0981 100644 --- a/src/hooks/useFixedInfo.ts +++ b/src/hooks/useFixedInfo.ts @@ -7,10 +7,17 @@ export default function useFixedInfo<RecordType>( flattenColumns: readonly ColumnType<RecordType>[], stickyOffsets: StickyOffsets, direction: Direction, - columns: ColumnsType<RecordType> + columns: ColumnsType<RecordType>, ) { const fixedInfoList = flattenColumns.map((_, colIndex) => - getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction, columns?.[colIndex]), + getCellFixedInfo( + colIndex, + colIndex, + flattenColumns, + stickyOffsets, + direction, + columns?.[colIndex], + ), ); return useMemo( diff --git a/src/hooks/useFlattenRecords.ts b/src/hooks/useFlattenRecords.ts index 5dba12070..ff67f5d9d 100644 --- a/src/hooks/useFlattenRecords.ts +++ b/src/hooks/useFlattenRecords.ts @@ -2,7 +2,8 @@ import * as React from 'react'; import type { GetRowKey, Key } from '../interface'; // recursion (flat tree structure) -function flatRecord<T>( +function fillRecords<T>( + list: FlattenData<T>[], record: T, indent: number, childrenColumnName: string, @@ -10,9 +11,7 @@ function flatRecord<T>( getRowKey: GetRowKey<T>, index: number, ) { - const arr = []; - - arr.push({ + list.push({ record, indent, index, @@ -25,7 +24,8 @@ function flatRecord<T>( if (record && Array.isArray(record[childrenColumnName]) && expanded) { // expanded state, flat record for (let i = 0; i < record[childrenColumnName].length; i += 1) { - const tempArr = flatRecord( + fillRecords( + list, record[childrenColumnName][i], indent + 1, childrenColumnName, @@ -33,12 +33,14 @@ function flatRecord<T>( getRowKey, i, ); - - arr.push(...tempArr); } } +} - return arr; +export interface FlattenData<RecordType> { + record: RecordType; + indent: number; + index: number; } /** @@ -53,23 +55,24 @@ function flatRecord<T>( * @returns flattened data */ export default function useFlattenRecords<T>( - data, + data: T[] | readonly T[], childrenColumnName: string, expandedKeys: Set<Key>, getRowKey: GetRowKey<T>, -) { - const arr: { record: T; indent: number; index: number }[] = React.useMemo(() => { +): FlattenData<T>[] { + const arr: FlattenData<T>[] = React.useMemo(() => { if (expandedKeys?.size) { - const temp: { record: T; indent: number; index: number }[] = []; + const list: FlattenData<T>[] = []; // collect flattened record for (let i = 0; i < data?.length; i += 1) { const record = data[i]; - temp.push(...flatRecord<T>(record, 0, childrenColumnName, expandedKeys, getRowKey, i)); + // using array.push or spread operator may cause "Maximum call stack size exceeded" exception if array size is big enough. + fillRecords(list, record, 0, childrenColumnName, expandedKeys, getRowKey, i); } - return temp; + return list; } return data?.map((item, index) => { diff --git a/src/hooks/useRowInfo.tsx b/src/hooks/useRowInfo.tsx new file mode 100644 index 000000000..bba123a89 --- /dev/null +++ b/src/hooks/useRowInfo.tsx @@ -0,0 +1,123 @@ +import { useContext } from '@rc-component/context'; +import type { TableContextProps } from '../context/TableContext'; +import TableContext from '../context/TableContext'; +import { getColumnsKey } from '../utils/valueUtil'; +import { useEvent } from 'rc-util'; +import classNames from 'classnames'; + +export default function useRowInfo<RecordType>( + record: RecordType, + rowKey: React.Key, + recordIndex: number, + indent: number, +): Pick< + TableContextProps, + | 'prefixCls' + | 'fixedInfoList' + | 'flattenColumns' + | 'expandableType' + | 'expandRowByClick' + | 'onTriggerExpand' + | 'rowClassName' + | 'expandedRowClassName' + | 'indentSize' + | 'expandIcon' + | 'expandedRowRender' + | 'expandIconColumnIndex' + | 'expandedKeys' + | 'childrenColumnName' + | 'onRow' +> & { + columnsKey: React.Key[]; + nestExpandable: boolean; + expanded: boolean; + hasNestChildren: boolean; + record: RecordType; + rowSupportExpand: boolean; + expandable: boolean; + rowProps: React.HTMLAttributes<any> & React.TdHTMLAttributes<any>; +} { + const context: TableContextProps = useContext(TableContext, [ + 'prefixCls', + 'fixedInfoList', + 'flattenColumns', + 'expandableType', + 'expandRowByClick', + 'onTriggerExpand', + 'rowClassName', + 'expandedRowClassName', + 'indentSize', + 'expandIcon', + 'expandedRowRender', + 'expandIconColumnIndex', + 'expandedKeys', + 'childrenColumnName', + 'rowExpandable', + 'onRow', + ]); + + const { + flattenColumns, + expandableType, + expandedKeys, + childrenColumnName, + onTriggerExpand, + rowExpandable, + onRow, + expandRowByClick, + rowClassName, + } = context; + + // ======================= Expandable ======================= + // Only when row is not expandable and `children` exist in record + const nestExpandable = expandableType === 'nest'; + + const rowSupportExpand = expandableType === 'row' && (!rowExpandable || rowExpandable(record)); + const mergedExpandable = rowSupportExpand || nestExpandable; + + const expanded = expandedKeys && expandedKeys.has(rowKey); + + const hasNestChildren = childrenColumnName && record && record[childrenColumnName]; + + const onInternalTriggerExpand = useEvent(onTriggerExpand); + + // ========================= onRow ========================== + const rowProps = onRow?.(record, recordIndex); + const onRowClick = rowProps?.onClick; + + const onClick: React.MouseEventHandler<HTMLElement> = (event, ...args) => { + if (expandRowByClick && mergedExpandable) { + onTriggerExpand(record, event); + } + + onRowClick?.(event, ...args); + }; + + // ====================== RowClassName ====================== + let computeRowClassName: string; + if (typeof rowClassName === 'string') { + computeRowClassName = rowClassName; + } else if (typeof rowClassName === 'function') { + computeRowClassName = rowClassName(record, recordIndex, indent); + } + + // ========================= Column ========================= + const columnsKey = getColumnsKey(flattenColumns); + + return { + ...context, + columnsKey, + nestExpandable, + expanded, + hasNestChildren, + record, + onTriggerExpand: onInternalTriggerExpand, + rowSupportExpand, + expandable: mergedExpandable, + rowProps: { + ...rowProps, + className: classNames(computeRowClassName, rowProps?.className), + onClick, + }, + }; +} diff --git a/src/index.ts b/src/index.ts index fb1892b77..a1c42ecbe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,28 @@ -import { EXPAND_COLUMN } from './constant'; +import { EXPAND_COLUMN, INTERNAL_HOOKS } from './constant'; import { FooterComponents as Summary } from './Footer'; +import type { ColumnType, Reference } from './interface'; import Column from './sugar/Column'; import ColumnGroup from './sugar/ColumnGroup'; import type { TableProps } from './Table'; import Table, { genTable } from './Table'; import { INTERNAL_COL_DEFINE } from './utils/legacyUtil'; +import type { VirtualTableProps } from './VirtualTable'; +import VirtualTable, { genVirtualTable } from './VirtualTable'; -export { genTable, Summary, Column, ColumnGroup, TableProps, INTERNAL_COL_DEFINE, EXPAND_COLUMN }; +export { + genTable, + Summary, + Column, + ColumnGroup, + type TableProps, + INTERNAL_COL_DEFINE, + EXPAND_COLUMN, + INTERNAL_HOOKS, + VirtualTable, + genVirtualTable, + type VirtualTableProps, + type Reference, + type ColumnType, +}; export default Table; diff --git a/src/interface.ts b/src/interface.ts index d3c2c99a6..f589862fb 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -25,6 +25,17 @@ export type DefaultRecordType = Record<string, any>; export type TableLayout = 'auto' | 'fixed'; +export type ScrollConfig = { + index?: number; + key?: Key; + top?: number; +}; + +export type Reference = { + nativeElement: HTMLDivElement; + scrollTo: (config: ScrollConfig) => void; +}; + // ==================== Row ===================== export type RowClassName<RecordType> = ( record: RecordType, @@ -80,7 +91,7 @@ export interface ColumnGroupType<RecordType> extends ColumnSharedType<RecordType children: ColumnsType<RecordType>; } -export type AlignType = 'left' | 'center' | 'right'; +export type AlignType = 'start' | 'end' | 'left' | 'right' | 'center' | 'justify' | 'match-parent'; export interface ColumnType<RecordType> extends ColumnSharedType<RecordType> { colSpan?: number; @@ -116,7 +127,7 @@ export interface StickyOffsets { export type GetComponentProps<DataType> = ( data: DataType, index?: number, -) => React.HTMLAttributes<any> | React.TdHTMLAttributes<any>; +) => React.HTMLAttributes<any> & React.TdHTMLAttributes<any>; type Component<P> = | React.ComponentType<P> @@ -126,12 +137,17 @@ type Component<P> = export type CustomizeComponent = Component<any>; +export type OnCustomizeScroll = (info: { + currentTarget?: HTMLElement; + scrollLeft?: number; +}) => void; + export type CustomizeScrollBody<RecordType> = ( data: readonly RecordType[], info: { scrollbarSize: number; - ref: React.Ref<{ scrollLeft: number }>; - onScroll: (info: { currentTarget?: HTMLElement; scrollLeft?: number }) => void; + ref: React.Ref<{ scrollLeft: number; scrollTo?: (scrollConfig: ScrollConfig) => void }>; + onScroll: OnCustomizeScroll; }, ) => React.ReactNode; @@ -184,7 +200,6 @@ export interface LegacyExpandableProps<RecordType> { expandedRowClassName?: RowClassName<RecordType>; /** @deprecated Use `expandable.childrenColumnName` instead */ childrenColumnName?: string; - /** @deprecated Use `caption` instead */ title?: PanelRender<RecordType>; } diff --git a/src/stickyScrollBar.tsx b/src/stickyScrollBar.tsx index 712878283..6aa84777b 100644 --- a/src/stickyScrollBar.tsx +++ b/src/stickyScrollBar.tsx @@ -1,10 +1,10 @@ +import { useContext } from '@rc-component/context'; import classNames from 'classnames'; import addEventListener from 'rc-util/lib/Dom/addEventListener'; import { getOffset } from 'rc-util/lib/Dom/css'; import getScrollBarSize from 'rc-util/lib/getScrollBarSize'; import * as React from 'react'; import TableContext from './context/TableContext'; -import { useContext } from '@rc-component/context'; import { useLayoutState } from './hooks/useFrame'; interface StickyScrollBarProps { diff --git a/src/utils/fixUtil.ts b/src/utils/fixUtil.ts index ca6c469cd..4e4431de8 100644 --- a/src/utils/fixUtil.ts +++ b/src/utils/fixUtil.ts @@ -1,4 +1,10 @@ -import type { StickyOffsets, FixedType, Direction, ColumnType, ColumnGroupType } from '../interface'; +import type { + ColumnGroupType, + ColumnType, + Direction, + FixedType, + StickyOffsets, +} from '../interface'; export interface FixedInfo { fixLeft: number | false; @@ -19,7 +25,7 @@ export function getCellFixedInfo<RecordType = any>( columns: readonly { fixed?: FixedType }[], stickyOffsets: StickyOffsets, direction: Direction, - curColumns?: ColumnType<RecordType> | ColumnGroupType<RecordType> + curColumns?: ColumnType<RecordType> | ColumnGroupType<RecordType>, ): FixedInfo { const startColumn = columns[colStart] || {}; const endColumn = columns[colEnd] || {}; @@ -28,9 +34,9 @@ export function getCellFixedInfo<RecordType = any>( let fixRight: number; if (startColumn.fixed === 'left') { - fixLeft = stickyOffsets.left[colStart]; + fixLeft = stickyOffsets.left[direction === 'rtl' ? colEnd : colStart]; } else if (endColumn.fixed === 'right') { - fixRight = stickyOffsets.right[colEnd]; + fixRight = stickyOffsets.right[direction === 'rtl' ? colStart : colEnd]; } let lastFixLeft: boolean = false; diff --git a/tests/ColSpan.spec.jsx b/tests/ColSpan.spec.jsx new file mode 100644 index 000000000..d58298ffd --- /dev/null +++ b/tests/ColSpan.spec.jsx @@ -0,0 +1,54 @@ +import { render } from '@testing-library/react'; +import React from 'react'; +import Table from '../src'; + +describe('Table.ColSpan', () => { + it('hover the tree table', () => { + const { container } = render( + <Table + columns={[ + { + title: 'Parent', + key: 'parent', + children: [ + { + title: 'name', + key: 'name', + dataIndex: 'name', + onHeaderCell: () => ({ + colSpan: 2, + }), + }, + { + title: 'age', + key: 'age', + dataIndex: 'age', + onHeaderCell: () => ({ colSpan: 0 }), + }, + ], + }, + ]} + data={[ + { + key: '1', + name: 'Little', + age: 2, + }, + ]} + />, + ); + + // 2 rows + expect(container.querySelector('thead').querySelectorAll('tr')).toHaveLength(2); + + // one cell + const lastTr = container.querySelector('thead').querySelectorAll('tr')[1]; + expect(lastTr.querySelectorAll('th')).toHaveLength(1); + expect(lastTr.querySelector('th')).toHaveAttribute('colSpan', '2'); + + // Data 2 cells + expect( + container.querySelector('tbody').querySelectorAll('tr')[0].querySelectorAll('td'), + ).toHaveLength(2); + }); +}); diff --git a/tests/Colgroup.spec.js b/tests/Colgroup.spec.jsx similarity index 100% rename from tests/Colgroup.spec.js rename to tests/Colgroup.spec.jsx index 1b88224f6..e112721a6 100644 --- a/tests/Colgroup.spec.js +++ b/tests/Colgroup.spec.jsx @@ -1,5 +1,5 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import Table, { INTERNAL_COL_DEFINE } from '../src'; describe('Table.ColGroup', () => { diff --git a/tests/Deprecated.spec.js b/tests/Deprecated.spec.jsx similarity index 90% rename from tests/Deprecated.spec.js rename to tests/Deprecated.spec.jsx index 12cb00988..274c6b546 100644 --- a/tests/Deprecated.spec.js +++ b/tests/Deprecated.spec.jsx @@ -1,13 +1,13 @@ -import React from 'react'; import { mount } from 'enzyme'; import { resetWarned } from 'rc-util/lib/warning'; +import React from 'react'; import Table from '../src'; describe('Table.Deprecated', () => { let errorSpy; beforeAll(() => { - errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); }); beforeEach(() => { @@ -34,7 +34,7 @@ describe('Table.Deprecated', () => { removedProp => { it(`warning for '${removedProp}'`, () => { const props = { - [removedProp]: jest.fn(), + [removedProp]: vi.fn(), }; mount(<Table {...props} />); diff --git a/tests/ExpandRow.spec.js b/tests/ExpandRow.spec.jsx similarity index 94% rename from tests/ExpandRow.spec.js rename to tests/ExpandRow.spec.jsx index 7dbb9593d..3938ea1f5 100644 --- a/tests/ExpandRow.spec.js +++ b/tests/ExpandRow.spec.jsx @@ -1,8 +1,9 @@ -import React from 'react'; +import { render } from '@testing-library/react'; import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; -import { resetWarned } from 'rc-util/lib/warning'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; +import { resetWarned } from 'rc-util/lib/warning'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; import Table from '../src'; describe('Table.Expand', () => { @@ -22,7 +23,7 @@ describe('Table.Expand', () => { it('renders expand row correctly', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount(createTable({ expandedRowRender })); expect(wrapper.find('tbody tr')).toHaveLength(2); expect(errorSpy).toHaveBeenCalledWith( @@ -32,7 +33,7 @@ describe('Table.Expand', () => { }); it('pass proper parameters to expandedRowRender', () => { - const rowRender = jest.fn(() => <div>expanded row</div>); + const rowRender = vi.fn(() => <div>expanded row</div>); const expandableProps = props => ({ expandable: { expandedRowRender: rowRender, ...props } }); const wrapper = mount(createTable(expandableProps())); wrapper.setProps(expandableProps({ expandedRowKeys: [0] })); @@ -232,7 +233,7 @@ describe('Table.Expand', () => { describe('config expand column index', () => { it('not show EXPAND_COLUMN if expandable is false', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount( createTable({ @@ -250,7 +251,7 @@ describe('Table.Expand', () => { it('renders expand icon to the specify column', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount( createTable({ @@ -287,7 +288,7 @@ describe('Table.Expand', () => { it('de-duplicate of EXPAND_COLUMN', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount( createTable({ @@ -400,7 +401,7 @@ describe('Table.Expand', () => { }); it('renders expend row class correctly', () => { - const expandedRowClassName = jest.fn().mockReturnValue('expand-row-test-class-name'); + const expandedRowClassName = vi.fn().mockReturnValue('expand-row-test-class-name'); const wrapper = mount( createTable({ expandable: { @@ -431,7 +432,7 @@ describe('Table.Expand', () => { }); it('fires expand change event', () => { - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -448,7 +449,7 @@ describe('Table.Expand', () => { }); it('fires onExpandedRowsChange event', () => { - const onExpandedRowsChange = jest.fn(); + const onExpandedRowsChange = vi.fn(); const wrapper = mount( createTable({ expandedRowRender, @@ -473,7 +474,7 @@ describe('Table.Expand', () => { }); it('expandRowByClick', () => { - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -533,7 +534,7 @@ describe('Table.Expand', () => { // https://github.com/ant-design/ant-design/issues/23894 it('should be collapsible when use `expandIcon` & `expandRowByClick`', () => { const data = [{ key: 0, name: 'Lucy', age: 27 }]; - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -561,7 +562,7 @@ describe('Table.Expand', () => { // https://github.com/ant-design/ant-design/issues/23894 it('should be collapsible when `expandRowByClick` without custom `expandIcon`', () => { const data = [{ key: 0, name: 'Lucy', age: 27 }]; - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -582,7 +583,7 @@ describe('Table.Expand', () => { it('should be collapsible when `expandRowByClick` with custom `expandIcon` and event.stopPropagation', () => { const data = [{ key: 0, name: 'Lucy', age: 27 }]; - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -612,7 +613,7 @@ describe('Table.Expand', () => { it('support invalid expandIcon', () => { const data = [{ key: 0, name: 'Lucy', age: 27 }]; - const onExpand = jest.fn(); + const onExpand = vi.fn(); const wrapper = mount( createTable({ expandable: { @@ -629,11 +630,25 @@ describe('Table.Expand', () => { it('warning for use `expandedRowRender` and nested table in the same time', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); mount(createTable({ expandedRowRender, data: [{ children: [] }] })); expect(errorSpy).toHaveBeenCalledWith( 'Warning: `expandedRowRender` should not use with nested Table', ); errorSpy.mockRestore(); }); + + it('should only trigger once', () => { + const expandedRowRender = vi.fn(() => <p>extra data</p>); + render( + createTable({ + expandable: { + expandedRowRender, + expandedRowKeys: [0], + }, + }), + ); + + expect(expandedRowRender).toHaveBeenCalledTimes(1); + }); }); diff --git a/tests/FixedColumn-IE.spec.js b/tests/FixedColumn-IE.spec.jsx similarity index 92% rename from tests/FixedColumn-IE.spec.js rename to tests/FixedColumn-IE.spec.jsx index 8d74411ff..feff1ca19 100644 --- a/tests/FixedColumn-IE.spec.js +++ b/tests/FixedColumn-IE.spec.jsx @@ -1,13 +1,12 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; -import Table from '../src'; import RcResizeObserver from 'rc-resize-observer'; +import Table from '../src'; -jest.mock('rc-util/lib/Dom/styleChecker', () => { +vi.mock('rc-util/lib/Dom/styleChecker', () => { return { isStyleSupport: (name, val) => val !== 'sticky', }; @@ -43,7 +42,7 @@ describe('Table.FixedColumn', () => { const data = [{ a: '123', b: 'xxxxxxxx', d: 3, key: '1' }]; it('not sticky', async () => { - jest.useFakeTimers(); + vi.useFakeTimers(); const wrapper = mount(<Table columns={columns} data={data} scroll={{ x: 1200 }} />); act(() => { @@ -60,7 +59,7 @@ describe('Table.FixedColumn', () => { }); await act(async () => { - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); diff --git a/tests/FixedColumn.spec.js b/tests/FixedColumn.spec.jsx similarity index 97% rename from tests/FixedColumn.spec.js rename to tests/FixedColumn.spec.jsx index 18eb60451..a0f7eb47a 100644 --- a/tests/FixedColumn.spec.js +++ b/tests/FixedColumn.spec.jsx @@ -3,13 +3,13 @@ import RcResizeObserver from 'rc-resize-observer'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; import { resetWarned } from 'rc-util/lib/warning'; import { act } from 'react-dom/test-utils'; -import { safeAct } from './utils'; import Table from '../src'; +import { safeAct } from './utils'; describe('Table.FixedColumn', () => { let domSpy; beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); beforeAll(() => { domSpy = spyElementPrototypes(HTMLElement, { @@ -70,7 +70,7 @@ describe('Table.FixedColumn', () => { { name: 'without data', data: [] }, ].forEach(({ name, data: testData }) => { it(`${scrollName} - ${name}`, async () => { - jest.useFakeTimers(); + vi.useFakeTimers(); const wrapper = mount(<Table columns={columns} data={testData} scroll={scroll} />); act(() => { @@ -91,7 +91,7 @@ describe('Table.FixedColumn', () => { }); await safeAct(wrapper); expect(wrapper.render()).toMatchSnapshot(); - jest.useRealTimers(); + vi.useRealTimers(); }); }); }); @@ -107,7 +107,7 @@ describe('Table.FixedColumn', () => { scroll={{ x: 'max-content' }} />, ); - + await safeAct(wrapper); expect(wrapper.find('colgroup').render()).toMatchSnapshot(); @@ -193,7 +193,7 @@ describe('Table.FixedColumn', () => { let errorSpy; beforeAll(() => { - errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); }); beforeEach(() => { diff --git a/tests/FixedHeader.spec.js b/tests/FixedHeader.spec.jsx similarity index 83% rename from tests/FixedHeader.spec.js rename to tests/FixedHeader.spec.jsx index 842c9f45e..c3d3dd8f4 100644 --- a/tests/FixedHeader.spec.js +++ b/tests/FixedHeader.spec.jsx @@ -3,8 +3,8 @@ import RcResizeObserver from 'rc-resize-observer'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; import React from 'react'; import { act } from 'react-dom/test-utils'; -import { safeAct } from './utils'; import Table, { INTERNAL_COL_DEFINE } from '../src'; +import { safeAct } from './utils'; describe('Table.FixedHeader', () => { let domSpy; @@ -17,7 +17,7 @@ describe('Table.FixedHeader', () => { }); beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); visible = true; }); @@ -36,41 +36,52 @@ describe('Table.FixedHeader', () => { scroll={{ y: 10 }} />, ); - wrapper - .find(RcResizeObserver.Collection) - .first() - .props() - .onBatchResize([ - { - data: wrapper.find('ResizeObserver').at(0).props().data, - size: { width: 100, offsetWidth: 100 }, - }, - { - data: wrapper.find('ResizeObserver').at(1).props().data, - size: { width: 200, offsetWidth: 200 }, - }, - { - data: wrapper.find('ResizeObserver').at(2).props().data, - size: { width: 0, offsetWidth: 0 }, - }, - ]); - await safeAct(wrapper); + + async function triggerResize(resizeList) { + wrapper.find(RcResizeObserver.Collection).first().props().onBatchResize(resizeList); + await safeAct(wrapper); + wrapper.update(); + } + + await triggerResize([ + { + data: wrapper.find('ResizeObserver').at(0).props().data, + size: { width: 100, offsetWidth: 100 }, + }, + { + data: wrapper.find('ResizeObserver').at(1).props().data, + size: { width: 200, offsetWidth: 200 }, + }, + { + data: wrapper.find('ResizeObserver').at(2).props().data, + size: { width: 0, offsetWidth: 0 }, + }, + ]); expect(wrapper.find('.rc-table-header table').props().style.visibility).toBeFalsy(); - expect(); expect(wrapper.find('colgroup col').at(0).props().style.width).toEqual(100); expect(wrapper.find('colgroup col').at(1).props().style.width).toEqual(200); expect(wrapper.find('colgroup col').at(2).props().style.width).toEqual(0); // Update columns wrapper.setProps({ columns: [col2, col1] }); - wrapper.update(); + + await triggerResize([ + { + data: wrapper.find('ResizeObserver').at(0).props().data, + size: { width: 200, offsetWidth: 200 }, + }, + { + data: wrapper.find('ResizeObserver').at(1).props().data, + size: { width: 100, offsetWidth: 100 }, + }, + ]); expect(wrapper.find('colgroup col').at(0).props().style.width).toEqual(200); expect(wrapper.find('colgroup col').at(1).props().style.width).toEqual(100); - jest.useRealTimers(); + vi.useRealTimers(); }); it('INTERNAL_COL_DEFINE', async () => { @@ -121,7 +132,7 @@ describe('Table.FixedHeader', () => { }} />, ); - + await safeAct(wrapper); expect(wrapper.find('.rc-table-header table').props().style).toEqual( expect.objectContaining({ visibility: null }), @@ -190,7 +201,7 @@ describe('Table.FixedHeader', () => { ]); act(() => { - jest.runAllTimers(); + vi.runAllTimers(); wrapper.update(); }); @@ -198,7 +209,7 @@ describe('Table.FixedHeader', () => { expect.objectContaining({ width: 93 }), ); - jest.useRealTimers(); + vi.useRealTimers(); }); it('do not mask as ant-table-cell-fix-left-last in nested table parent cell', async () => { @@ -247,16 +258,11 @@ describe('Table.FixedHeader', () => { name: 'Jack1', }, ]; - const wrapper = mount( - <Table - columns={columns} - data={data} - scroll={{ x: true }} - />, - ); + const wrapper = mount(<Table columns={columns} data={data} scroll={{ x: true }} />); await safeAct(wrapper); expect(wrapper.find('td').at(9).props().className).toContain('rc-table-cell-fix-left-last'); - expect(wrapper.find('th').first().props().className).not.toContain('rc-table-cell-fix-left-last'); - + expect(wrapper.find('th').first().props().className).not.toContain( + 'rc-table-cell-fix-left-last', + ); }); }); diff --git a/tests/GroupingColumns.spec.js b/tests/GroupingColumns.spec.jsx similarity index 100% rename from tests/GroupingColumns.spec.js rename to tests/GroupingColumns.spec.jsx index 2f69d74e5..7300265f7 100644 --- a/tests/GroupingColumns.spec.js +++ b/tests/GroupingColumns.spec.jsx @@ -1,5 +1,5 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import Table from '../src'; describe('Table with grouping columns', () => { diff --git a/tests/Hover.spec.tsx b/tests/Hover.spec.tsx index 7f49160c3..01162e7b1 100644 --- a/tests/Hover.spec.tsx +++ b/tests/Hover.spec.tsx @@ -1,7 +1,7 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { resetWarned } from 'rc-util/lib/warning'; import toArray from 'rc-util/lib/Children/toArray'; +import { resetWarned } from 'rc-util/lib/warning'; +import React from 'react'; import Table from '../src'; import type { TableProps } from '../src/Table'; @@ -41,7 +41,7 @@ describe('Table.Hover', () => { it('warning if use `render` for rowSpan', () => { resetWarned(); - const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount( createTable({ diff --git a/tests/Internal.spec.js b/tests/Internal.spec.jsx similarity index 92% rename from tests/Internal.spec.js rename to tests/Internal.spec.jsx index c19c14373..05f1bbf1d 100644 --- a/tests/Internal.spec.js +++ b/tests/Internal.spec.jsx @@ -1,7 +1,7 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import Table from '../src'; -import { INTERNAL_HOOKS } from '../src/Table'; +import { INTERNAL_HOOKS } from '../src/constant'; // All follow test is only for internal usage which should be removed when refactor describe('Table.Internal', () => { diff --git a/tests/Node.spec.jsx b/tests/Node.spec.jsx new file mode 100644 index 000000000..f4d59f2f7 --- /dev/null +++ b/tests/Node.spec.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { renderToString } from 'react-dom/server'; +import Table from '../src'; + +describe('Table.Node', () => { + // Remove env variables + window.Element = null; + global.Element = null; + + it('not crash in node', () => { + console.log(Element); + + const html = renderToString( + <Table + columns={[{ title: 'Name', dataIndex: 'name', key: 'name' }]} + data={[{ key: 'key0', name: 'Lucy' }]} + sticky + />, + ); + + expect(html).toContain('rc-table'); + }); +}); diff --git a/tests/Scroll.spec.js b/tests/Scroll.spec.jsx similarity index 84% rename from tests/Scroll.spec.js rename to tests/Scroll.spec.jsx index c5e243658..122d79664 100644 --- a/tests/Scroll.spec.js +++ b/tests/Scroll.spec.jsx @@ -1,17 +1,31 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; import Table from '../src'; describe('Table.Scroll', () => { - const data = [{ key: 'key0', name: 'Lucy' }, { key: 'key1', name: 'Jack' }]; + const data = [ + { key: 'key0', name: 'Lucy' }, + { key: 'key1', name: 'Jack' }, + ]; const createTable = props => { const columns = [{ title: 'Name', dataIndex: 'name', key: 'name' }]; return <Table columns={columns} data={data} {...props} />; }; + it('should always has content when scroll.x is enabled', () => { + const data = []; + const createTable = props => { + return <Table data={data} {...props} />; + }; + + const wrapper = mount(createTable({ scroll: { x: true } })); + + expect(wrapper.find('.rc-table-tbody').hostNodes().text()).toContain('No Data'); + }); + it('renders scroll.x is true', () => { const wrapper = mount(createTable({ scroll: { x: true } })); expect(wrapper.find('table').props().style.width).toEqual('auto'); @@ -36,14 +50,14 @@ describe('Table.Scroll', () => { }); it('fire scroll event', () => { - jest.useFakeTimers(); + vi.useFakeTimers(); let scrollLeft = 0; let scrollTop = 0; - const setScrollLeft = jest.fn((_, val) => { + const setScrollLeft = vi.fn((_, val) => { scrollLeft = val; }); - const setScrollTop = jest.fn((_, val) => { + const setScrollTop = vi.fn((_, val) => { scrollTop = val; }); @@ -85,7 +99,7 @@ describe('Table.Scroll', () => { />, ); - jest.runAllTimers(); + vi.runAllTimers(); // Use `onScroll` directly since simulate not support `currentTarget` act(() => { const headerDiv = wrapper.find('div.rc-table-header').instance(); @@ -96,7 +110,7 @@ describe('Table.Scroll', () => { }); headerDiv.dispatchEvent(wheelEvent); - jest.runAllTimers(); + vi.runAllTimers(); }); expect(setScrollLeft).toHaveBeenCalledWith(undefined, 10); @@ -114,11 +128,11 @@ describe('Table.Scroll', () => { }, }); }); - jest.runAllTimers(); + vi.runAllTimers(); expect(setScrollLeft).toHaveBeenCalledWith(undefined, 33); setScrollLeft.mockReset(); domSpy.mockRestore(); - jest.useRealTimers(); + vi.useRealTimers(); }); }); diff --git a/tests/Sticky.spec.js b/tests/Sticky.spec.jsx similarity index 96% rename from tests/Sticky.spec.js rename to tests/Sticky.spec.jsx index f1ccbda2c..34cc1cb8d 100644 --- a/tests/Sticky.spec.js +++ b/tests/Sticky.spec.jsx @@ -1,13 +1,13 @@ -import React from 'react'; -import { act } from 'react-dom/test-utils'; import { mount } from 'enzyme'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; import Table from '../src'; import { safeAct } from './utils'; describe('Table.Sticky', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); it('Sticky Header', async () => { const col1 = { dataIndex: 'light', width: 100 }; @@ -53,7 +53,7 @@ describe('Table.Sticky', () => { top: 10, }); - jest.useRealTimers(); + vi.useRealTimers(); }); it('Sticky scroll', async () => { @@ -120,7 +120,7 @@ describe('Table.Sticky', () => { ); await act(async () => { - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); }); @@ -133,7 +133,7 @@ describe('Table.Sticky', () => { await act(async () => { global.dispatchEvent(resizeEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); @@ -143,12 +143,12 @@ describe('Table.Sticky', () => { await act(async () => { global.innerHeight = oldInnerHeight; global.dispatchEvent(resizeEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); - const mockFn = jest.fn(); + const mockFn = vi.fn(); wrapper .find('.rc-table-sticky-scroll-bar') @@ -165,7 +165,7 @@ describe('Table.Sticky', () => { await act(async () => { document.body.dispatchEvent(mousemoveEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); @@ -179,7 +179,7 @@ describe('Table.Sticky', () => { mousemoveEvent.pageX = -50; document.body.dispatchEvent(mousemoveEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); @@ -193,7 +193,7 @@ describe('Table.Sticky', () => { mousemoveEvent.buttons = 0; document.body.dispatchEvent(mousemoveEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); @@ -209,11 +209,10 @@ describe('Table.Sticky', () => { window.pageYOffset = 0; mockFn.mockRestore(); domSpy.mockRestore(); - jest.useRealTimers(); + vi.useRealTimers(); }); it('Sticky Header with border classname', async () => { - const TableDemo = props => { return ( <div @@ -251,11 +250,10 @@ describe('Table.Sticky', () => { }); expect(wrapper.find('.rc-table-cell-fix-sticky')).not.toBe(undefined); - jest.useRealTimers(); + vi.useRealTimers(); }); it('Sticky Header with scroll-y', async () => { - const TableDemo = props => { return ( <div @@ -293,11 +291,10 @@ describe('Table.Sticky', () => { right: 15, }); - jest.useRealTimers(); + vi.useRealTimers(); }); it('Sticky scroll with getContainer', async () => { - window.pageYOffset = 900; document.documentElement.scrollTop = 200; const container = document.createElement('ol'); @@ -393,7 +390,7 @@ describe('Table.Sticky', () => { ); await act(async () => { - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); }); @@ -405,7 +402,7 @@ describe('Table.Sticky', () => { transform: 'translate3d(0px, 0, 0)', }); - const mockFn = jest.fn(); + const mockFn = vi.fn(); wrapper .find('.rc-table-sticky-scroll-bar') @@ -420,7 +417,7 @@ describe('Table.Sticky', () => { await act(async () => { document.body.dispatchEvent(mousemoveEvent); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); @@ -436,6 +433,6 @@ describe('Table.Sticky', () => { domSpy.mockRestore(); sectionSpy.mockRestore(); mockFn.mockRestore(); - jest.useRealTimers(); + vi.useRealTimers(); }); }); diff --git a/tests/Summary.spec.tsx b/tests/Summary.spec.tsx index d86c927f8..61d9b9a6c 100644 --- a/tests/Summary.spec.tsx +++ b/tests/Summary.spec.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import Table from '../src'; describe('Table.Summary', () => { @@ -53,6 +53,35 @@ describe('Table.Summary', () => { expect(wrapper.find('tfoot').render()).toMatchSnapshot(); }); + it('summary row click', async () => { + const onClick = vi.fn(); + const wrapper = mount( + <Table + columns={[ + { dataIndex: 'a', fixed: 'left', width: 10 }, + { dataIndex: 'b', fixed: 'left', width: 20 }, + { dataIndex: 'c', width: 30 }, + ]} + data={[{ key: 1, a: 2, b: 3, c: 4 }]} + summary={() => ( + <Table.Summary.Row onClick={onClick}> + <Table.Summary.Cell colSpan={2} index={0}> + Light + </Table.Summary.Cell> + <Table.Summary.Cell index={2}>Bamboo</Table.Summary.Cell> + <Table.Summary.Cell index={3} align="right"> + 112.5 + </Table.Summary.Cell> + </Table.Summary.Row> + )} + />, + ); + + const tr = wrapper.find('tfoot tr').first(); + tr.simulate('click'); + expect(onClick).toHaveBeenCalled(); + }); + describe('fixed summary', () => { const getSummaryTable = (fixed: boolean | 'top' | 'bottom') => mount( diff --git a/tests/Table.spec.js b/tests/Table.spec.jsx similarity index 84% rename from tests/Table.spec.js rename to tests/Table.spec.jsx index 1a60f7f6c..1c62fe31f 100644 --- a/tests/Table.spec.js +++ b/tests/Table.spec.jsx @@ -1,10 +1,11 @@ import { mount } from 'enzyme'; import { resetWarned } from 'rc-util/lib/warning'; import React from 'react'; +import { VariableSizeGrid as Grid } from 'react-window'; import Table, { INTERNAL_COL_DEFINE } from '../src'; import BodyRow from '../src/Body/BodyRow'; import Cell from '../src/Cell'; -import { INTERNAL_HOOKS } from '../src/Table'; +import { INTERNAL_HOOKS } from '../src/constant'; describe('Table.Basic', () => { const data = [ @@ -358,7 +359,7 @@ describe('Table.Basic', () => { describe('dataIndex', () => { it("pass record to render when it's falsy", () => { [null, undefined, '', []].forEach(dataIndex => { - const cellRender = jest.fn(); + const cellRender = vi.fn(); const columns = [ { title: 'Name', @@ -504,7 +505,7 @@ describe('Table.Basic', () => { }); it('shows error if no rowKey specify', () => { - const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const spy = vi.spyOn(console, 'error').mockImplementation(() => {}); const localData = [{ name: 'Lucy' }, { name: 'Jack' }]; mount(createTable({ data: localData })); expect(spy.mock.calls[0][0]).toMatch( @@ -595,7 +596,7 @@ describe('Table.Basic', () => { }); it('renders onHeaderRow correctly', () => { - const onHeaderRow = jest.fn((columns, index) => ({ + const onHeaderRow = vi.fn((columns, index) => ({ id: `header-row-${index}`, })); const wrapper = mount(createTable({ onHeaderRow })); @@ -666,7 +667,7 @@ describe('Table.Basic', () => { describe('scroll content', () => { it('with scroll', () => { resetWarned(); - const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const wrapper = mount( createTable({ columns: [{ dataIndex: 'a' }, { dataIndex: 'b', width: 903 }], @@ -683,22 +684,24 @@ describe('Table.Basic', () => { ); errSpy.mockRestore(); }); + }); - it('without scroll', () => { - resetWarned(); - const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); - mount( - createTable({ - components: { - body: () => <h1>Bamboo</h1>, - }, - }), - ); - expect(errSpy).toHaveBeenCalledWith( - 'Warning: `components.body` with render props is only work on `scroll.y`.', - ); - errSpy.mockRestore(); - }); + it('without warning - columns is empty', () => { + resetWarned(); + const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + mount( + createTable({ + columns: [], + components: { + body: () => <h1>Bamboo</h1>, + }, + scroll: { x: 100, y: 100 }, + }), + ); + expect(errSpy).not.toHaveBeenCalledWith( + 'Warning: When use `components.body` with render props. Each column should have a fixed `width` value.', + ); + errSpy.mockRestore(); }); it('not crash', () => { @@ -757,7 +760,7 @@ describe('Table.Basic', () => { let spy; beforeAll(() => { - spy = jest.spyOn(console, 'error').mockImplementation(() => {}); + spy = vi.spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { @@ -769,7 +772,7 @@ describe('Table.Basic', () => { }); it('fires row click event', () => { - const onClick = jest.fn(); + const onClick = vi.fn(); const wrapper = mount(createTable({ onRow: () => ({ onClick }) })); const tr = wrapper.find('tbody tr').first(); @@ -782,7 +785,7 @@ describe('Table.Basic', () => { }); it('fires double row click event', () => { - const onDoubleClick = jest.fn(); + const onDoubleClick = vi.fn(); const wrapper = mount(createTable({ onRow: () => ({ onDoubleClick }) })); const tr = wrapper.find('tbody tr').first(); @@ -795,7 +798,7 @@ describe('Table.Basic', () => { }); it('fires row contextmenu event', () => { - const onContextMenu = jest.fn(); + const onContextMenu = vi.fn(); const wrapper = mount(createTable({ onRow: () => ({ onContextMenu }) })); const tr = wrapper.find('tbody tr').first(); @@ -808,7 +811,7 @@ describe('Table.Basic', () => { }); it('fires onRowMouseEnter', () => { - const onMouseEnter = jest.fn(); + const onMouseEnter = vi.fn(); const wrapper = mount( createTable({ onRow: () => ({ onMouseEnter }), @@ -826,7 +829,7 @@ describe('Table.Basic', () => { }); it('fires onRowMouseLeave', () => { - const onMouseLeave = jest.fn(); + const onMouseLeave = vi.fn(); const wrapper = mount( createTable({ onRow: () => ({ onMouseLeave }), @@ -1037,7 +1040,7 @@ describe('Table.Basic', () => { }); it('not block nest children', () => { - const onExpandedRowsChange = jest.fn(); + const onExpandedRowsChange = vi.fn(); const wrapper = mount( <Table @@ -1153,4 +1156,168 @@ describe('Table.Basic', () => { expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.find('col')).toHaveLength(tColumns.length + 1); }); + it('columns support JSX condition', () => { + const Example = () => { + const [count, setCount] = React.useState(0); + const columns = [ + { + title: 'title', + dataIndex: 'a', + render: () => count, + }, + count === 1 && { + title: 'title2', + dataIndex: 'b', + render: () => count + 1, + }, + count === 2 + ? { + title: 'title3', + dataIndex: 'c', + render: () => count + 1, + } + : null, + ]; + return ( + <> + <button + onClick={() => { + setCount(val => val + 1); + }} + > + Click {count} times + </button> + <Table columns={columns} data={data} /> + </> + ); + }; + const wrapper = mount(<Example />); + + wrapper.find('button').simulate('click'); + expect(wrapper.find('.rc-table-cell').at(1).text()).toEqual('title2'); + + wrapper.find('button').simulate('click'); + expect(wrapper.find('.rc-table-cell').at(1).text()).toEqual('title3'); + + expect(wrapper.render()).toMatchSnapshot(); + }); + + it('using both column children and component body simultaneously', () => { + const width = 150; + const noChildColLen = 4; + const ChildColLen = 4; + const buildChildDataIndex = n => `col${n}`; + const columns = Array.from({ length: noChildColLen }, (_, i) => ({ + title: `第 ${i} 列`, + dataIndex: buildChildDataIndex(i), + width, + })).concat( + Array.from({ length: ChildColLen }, (_, i) => ({ + title: `第 ${i} 分组`, + dataIndex: `parentCol${i}`, + width: width * 2, + children: [ + { + title: `第 ${noChildColLen + i} 列`, + dataIndex: buildChildDataIndex(noChildColLen + i), + width, + }, + { + title: `第 ${noChildColLen + 1 + i} 列`, + dataIndex: buildChildDataIndex(noChildColLen + 1 + i), + width, + }, + ], + })), + ); + const data = Array.from({ length: 10000 }, (_, r) => { + const colLen = noChildColLen + ChildColLen * 2; + const record = {}; + for (let c = 0; c < colLen; c++) { + record[buildChildDataIndex(c)] = `r${r}, c${c}`; + } + return record; + }); + const Demo = props => { + const gridRef = React.useRef(); + const [connectObject] = React.useState(() => { + const obj = {}; + Object.defineProperty(obj, 'scrollLeft', { + get: () => { + if (gridRef.current) { + return gridRef.current?.state?.scrollLeft; + } + return null; + }, + set: scrollLeft => { + if (gridRef.current) { + gridRef.current.scrollTo({ scrollLeft }); + } + }, + }); + + return obj; + }); + + React.useEffect(() => { + gridRef.current.resetAfterIndices({ + columnIndex: 0, + shouldForceUpdate: false, + }); + }, []); + + const renderVirtualList = (rawData, { scrollbarSize, ref, onScroll }) => { + ref.current = connectObject; + return ( + <Grid + ref={gridRef} + className="virtual-grid" + columnCount={columns.length} + columnWidth={index => { + const { width } = columns[index]; + return index === columns.length - 1 ? width - scrollbarSize - 1 : width; + }} + height={300} + rowCount={rawData.length} + rowHeight={() => 50} + width={800} + onScroll={({ scrollLeft }) => { + onScroll({ scrollLeft }); + }} + > + {({ columnIndex, rowIndex, style }) => ( + <div + className={`virtual-cell ${ + columnIndex === columns.length - 1 ? 'virtual-cell-last' : '' + }`} + style={style} + > + r{rowIndex}, c{columnIndex} + </div> + )} + </Grid> + ); + }; + + return ( + <Table + style={{ width: 800 }} + tableLayout="fixed" + columns={props.columns} + data={props.data} + scroll={{ y: 300, x: 300 }} + components={{ + body: renderVirtualList, + }} + /> + ); + }; + const wrapper = mount(<Demo columns={columns} data={data} />); + expect( + wrapper + .find('col') + .at(noChildColLen + ChildColLen * 2 - 1) + .props().style.width + wrapper.find('col').last().props().style.width, + ).toEqual(width); + }); }); diff --git a/tests/Virtual.spec.tsx b/tests/Virtual.spec.tsx new file mode 100644 index 000000000..10742ffb5 --- /dev/null +++ b/tests/Virtual.spec.tsx @@ -0,0 +1,415 @@ +import { act, fireEvent, render } from '@testing-library/react'; +import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil'; +import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil'; +import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import { resetWarned } from 'rc-util/lib/warning'; +import React from 'react'; +import { VirtualTable, type Reference, type VirtualTableProps } from '../src'; + +global.scrollToConfig = null; + +vi.mock('rc-virtual-list', async () => { + const RealVirtualList = ((await vi.importActual('rc-virtual-list')) as any).default; + + const WrapperVirtualList = React.forwardRef((props: any, ref) => { + const myRef = React.useRef(null); + + React.useImperativeHandle(ref, () => ({ + ...myRef.current, + scrollTo: (config: any) => { + global.scrollToConfig = config; + return myRef.current.scrollTo(config); + }, + })); + + return <RealVirtualList ref={myRef} {...props} data-scroll-width={props.scrollWidth} />; + }); + + return { + default: WrapperVirtualList, + }; +}); + +describe('Table.Virtual', () => { + let scrollLeftCalled = false; + + beforeAll(() => { + spyElementPrototypes(HTMLElement, { + getBoundingClientRect: () => ({ + width: 50, + }), + scrollLeft: { + get: () => { + scrollLeftCalled = true; + return 100; + }, + set: () => {}, + }, + }); + }); + + beforeEach(() => { + scrollLeftCalled = false; + global.scrollToConfig = null; + vi.useFakeTimers(); + resetWarned(); + }); + + afterEach(() => { + vi.clearAllTimers(); + vi.useRealTimers(); + }); + + async function waitFakeTimer() { + for (let i = 0; i < 10; i += 1) { + // eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-loop-func + await act(async () => { + vi.advanceTimersByTime(100); + await Promise.resolve(); + }); + } + } + + function resize(target: HTMLElement) { + act(() => { + onLibResize([{ target } as any]); + onEsResize([{ target } as any]); + }); + } + + function getTable(props?: Partial<VirtualTableProps<any>> & { ref?: React.Ref<Reference> }) { + return render( + <VirtualTable + columns={[ + { + dataIndex: 'name', + }, + { + dataIndex: 'age', + }, + { + dataIndex: 'address', + }, + ]} + rowKey="name" + scroll={{ x: 100, y: 100 }} + listItemHeight={20} + data={new Array(100).fill(null).map((_, index) => ({ + name: `name${index}`, + age: index, + address: `address${index}`, + }))} + {...props} + />, + ); + } + + it('should work', async () => { + const { container } = getTable(); + + await waitFakeTimer(); + + expect(container.querySelector('.rc-virtual-list')).toBeTruthy(); + }); + + it('warning for scroll props is not a number', () => { + const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + + getTable({ + scroll: { + x: true, + } as any, + }); + + expect(errSpy).toHaveBeenCalledWith('Warning: `scroll.x` in virtual table must be number.'); + expect(errSpy).toHaveBeenCalledWith('Warning: `scroll.y` in virtual table must be number.'); + }); + + it('rowSpan', () => { + const { container } = getTable({ + columns: [ + { + dataIndex: 'name', + onCell: (_, index) => ({ + rowSpan: index % 2 ? 0 : 2, + }), + }, + ], + }); + + expect(container.querySelector('.rc-table-row-extra').textContent).toBe('name0'); + }); + + it('empty', () => { + const { container } = getTable({ + data: [], + }); + + expect(container.querySelector('.rc-table-placeholder').textContent).toBe('No Data'); + }); + + describe('expandable', () => { + it('basic', () => { + const { container } = getTable({ + expandable: { + expandedRowKeys: ['name0', 'name3'], + expandedRowRender: record => record.name, + }, + }); + + const expandedCells = container.querySelectorAll('.rc-table-expanded-row-cell'); + expect(expandedCells).toHaveLength(2); + expect(expandedCells[0].textContent).toBe('name0'); + expect(expandedCells[1].textContent).toBe('name3'); + }); + + it('fixed', () => { + const { container } = getTable({ + columns: [ + { + dataIndex: 'name', + fixed: 'left', + }, + { + dataIndex: 'age', + }, + { + dataIndex: 'address', + }, + ], + expandable: { + expandedRowKeys: ['name0', 'name3'], + expandedRowRender: record => record.name, + }, + }); + + const expandedCells = container.querySelectorAll('.rc-table-expanded-row-cell-fixed'); + expect(expandedCells).toHaveLength(2); + expect(expandedCells[0].textContent).toBe('name0'); + expect(expandedCells[1].textContent).toBe('name3'); + }); + }); + + it('scroll sync', () => { + const { container } = getTable(); + + resize(container.querySelector('.rc-table')!); + + scrollLeftCalled = false; + expect(scrollLeftCalled).toBeFalsy(); + + fireEvent.wheel(container.querySelector('.rc-virtual-list-holder')!, { + deltaX: 10, + }); + expect(scrollLeftCalled).toBeTruthy(); + }); + + it('should follow correct width', () => { + const { container } = getTable({ + columns: [ + { + width: 93, + }, + { + width: 510, + }, + ], + scroll: { + x: 100, + y: 10, + }, + data: [{}], + }); + + expect(container.querySelector('.rc-virtual-list')).toHaveAttribute('data-scroll-width', '603'); + }); + + it('render params should correct', () => { + const { container } = getTable({ + columns: [ + { + width: 93, + render: (_, __, index) => <div className="bamboo">{index}</div>, + }, + ], + scroll: { + x: 1128, + y: 10, + }, + data: [{}], + }); + + expect(container.querySelector('.bamboo').textContent).toEqual('0'); + }); + + it('columns less than width', async () => { + const { container } = getTable({ + columns: [{}, {}], + scroll: { + y: 10, + }, + getContainerWidth: () => 200, + data: [{}], + }); + + resize(container.querySelector('.rc-table')); + + await waitFakeTimer(); + + expect(container.querySelectorAll('col')).toHaveLength(2); + expect(container.querySelectorAll('col')[0]).toHaveStyle({ width: '100px' }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ width: '100px' }); + }); + + it('should fill width as scrollX if scrollX is larger', async () => { + const { container } = getTable({ + columns: [ + { + width: 100, + }, + ], + scroll: { + x: 1128, + y: 10, + }, + getContainerWidth: () => 200, + data: [{}], + }); + + expect(container.querySelector('.rc-virtual-list')).toHaveAttribute( + 'data-scroll-width', + '1128', + ); + }); + + it('sticky header with virtual should work', async () => { + const { container } = getTable({ sticky: { offsetHeader: 10 } }); + + await waitFakeTimer(); + + expect(container.querySelector('.rc-table-header')).toHaveStyle({ + overflow: 'hidden', + top: '10px', + }); + + expect(container.querySelector('.rc-table-header')).toHaveClass( + 'rc-table-header', + 'rc-table-sticky-holder', + ); + }); + + it('sticky scrollbar with virtual should work', async () => { + const { container } = getTable({ sticky: { offsetScroll: 10 } }); + + await waitFakeTimer(); + + expect(container.querySelector('.rc-virtual-list-scrollbar-horizontal')).toHaveStyle({ + position: 'sticky', + bottom: '10px', + }); + }); + + it('scrollTo should pass', async () => { + const tblRef = React.createRef<Reference>(); + getTable({ ref: tblRef }); + + tblRef.current.scrollTo({ + index: 99, + }); + + await waitFakeTimer(); + + expect(global.scrollToConfig).toEqual({ + index: 99, + }); + }); + + describe('auto width', () => { + async function prepareTable(columns: any[]) { + const { container } = getTable({ + getContainerWidth: () => 300, + columns: columns, + }); + + resize(container.querySelector('.rc-table')!); + await waitFakeTimer(); + + return container; + } + + it('fill rest', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 100, + }, + { + dataIndex: 'age', + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '100px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '200px', + }); + }); + + it('stretch', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 100, + }, + { + dataIndex: 'age', + width: 100, + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '150px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '150px', + }); + }); + + it('exceed', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 500, + }, + { + dataIndex: 'age', + width: 600, + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '500px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '600px', + }); + }); + }); + + it('components', async () => { + const { container } = getTable({ + components: { + header: { + cell: function MyTh(props: any) { + return <th {...props} data-mark="my-th" />; + }, + }, + }, + }); + + await waitFakeTimer(); + + expect(container.querySelector('thead th')).toHaveAttribute('data-mark', 'my-th'); + }); +}); diff --git a/tests/__snapshots__/ExpandRow.spec.js.snap b/tests/__snapshots__/ExpandRow.spec.js.snap deleted file mode 100644 index 2566c90c5..000000000 --- a/tests/__snapshots__/ExpandRow.spec.js.snap +++ /dev/null @@ -1,1284 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Table.Expand childrenColumnName 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-expanded" - /> - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-1" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-1" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jim - </td> - <td - class="rc-table-cell" - > - 1 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand does not crash if scroll is not set 1`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - class="rc-table-expand-icon-col" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - /> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell" - scope="col" - > - Gender - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - <td - class="rc-table-cell" - > - F - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - <td - class="rc-table-cell" - > - M - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand does not crash if scroll is not set 2`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - class="rc-table-expand-icon-col" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - /> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell" - scope="col" - > - Gender - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - <td - class="rc-table-cell" - > - F - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - <td - class="rc-table-cell" - > - M - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand not use nest when children is invalidate 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="2" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="4" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="5" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand renders fixed column correctly work 1`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 903px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - class="rc-table-expand-icon-col" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - /> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - scope="col" - style="position: sticky; left: 0px;" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - scope="col" - style="position: sticky; right: 0px;" - > - Gender - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-expanded" - /> - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - F - </td> - </tr> - <tr - class="rc-table-expanded-row rc-table-expanded-row-level-1" - > - <td - class="rc-table-cell" - colspan="4" - > - <div - class="rc-table-expanded-row-fixed" - style="width: 1128px; position: sticky; left: 0px; overflow: hidden;" - > - <p> - extra data - </p> - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-expanded" - /> - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - M - </td> - </tr> - <tr - class="rc-table-expanded-row rc-table-expanded-row-level-1" - > - <td - class="rc-table-cell" - colspan="4" - > - <div - class="rc-table-expanded-row-fixed" - style="width: 1128px; position: sticky; left: 0px; overflow: hidden;" - > - <p> - extra data - </p> - </div> - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand renders tree row correctly 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-expanded" - /> - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-1" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-1" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jim - </td> - <td - class="rc-table-cell" - > - 1 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand renders tree row correctly with different children 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="3" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="4" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="5" - > - <td - class="rc-table-cell rc-table-cell-with-append" - > - <span - class="rc-table-row-indent indent-level-0" - /> - <span - class="rc-table-row-expand-icon rc-table-row-spaced" - /> - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand work in expandable fix 1`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 903px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - class="rc-table-expand-icon-col" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - /> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell" - scope="col" - > - Gender - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - <td - class="rc-table-cell" - > - F - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - style="position: sticky; left: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - <td - class="rc-table-cell" - > - M - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Expand work in expandable fix 2`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 903px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col /> - <col /> - <col /> - <col - class="rc-table-expand-icon-col" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell" - scope="col" - > - Gender - </th> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - > - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - > - 27 - </td> - <td - class="rc-table-cell" - > - F - </td> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - > - 28 - </td> - <td - class="rc-table-cell" - > - M - </td> - <td - class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - <span - class="rc-table-row-expand-icon rc-table-row-collapsed" - /> - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; diff --git a/tests/__snapshots__/ExpandRow.spec.jsx.snap b/tests/__snapshots__/ExpandRow.spec.jsx.snap new file mode 100644 index 000000000..96f841d8f --- /dev/null +++ b/tests/__snapshots__/ExpandRow.spec.jsx.snap @@ -0,0 +1,1554 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Table.Expand > childrenColumnName 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-expanded" + /> + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-1" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-1" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jim + </td> + <td + class="rc-table-cell" + > + 1 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > does not crash if scroll is not set 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + class="rc-table-expand-icon-col" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + /> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell" + scope="col" + > + Gender + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + <td + class="rc-table-cell" + > + F + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + <td + class="rc-table-cell" + > + M + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > does not crash if scroll is not set 2`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + class="rc-table-expand-icon-col" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + /> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell" + scope="col" + > + Gender + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + <td + class="rc-table-cell" + > + F + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + <td + class="rc-table-cell" + > + M + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > not use nest when children is invalidate 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="2" + > + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="4" + > + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="5" + > + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > renders fixed column correctly > work 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 903px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + class="rc-table-expand-icon-col" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + /> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + scope="col" + style="position: sticky; left: 0px;" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + scope="col" + style="position: sticky; right: 0px;" + > + Gender + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-expanded" + /> + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + F + </td> + </tr> + <tr + class="rc-table-expanded-row rc-table-expanded-row-level-1" + > + <td + class="rc-table-cell" + colspan="4" + > + <div + class="rc-table-expanded-row-fixed" + style="width: 1128px; position: sticky; left: 0px; overflow: hidden;" + > + <p> + extra data + </p> + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-expanded" + /> + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + M + </td> + </tr> + <tr + class="rc-table-expanded-row rc-table-expanded-row-level-1" + > + <td + class="rc-table-cell" + colspan="4" + > + <div + class="rc-table-expanded-row-fixed" + style="width: 1128px; position: sticky; left: 0px; overflow: hidden;" + > + <p> + extra data + </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > renders tree row correctly 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-expanded" + /> + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-1" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-1" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jim + </td> + <td + class="rc-table-cell" + > + 1 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > renders tree row correctly with different children 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="3" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="4" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="5" + > + <td + class="rc-table-cell rc-table-cell-with-append" + > + <span + class="rc-table-row-indent indent-level-0" + /> + <span + class="rc-table-row-expand-icon rc-table-row-spaced" + /> + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > work in expandable fix 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 903px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + class="rc-table-expand-icon-col" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + /> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell" + scope="col" + > + Gender + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + <td + class="rc-table-cell" + > + F + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + style="position: sticky; left: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + <td + class="rc-table-cell" + > + M + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Expand > work in expandable fix 2`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 903px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col /> + <col /> + <col /> + <col + class="rc-table-expand-icon-col" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell" + scope="col" + > + Gender + </th> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + > + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + > + 27 + </td> + <td + class="rc-table-cell" + > + F + </td> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + > + 28 + </td> + <td + class="rc-table-cell" + > + M + </td> + <td + class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + <span + class="rc-table-row-expand-icon rc-table-row-collapsed" + /> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; diff --git a/tests/__snapshots__/FixedColumn.spec.js.snap b/tests/__snapshots__/FixedColumn.spec.js.snap deleted file mode 100644 index 99648e662..000000000 --- a/tests/__snapshots__/FixedColumn.spec.js.snap +++ /dev/null @@ -1,2965 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Table.FixedColumn fixed column renders correctly RTL 1`] = ` -<div - class="rc-table rc-table-rtl rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 1px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col - style="width: 100px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell rc-table-cell-fix-right" - scope="col" - style="position: sticky; right: 0px;" - > - title1 - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - scope="col" - style="position: sticky; right: 0px;" - title="title2" - > - title2 - </th> - <th - class="rc-table-cell" - scope="col" - > - title3 - </th> - <th - class="rc-table-cell" - scope="col" - > - title4 - </th> - <th - class="rc-table-cell" - scope="col" - > - title5 - </th> - <th - class="rc-table-cell" - scope="col" - > - title6 - </th> - <th - class="rc-table-cell" - scope="col" - > - title7 - </th> - <th - class="rc-table-cell" - scope="col" - > - title8 - </th> - <th - class="rc-table-cell" - scope="col" - > - title9 - </th> - <th - class="rc-table-cell" - scope="col" - > - title10 - </th> - <th - class="rc-table-cell" - scope="col" - > - title11 - </th> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - scope="col" - style="position: sticky; left: 0px;" - > - title12 - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 123 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - > - xxxxxxxx - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - cdd - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - > - edd12221 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="3" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="4" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="5" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="6" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="7" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="8" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="9" - > - <td - class="rc-table-cell rc-table-cell-fix-right" - style="position: sticky; right: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" - style="position: sticky; right: 0px;" - title="1111" - > - <span> - 1111 - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" - style="position: sticky; left: 0px;" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.FixedColumn renders correctly all column has width should use it 1`] = ` -<colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> -</colgroup> -`; - -exports[`Table.FixedColumn renders correctly scrollX - with data 1`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 1200px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col - style="width: 100px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell rc-table-cell-fix-left" - scope="col" - style="position: sticky; left: 0px;" - > - title1 - </th> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - scope="col" - style="position: sticky; left: 93px;" - title="title2" - > - <span - class="rc-table-cell-content" - > - title2 - </span> - </th> - <th - class="rc-table-cell" - scope="col" - > - title3 - </th> - <th - class="rc-table-cell" - scope="col" - > - title4 - </th> - <th - class="rc-table-cell" - scope="col" - > - title5 - </th> - <th - class="rc-table-cell" - scope="col" - > - title6 - </th> - <th - class="rc-table-cell" - scope="col" - > - title7 - </th> - <th - class="rc-table-cell" - scope="col" - > - title8 - </th> - <th - class="rc-table-cell" - scope="col" - > - title9 - </th> - <th - class="rc-table-cell" - scope="col" - > - title10 - </th> - <th - class="rc-table-cell" - scope="col" - > - title11 - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - scope="col" - style="position: sticky; right: 0px;" - > - title12 - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 123 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - xxxxxxxx - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - cdd - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - edd12221 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="3" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="4" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="5" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="6" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="7" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="8" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="9" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.FixedColumn renders correctly scrollX - without data 1`] = ` -<div - class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - style="overflow-x: auto; overflow-y: hidden;" - > - <table - style="width: 1200px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col - style="width: 100px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell rc-table-cell-fix-left" - scope="col" - style="position: sticky; left: 0px;" - > - title1 - </th> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - scope="col" - style="position: sticky; left: 93px;" - title="title2" - > - <span - class="rc-table-cell-content" - > - title2 - </span> - </th> - <th - class="rc-table-cell" - scope="col" - > - title3 - </th> - <th - class="rc-table-cell" - scope="col" - > - title4 - </th> - <th - class="rc-table-cell" - scope="col" - > - title5 - </th> - <th - class="rc-table-cell" - scope="col" - > - title6 - </th> - <th - class="rc-table-cell" - scope="col" - > - title7 - </th> - <th - class="rc-table-cell" - scope="col" - > - title8 - </th> - <th - class="rc-table-cell" - scope="col" - > - title9 - </th> - <th - class="rc-table-cell" - scope="col" - > - title10 - </th> - <th - class="rc-table-cell" - scope="col" - > - title11 - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - scope="col" - style="position: sticky; right: 0px;" - > - title12 - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-placeholder" - > - <td - class="rc-table-cell" - colspan="12" - > - <div - class="rc-table-expanded-row-fixed" - style="width: 1000px; position: sticky; left: 0px; overflow: hidden;" - > - No Data - </div> - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.FixedColumn renders correctly scrollXY - with data 1`] = ` -<div - class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-header" - style="overflow: hidden;" - > - <table - style="table-layout: fixed;" - > - <colgroup> - <col - style="width: 93px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 15px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell rc-table-cell-fix-left" - scope="col" - style="position: sticky; left: 0px;" - > - title1 - </th> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - scope="col" - style="position: sticky; left: 93px;" - title="title2" - > - <span - class="rc-table-cell-content" - > - title2 - </span> - </th> - <th - class="rc-table-cell" - scope="col" - > - title3 - </th> - <th - class="rc-table-cell" - scope="col" - > - title4 - </th> - <th - class="rc-table-cell" - scope="col" - > - title5 - </th> - <th - class="rc-table-cell" - scope="col" - > - title6 - </th> - <th - class="rc-table-cell" - scope="col" - > - title7 - </th> - <th - class="rc-table-cell" - scope="col" - > - title8 - </th> - <th - class="rc-table-cell" - scope="col" - > - title9 - </th> - <th - class="rc-table-cell" - scope="col" - > - title10 - </th> - <th - class="rc-table-cell" - scope="col" - > - title11 - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - scope="col" - style="position: sticky; right: 15px;" - > - title12 - </th> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" - style="position: sticky; right: 0px;" - /> - </tr> - </thead> - </table> - </div> - <div - class="rc-table-body" - style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" - > - <table - style="width: 1200px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col - style="width: 100px;" - /> - </colgroup> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="1" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 123 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell" - > - xxxxxxxx - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - xxxxxxxx - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="2" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - cdd - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - > - edd12221 - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="3" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="4" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="5" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="6" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="7" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="8" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="9" - > - <td - class="rc-table-cell rc-table-cell-fix-left" - style="position: sticky; left: 0px;" - > - 133 - </td> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - style="position: sticky; left: 93px;" - title="1111" - > - <span - class="rc-table-cell-content" - > - <span> - 1111 - </span> - </span> - </td> - <td - class="rc-table-cell" - > - edd12221 - </td> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - style="position: sticky; right: 0px;" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.FixedColumn renders correctly scrollXY - without data 1`] = ` -<div - class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-header" - style="overflow: hidden;" - > - <table - style="table-layout: fixed;" - > - <colgroup> - <col - style="width: 93px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 1000px;" - /> - <col - style="width: 15px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell rc-table-cell-fix-left" - scope="col" - style="position: sticky; left: 0px;" - > - title1 - </th> - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" - scope="col" - style="position: sticky; left: 93px;" - title="title2" - > - <span - class="rc-table-cell-content" - > - title2 - </span> - </th> - <th - class="rc-table-cell" - scope="col" - > - title3 - </th> - <th - class="rc-table-cell" - scope="col" - > - title4 - </th> - <th - class="rc-table-cell" - scope="col" - > - title5 - </th> - <th - class="rc-table-cell" - scope="col" - > - title6 - </th> - <th - class="rc-table-cell" - scope="col" - > - title7 - </th> - <th - class="rc-table-cell" - scope="col" - > - title8 - </th> - <th - class="rc-table-cell" - scope="col" - > - title9 - </th> - <th - class="rc-table-cell" - scope="col" - > - title10 - </th> - <th - class="rc-table-cell" - scope="col" - > - title11 - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - scope="col" - style="position: sticky; right: 15px;" - > - title12 - </th> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" - style="position: sticky; right: 0px;" - /> - </tr> - </thead> - </table> - </div> - <div - class="rc-table-body" - style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" - > - <table - style="width: 1200px; min-width: 100%; table-layout: fixed;" - > - <colgroup> - <col - style="width: 100px;" - /> - <col - style="width: 100px;" - /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col /> - <col - style="width: 100px;" - /> - </colgroup> - <tbody - class="rc-table-tbody" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-placeholder" - > - <td - class="rc-table-cell" - colspan="12" - > - <div - class="rc-table-expanded-row-fixed" - style="width: 985px; position: sticky; left: 0px; overflow: hidden;" - > - No Data - </div> - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; diff --git a/tests/__snapshots__/FixedColumn.spec.jsx.snap b/tests/__snapshots__/FixedColumn.spec.jsx.snap new file mode 100644 index 000000000..249dfc2ef --- /dev/null +++ b/tests/__snapshots__/FixedColumn.spec.jsx.snap @@ -0,0 +1,3145 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Table.FixedColumn > fixed column renders correctly RTL 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-rtl rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 1px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col + style="width: 100px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell rc-table-cell-fix-right" + scope="col" + style="position: sticky; right: 0px;" + > + title1 + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + scope="col" + style="position: sticky; right: 0px;" + title="title2" + > + title2 + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + <th + class="rc-table-cell" + scope="col" + > + title4 + </th> + <th + class="rc-table-cell" + scope="col" + > + title5 + </th> + <th + class="rc-table-cell" + scope="col" + > + title6 + </th> + <th + class="rc-table-cell" + scope="col" + > + title7 + </th> + <th + class="rc-table-cell" + scope="col" + > + title8 + </th> + <th + class="rc-table-cell" + scope="col" + > + title9 + </th> + <th + class="rc-table-cell" + scope="col" + > + title10 + </th> + <th + class="rc-table-cell" + scope="col" + > + title11 + </th> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + scope="col" + style="position: sticky; left: 0px;" + > + title12 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 123 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + > + xxxxxxxx + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + cdd + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + > + edd12221 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="3" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="4" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="5" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="6" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="7" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="8" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="9" + > + <td + class="rc-table-cell rc-table-cell-fix-right" + style="position: sticky; right: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-last rc-table-cell-ellipsis" + style="position: sticky; right: 0px;" + title="1111" + > + <span> + 1111 + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-first" + style="position: sticky; left: 0px;" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.FixedColumn > renders correctly > all column has width should use it 1`] = ` +LoadedCheerio { + "0": <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + </colgroup>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.FixedColumn > renders correctly > scrollX - with data 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 1200px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col + style="width: 100px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell rc-table-cell-fix-left" + scope="col" + style="position: sticky; left: 0px;" + > + title1 + </th> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + scope="col" + style="position: sticky; left: 93px;" + title="title2" + > + <span + class="rc-table-cell-content" + > + title2 + </span> + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + <th + class="rc-table-cell" + scope="col" + > + title4 + </th> + <th + class="rc-table-cell" + scope="col" + > + title5 + </th> + <th + class="rc-table-cell" + scope="col" + > + title6 + </th> + <th + class="rc-table-cell" + scope="col" + > + title7 + </th> + <th + class="rc-table-cell" + scope="col" + > + title8 + </th> + <th + class="rc-table-cell" + scope="col" + > + title9 + </th> + <th + class="rc-table-cell" + scope="col" + > + title10 + </th> + <th + class="rc-table-cell" + scope="col" + > + title11 + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + scope="col" + style="position: sticky; right: 0px;" + > + title12 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 123 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + xxxxxxxx + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + cdd + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + edd12221 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="3" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="4" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="5" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="6" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="7" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="8" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="9" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.FixedColumn > renders correctly > scrollX - without data 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + style="overflow-x: auto; overflow-y: hidden;" + > + <table + style="width: 1200px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col + style="width: 100px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell rc-table-cell-fix-left" + scope="col" + style="position: sticky; left: 0px;" + > + title1 + </th> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + scope="col" + style="position: sticky; left: 93px;" + title="title2" + > + <span + class="rc-table-cell-content" + > + title2 + </span> + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + <th + class="rc-table-cell" + scope="col" + > + title4 + </th> + <th + class="rc-table-cell" + scope="col" + > + title5 + </th> + <th + class="rc-table-cell" + scope="col" + > + title6 + </th> + <th + class="rc-table-cell" + scope="col" + > + title7 + </th> + <th + class="rc-table-cell" + scope="col" + > + title8 + </th> + <th + class="rc-table-cell" + scope="col" + > + title9 + </th> + <th + class="rc-table-cell" + scope="col" + > + title10 + </th> + <th + class="rc-table-cell" + scope="col" + > + title11 + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + scope="col" + style="position: sticky; right: 0px;" + > + title12 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-placeholder" + > + <td + class="rc-table-cell" + colspan="12" + > + <div + class="rc-table-expanded-row-fixed" + style="width: 1000px; position: sticky; left: 0px; overflow: hidden;" + > + No Data + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.FixedColumn > renders correctly > scrollXY - with data 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-header" + style="overflow: hidden;" + > + <table + style="table-layout: fixed;" + > + <colgroup> + <col + style="width: 93px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 15px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell rc-table-cell-fix-left" + scope="col" + style="position: sticky; left: 0px;" + > + title1 + </th> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + scope="col" + style="position: sticky; left: 93px;" + title="title2" + > + <span + class="rc-table-cell-content" + > + title2 + </span> + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + <th + class="rc-table-cell" + scope="col" + > + title4 + </th> + <th + class="rc-table-cell" + scope="col" + > + title5 + </th> + <th + class="rc-table-cell" + scope="col" + > + title6 + </th> + <th + class="rc-table-cell" + scope="col" + > + title7 + </th> + <th + class="rc-table-cell" + scope="col" + > + title8 + </th> + <th + class="rc-table-cell" + scope="col" + > + title9 + </th> + <th + class="rc-table-cell" + scope="col" + > + title10 + </th> + <th + class="rc-table-cell" + scope="col" + > + title11 + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + scope="col" + style="position: sticky; right: 15px;" + > + title12 + </th> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" + style="position: sticky; right: 0px;" + /> + </tr> + </thead> + </table> + </div> + <div + class="rc-table-body" + style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" + > + <table + style="width: 1200px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col + style="width: 100px;" + /> + </colgroup> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="1" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 123 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell" + > + xxxxxxxx + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + xxxxxxxx + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="2" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + cdd + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + > + edd12221 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="3" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="4" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="5" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="6" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="7" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="8" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="9" + > + <td + class="rc-table-cell rc-table-cell-fix-left" + style="position: sticky; left: 0px;" + > + 133 + </td> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + style="position: sticky; left: 93px;" + title="1111" + > + <span + class="rc-table-cell-content" + > + <span> + 1111 + </span> + </span> + </td> + <td + class="rc-table-cell" + > + edd12221 + </td> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + style="position: sticky; right: 0px;" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.FixedColumn > renders correctly > scrollXY - without data 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-header" + style="overflow: hidden;" + > + <table + style="table-layout: fixed;" + > + <colgroup> + <col + style="width: 93px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 1000px;" + /> + <col + style="width: 15px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell rc-table-cell-fix-left" + scope="col" + style="position: sticky; left: 0px;" + > + title1 + </th> + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last rc-table-cell-ellipsis" + scope="col" + style="position: sticky; left: 93px;" + title="title2" + > + <span + class="rc-table-cell-content" + > + title2 + </span> + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + <th + class="rc-table-cell" + scope="col" + > + title4 + </th> + <th + class="rc-table-cell" + scope="col" + > + title5 + </th> + <th + class="rc-table-cell" + scope="col" + > + title6 + </th> + <th + class="rc-table-cell" + scope="col" + > + title7 + </th> + <th + class="rc-table-cell" + scope="col" + > + title8 + </th> + <th + class="rc-table-cell" + scope="col" + > + title9 + </th> + <th + class="rc-table-cell" + scope="col" + > + title10 + </th> + <th + class="rc-table-cell" + scope="col" + > + title11 + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + scope="col" + style="position: sticky; right: 15px;" + > + title12 + </th> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" + style="position: sticky; right: 0px;" + /> + </tr> + </thead> + </table> + </div> + <div + class="rc-table-body" + style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" + > + <table + style="width: 1200px; min-width: 100%; table-layout: fixed;" + > + <colgroup> + <col + style="width: 100px;" + /> + <col + style="width: 100px;" + /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col /> + <col + style="width: 100px;" + /> + </colgroup> + <tbody + class="rc-table-tbody" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-placeholder" + > + <td + class="rc-table-cell" + colspan="12" + > + <div + class="rc-table-expanded-row-fixed" + style="width: 985px; position: sticky; left: 0px; overflow: hidden;" + > + No Data + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; diff --git a/tests/__snapshots__/Summary.spec.tsx.snap b/tests/__snapshots__/Summary.spec.tsx.snap index e72a20741..40aec2575 100644 --- a/tests/__snapshots__/Summary.spec.tsx.snap +++ b/tests/__snapshots__/Summary.spec.tsx.snap @@ -1,28 +1,58 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Table.Summary support data type 1`] = ` -<tfoot - class="rc-table-summary" -> - <tr> - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - colspan="2" - style="position: sticky; left: 0px;" - > - Light - </td> - <td - class="rc-table-cell" - > - Bamboo - </td> - <td - class="rc-table-cell" - style="text-align: right;" - > - 112.5 - </td> - </tr> -</tfoot> +exports[`Table.Summary > support data type 1`] = ` +LoadedCheerio { + "0": <tfoot + class="rc-table-summary" + > + <tr> + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + colspan="2" + style="position: sticky; left: 0px;" + > + Light + </td> + <td + class="rc-table-cell" + > + Bamboo + </td> + <td + class="rc-table-cell" + style="text-align: right;" + > + 112.5 + </td> + </tr> + </tfoot>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} `; diff --git a/tests/__snapshots__/Table.spec.js.snap b/tests/__snapshots__/Table.spec.js.snap deleted file mode 100644 index 4df87d27e..000000000 --- a/tests/__snapshots__/Table.spec.js.snap +++ /dev/null @@ -1,847 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Table.Basic custom components renders correctly 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - name="my-table" - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - name="my-header-wrapper" - > - <tr - name="my-header-row" - > - <th - class="rc-table-cell" - name="my-header-cell" - scope="col" - > - Name - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - name="my-body-wrapper" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - name="my-body-row" - > - <td - class="rc-table-cell" - name="my-body-cell" - > - Lucy - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - name="my-body-row" - > - <td - class="rc-table-cell" - name="my-body-cell" - > - Jack - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic custom components renders fixed column and header correctly 1`] = ` -<div - class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" -> - <div - class="rc-table-container" - > - <div - class="rc-table-header" - style="overflow: hidden;" - > - <table - style="table-layout: fixed; visibility: hidden;" - > - <colgroup /> - <thead - class="rc-table-thead" - name="my-header-wrapper" - > - <tr - name="my-header-row" - > - <th - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - name="my-header-cell" - scope="col" - style="position: sticky; left: 0px;" - > - Name - </th> - <th - class="rc-table-cell" - name="my-header-cell" - scope="col" - > - Age - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - name="my-header-cell" - scope="col" - style="position: sticky; right: 15px;" - > - Gender - </th> - <th - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" - name="my-header-cell" - style="position: sticky; right: 0px;" - /> - </tr> - </thead> - </table> - </div> - <div - class="rc-table-body" - style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" - > - <table - name="my-table" - style="width: 100px; min-width: 100%; table-layout: fixed;" - > - <colgroup /> - <tbody - class="rc-table-tbody" - name="my-body-wrapper" - > - <tr - aria-hidden="true" - class="rc-table-measure-row" - style="height: 0px; font-size: 0px;" - > - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - <td - style="padding: 0px; border: 0px; height: 0px;" - > - <div - style="height: 0px; overflow: hidden;" - > - - </div> - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="0" - name="my-body-row" - > - <td - class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" - name="my-body-cell" - style="position: sticky; left: 0px;" - > - Lucy - </td> - <td - class="rc-table-cell" - name="my-body-cell" - > - 27 - </td> - <td - class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" - name="my-body-cell" - style="position: sticky; right: 0px;" - > - F - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic custom components scroll content with scroll 1`] = ` -<div - class="rc-table rc-table-fixed-header rc-table-scroll-horizontal" -> - <div - class="rc-table-container" - > - <div - class="rc-table-header" - style="overflow: hidden;" - > - <table - style="table-layout: fixed;" - > - <colgroup> - <col - style="width: 0px;" - /> - <col - style="width: 888px;" - /> - <col - style="width: 15px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell rc-table-cell-scrollbar" - /> - </tr> - </thead> - </table> - </div> - <h1> - Bamboo - </h1> - </div> -</div> -`; - -exports[`Table.Basic internal api transformColumns basic 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - before - </th> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <th - class="rc-table-cell" - scope="col" - > - after - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - /> - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders colSpan correctly 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - colspan="2" - scope="colgroup" - > - Name - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - colspan="2" - > - John - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - > - Terry - </td> - <td - class="rc-table-cell" - > - Garner - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders correctly RTL 1`] = ` -<div - class="test-prefix test-class-name test-prefix-rtl" -> - <div - class="test-prefix-container" - > - <div - class="test-prefix-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="test-prefix-thead" - > - <tr> - <th - class="test-prefix-cell" - scope="col" - > - Name - </th> - </tr> - </thead> - <tbody - class="test-prefix-tbody" - > - <tr - class="test-prefix-row test-prefix-row-level-0" - data-row-key="key0" - > - <td - class="test-prefix-cell" - > - Lucy - </td> - </tr> - <tr - class="test-prefix-row test-prefix-row-level-0" - data-row-key="key1" - > - <td - class="test-prefix-cell" - > - Jack - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders correctly basic 1`] = ` -<div - class="test-prefix test-class-name" -> - <div - class="test-prefix-container" - > - <div - class="test-prefix-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="test-prefix-thead" - > - <tr> - <th - class="test-prefix-cell" - scope="col" - > - Name - </th> - </tr> - </thead> - <tbody - class="test-prefix-tbody" - > - <tr - class="test-prefix-row test-prefix-row-level-0" - data-row-key="key0" - > - <td - class="test-prefix-cell" - > - Lucy - </td> - </tr> - <tr - class="test-prefix-row test-prefix-row-level-0" - data-row-key="key1" - > - <td - class="test-prefix-cell" - > - Jack - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders correctly column children undefined 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - 姓名 - </th> - <th - class="rc-table-cell" - scope="col" - > - 年龄 - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders correctly falsy columns 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - 姓名 - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - > - Lucy - </td> - <td - class="rc-table-cell" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - > - Jack - </td> - <td - class="rc-table-cell" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders correctly no columns 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <td - class="rc-table-cell" - /> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - /> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - /> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic renders rowSpan correctly 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - First Name - </th> - <th - class="rc-table-cell" - scope="col" - > - Last Name - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key0" - > - <td - class="rc-table-cell" - > - John - </td> - <td - class="rc-table-cell" - rowspan="2" - > - Doe - </td> - </tr> - <tr - class="rc-table-row rc-table-row-level-0" - data-row-key="key1" - > - <td - class="rc-table-cell" - > - Terry - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic should get scrollbar size 1`] = ` -<div - class="rc-table rc-table-fixed-header" -> - <div - class="rc-table-container" - > - <div - class="rc-table-header" - style="overflow: hidden;" - > - <table - style="table-layout: fixed;" - > - <colgroup> - <col - style="width: 85px;" - /> - <col - style="width: 15px;" - /> - </colgroup> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - <td - class="rc-table-cell rc-table-cell-scrollbar" - /> - </tr> - </thead> - </table> - </div> - </div> -</div> -`; - -exports[`Table.Basic syntactic sugar 1`] = ` -<div - class="rc-table" -> - <div - class="rc-table-container" - > - <div - class="rc-table-content" - > - <table - style="table-layout: auto;" - > - <colgroup /> - <thead - class="rc-table-thead" - > - <tr> - <th - class="rc-table-cell" - scope="col" - > - total - </th> - </tr> - <tr> - <th - class="rc-table-cell" - scope="col" - > - Name - </th> - </tr> - </thead> - <tbody - class="rc-table-tbody" - > - <tr - class="rc-table-placeholder" - > - <td - class="rc-table-cell" - > - No Data - </td> - </tr> - </tbody> - </table> - </div> - </div> -</div> -`; diff --git a/tests/__snapshots__/Table.spec.jsx.snap b/tests/__snapshots__/Table.spec.jsx.snap new file mode 100644 index 000000000..3dc5283f0 --- /dev/null +++ b/tests/__snapshots__/Table.spec.jsx.snap @@ -0,0 +1,1336 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Table.Basic > columns support JSX condition 1`] = ` +LoadedCheerio { + "0": <button> + Click 2 times + </button>, + "1": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + title + </th> + <th + class="rc-table-cell" + scope="col" + > + title3 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + > + 2 + </td> + <td + class="rc-table-cell" + > + 3 + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + > + 2 + </td> + <td + class="rc-table-cell" + > + 3 + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 2, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > custom components > renders correctly 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + name="my-table" + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + name="my-header-wrapper" + > + <tr + name="my-header-row" + > + <th + class="rc-table-cell" + name="my-header-cell" + scope="col" + > + Name + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + name="my-body-wrapper" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + name="my-body-row" + > + <td + class="rc-table-cell" + name="my-body-cell" + > + Lucy + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + name="my-body-row" + > + <td + class="rc-table-cell" + name="my-body-cell" + > + Jack + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > custom components > renders fixed column and header correctly 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-header rc-table-fixed-column rc-table-scroll-horizontal rc-table-has-fix-left rc-table-has-fix-right" + > + <div + class="rc-table-container" + > + <div + class="rc-table-header" + style="overflow: hidden;" + > + <table + style="table-layout: fixed; visibility: hidden;" + > + <colgroup /> + <thead + class="rc-table-thead" + name="my-header-wrapper" + > + <tr + name="my-header-row" + > + <th + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + name="my-header-cell" + scope="col" + style="position: sticky; left: 0px;" + > + Name + </th> + <th + class="rc-table-cell" + name="my-header-cell" + scope="col" + > + Age + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + name="my-header-cell" + scope="col" + style="position: sticky; right: 15px;" + > + Gender + </th> + <th + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-scrollbar" + name="my-header-cell" + style="position: sticky; right: 0px;" + /> + </tr> + </thead> + </table> + </div> + <div + class="rc-table-body" + style="overflow-x: auto; overflow-y: scroll; max-height: 100px;" + > + <table + name="my-table" + style="width: 100px; min-width: 100%; table-layout: fixed;" + > + <colgroup /> + <tbody + class="rc-table-tbody" + name="my-body-wrapper" + > + <tr + aria-hidden="true" + class="rc-table-measure-row" + style="height: 0px; font-size: 0px;" + > + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + <td + style="padding: 0px; border: 0px; height: 0px;" + > + <div + style="height: 0px; overflow: hidden;" + > + + </div> + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="0" + name="my-body-row" + > + <td + class="rc-table-cell rc-table-cell-fix-left rc-table-cell-fix-left-last" + name="my-body-cell" + style="position: sticky; left: 0px;" + > + Lucy + </td> + <td + class="rc-table-cell" + name="my-body-cell" + > + 27 + </td> + <td + class="rc-table-cell rc-table-cell-fix-right rc-table-cell-fix-right-first" + name="my-body-cell" + style="position: sticky; right: 0px;" + > + F + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > custom components > scroll content > with scroll 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-header rc-table-scroll-horizontal" + > + <div + class="rc-table-container" + > + <div + class="rc-table-header" + style="overflow: hidden;" + > + <table + style="table-layout: fixed;" + > + <colgroup> + <col + style="width: 0px;" + /> + <col + style="width: 888px;" + /> + <col + style="width: 15px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell rc-table-cell-scrollbar" + /> + </tr> + </thead> + </table> + </div> + <h1> + Bamboo + </h1> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > internal api > transformColumns > basic 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + before + </th> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <th + class="rc-table-cell" + scope="col" + > + after + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + /> + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders colSpan correctly 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + colspan="2" + scope="colgroup" + > + Name + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + colspan="2" + > + John + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + > + Terry + </td> + <td + class="rc-table-cell" + > + Garner + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders correctly > RTL 1`] = ` +LoadedCheerio { + "0": <div + class="test-prefix test-class-name test-prefix-rtl" + > + <div + class="test-prefix-container" + > + <div + class="test-prefix-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="test-prefix-thead" + > + <tr> + <th + class="test-prefix-cell" + scope="col" + > + Name + </th> + </tr> + </thead> + <tbody + class="test-prefix-tbody" + > + <tr + class="test-prefix-row test-prefix-row-level-0" + data-row-key="key0" + > + <td + class="test-prefix-cell" + > + Lucy + </td> + </tr> + <tr + class="test-prefix-row test-prefix-row-level-0" + data-row-key="key1" + > + <td + class="test-prefix-cell" + > + Jack + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders correctly > basic 1`] = ` +LoadedCheerio { + "0": <div + class="test-prefix test-class-name" + > + <div + class="test-prefix-container" + > + <div + class="test-prefix-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="test-prefix-thead" + > + <tr> + <th + class="test-prefix-cell" + scope="col" + > + Name + </th> + </tr> + </thead> + <tbody + class="test-prefix-tbody" + > + <tr + class="test-prefix-row test-prefix-row-level-0" + data-row-key="key0" + > + <td + class="test-prefix-cell" + > + Lucy + </td> + </tr> + <tr + class="test-prefix-row test-prefix-row-level-0" + data-row-key="key1" + > + <td + class="test-prefix-cell" + > + Jack + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders correctly > column children undefined 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + 姓名 + </th> + <th + class="rc-table-cell" + scope="col" + > + 年龄 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + > + Lucy + </td> + <td + class="rc-table-cell" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + > + Jack + </td> + <td + class="rc-table-cell" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders correctly > falsy columns 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + 姓名 + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + > + Lucy + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + > + Jack + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders correctly > no columns 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <td + class="rc-table-cell" + /> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + /> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + /> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > renders rowSpan correctly 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + First Name + </th> + <th + class="rc-table-cell" + scope="col" + > + Last Name + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key0" + > + <td + class="rc-table-cell" + > + John + </td> + <td + class="rc-table-cell" + rowspan="2" + > + Doe + </td> + </tr> + <tr + class="rc-table-row rc-table-row-level-0" + data-row-key="key1" + > + <td + class="rc-table-cell" + > + Terry + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > should get scrollbar size 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table rc-table-fixed-header" + > + <div + class="rc-table-container" + > + <div + class="rc-table-header" + style="overflow: hidden;" + > + <table + style="table-layout: fixed;" + > + <colgroup> + <col + style="width: 85px;" + /> + <col + style="width: 15px;" + /> + </colgroup> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + <td + class="rc-table-cell rc-table-cell-scrollbar" + /> + </tr> + </thead> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; + +exports[`Table.Basic > syntactic sugar 1`] = ` +LoadedCheerio { + "0": <div + class="rc-table" + > + <div + class="rc-table-container" + > + <div + class="rc-table-content" + > + <table + style="table-layout: auto;" + > + <colgroup /> + <thead + class="rc-table-thead" + > + <tr> + <th + class="rc-table-cell" + scope="col" + > + total + </th> + </tr> + <tr> + <th + class="rc-table-cell" + scope="col" + > + Name + </th> + </tr> + </thead> + <tbody + class="rc-table-tbody" + > + <tr + class="rc-table-placeholder" + > + <td + class="rc-table-cell" + > + No Data + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div>, + "_root": LoadedCheerio { + "0": Document { + "children": [ + <html> + <head /> + <body /> + </html>, + ], + "endIndex": null, + "next": null, + "parent": null, + "prev": null, + "startIndex": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, + }, + "length": 1, + "options": { + "decodeEntities": true, + "xml": false, + }, +} +`; diff --git a/tests/refs.spec.tsx b/tests/refs.spec.tsx new file mode 100644 index 000000000..f291741e5 --- /dev/null +++ b/tests/refs.spec.tsx @@ -0,0 +1,65 @@ +import { render } from '@testing-library/react'; +import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import React from 'react'; +import Table, { type Reference } from '../src'; + +describe('Table.Ref', () => { + let scrollParam: any = null; + let scrollIntoViewElement: HTMLElement = null; + + beforeAll(() => { + spyElementPrototypes(HTMLElement, { + scrollTo: (_: any, param: any) => { + scrollParam = param; + }, + scrollIntoView() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + scrollIntoViewElement = this; + }, + }); + }); + + beforeEach(() => { + scrollParam = null; + }); + + it('support reference', () => { + const ref = React.createRef<Reference>(); + + const { container } = render( + <Table + data={[{ key: 'light' }, { key: 'bamboo' }]} + columns={[ + { + dataIndex: 'key', + }, + ]} + ref={ref} + scroll={{ + y: 10, + }} + />, + ); + + expect(ref.current.nativeElement).toBe(container.querySelector('.rc-table')); + + // Scroll To number + ref.current.scrollTo({ + top: 903, + }); + + expect(scrollParam.top).toEqual(903); + + // Scroll index + ref.current.scrollTo({ + index: 0, + }); + expect(scrollIntoViewElement.textContent).toEqual('light'); + + // Scroll key + ref.current.scrollTo({ + key: 'bamboo', + }); + expect(scrollIntoViewElement.textContent).toEqual('bamboo'); + }); +}); diff --git a/tests/setup.js b/tests/setup.js deleted file mode 100644 index 154da504f..000000000 --- a/tests/setup.js +++ /dev/null @@ -1,7 +0,0 @@ -global.requestAnimationFrame = cb => setTimeout(cb, 0); -require('regenerator-runtime'); - -const Enzyme = require('enzyme'); -const Adapter = require('enzyme-adapter-react-16'); - -Enzyme.configure({ adapter: new Adapter() }); diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 000000000..8597c2d9b --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,23 @@ +import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; +import matchers from '@testing-library/jest-dom/matchers'; +import { expect } from 'vitest'; + +declare module 'vitest' { + interface Assertion<T = any> extends jest.Matchers<void, T>, TestingLibraryMatchers<T, void> {} +} + +expect.extend(matchers); + +// https://github.com/nickcolley/jest-axe/issues/147#issuecomment-758804533 +const { getComputedStyle } = window; +window.getComputedStyle = elt => getComputedStyle(elt); + +global.requestAnimationFrame = cb => setTimeout(cb, 0); +require('regenerator-runtime'); + +vi.mock('rc-util/lib/getScrollBarSize'); + +const Enzyme = require('enzyme'); +const Adapter = require('enzyme-adapter-react-16'); + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/tests/utils.js b/tests/utils.js index 8b6660ee0..ca13e158d 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -3,7 +3,7 @@ import { act } from 'react-dom/test-utils'; export function safeAct(wrapper, cb) { return act(async () => { cb && cb(); - jest.runAllTimers(); + vi.runAllTimers(); await Promise.resolve(); wrapper.update(); }); diff --git a/tsconfig.json b/tsconfig.json index 32b01dddc..613a69611 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,8 @@ "@/*": ["src/*"], "@@/*": [".dumi/tmp/*"], "rc-table": ["src/index.ts"] - } + }, + "types": ["vitest/globals"] }, - "include": [".dumi/**/*", ".dumirc.ts", "**/*.ts", "**/*.tsx"] + "include": [".dumirc.ts", "**/*.ts", "**/*.tsx"] } diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..a61325b92 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + esbuild: { + jsx: 'automatic', + }, + test: { + include: ['**/tests/*.spec.*'], + globals: true, + setupFiles: './tests/setup.ts', + environment: 'jsdom', + }, +});