diff --git a/webview/package.json b/webview/package.json index 9b1d70dee1..730f63f751 100644 --- a/webview/package.json +++ b/webview/package.json @@ -30,6 +30,7 @@ "lodash.merge": "^4.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-intersection-observer": "^9.3.5", "react-redux": "^8.0.2", "react-table": "^7.8.0", "react-vega": "^7.4.4", diff --git a/webview/setup-tests.js b/webview/setup-tests.js index bfb10431fe..b539a4bcf4 100644 --- a/webview/setup-tests.js +++ b/webview/setup-tests.js @@ -15,4 +15,13 @@ const mutationObserverMock = jest.fn().mockImplementation(() => { }) global.MutationObserver = mutationObserverMock +const intersectionObserverMock = jest.fn().mockImplementation(() => { + return { + disconnect: jest.fn(), + observe: jest.fn(), + unobserve: jest.fn() + } +}) +global.IntersectionObserver = intersectionObserverMock + StyleUtils.getThemeValue = jest.fn().mockImplementation(() => '#ffffff') diff --git a/webview/src/experiments/components/table/Table.tsx b/webview/src/experiments/components/table/Table.tsx index 469c4c5122..a7dd62e479 100644 --- a/webview/src/experiments/components/table/Table.tsx +++ b/webview/src/experiments/components/table/Table.tsx @@ -194,6 +194,7 @@ export const Table: React.FC = ({ filteredCounts={filteredCounts} filters={filters} columns={columns} + root={tableRef.current} /> {rows.map(row => ( = ({ +export const TableHead = ({ instance: { headerGroups, setColumnOrder, state: { columnOrder }, allColumns }, + root, filteredCounts, filters, columns, sorts -}) => { +}: TableHeadProps) => { const orderedColumns = useColumnOrder(columns, columnOrder) const allHeaders: HeaderGroup[] = [] for (const headerGroup of headerGroups) { @@ -85,9 +89,17 @@ export const TableHead: React.FC = ({ type: MessageFromWebviewType.REORDER_COLUMNS }) } + const [ref, needsShadow] = useInView({ + root, + rootMargin: '-15px 0px 0px 0px', + threshold: 1 + }) return ( -
+
= ({ tableData }) => { +const Template: ComponentStory = ({ tableData }) => { return } @@ -116,3 +122,37 @@ WithNoSortsOrFilters.args = { sorts: [] } } + +export const Scrolled: ComponentStory = ({ tableData }) => { + return ( +
+ +
+ ) +} +Scrolled.play = async ({ canvasElement }) => { + await findByText(canvasElement, '90aea7f') + const rows = getAllByRole(canvasElement, 'row') + const lastRow = rows[rows.length - 1] + const lastRowCells = within(lastRow).getAllByRole('cell') + const lastCell = lastRowCells[lastRowCells.length - 1] + lastCell.scrollIntoView() +} +Scrolled.parameters = { + chromatic: { + viewports: [400] + }, + viewport: { + defaultViewport: 'scrollable', + viewports: { + scrollable: { + name: 'Scrollable', + styles: { + height: '400px', + width: '600px' + }, + type: 'desktop' + } + } + } +} diff --git a/yarn.lock b/yarn.lock index e47b8b7c07..e5d2a2333b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14300,6 +14300,11 @@ react-inspector@^5.1.0: is-dom "^1.0.0" prop-types "^15.0.0" +react-intersection-observer@^9.3.5: + version "9.3.5" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.3.5.tgz#df97584c1ef1549a47d4af6380db2fb4b76d7bba" + integrity sha512-TiJXVUapzAaIrZCAMBLjyWvwGYNGm0Xpkcwm3NY23b9PsJEBavul0hRFmrwc/LOmBUA/8TlkjCj7lCvjM0q1Hg== + react-is@17.0.2, react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"