Skip to content

Commit

Permalink
Merge pull request #556 from icflorescu/next
Browse files Browse the repository at this point in the history
Improve/fix scroll to row examples
  • Loading branch information
icflorescu authored Mar 5, 2024
2 parents f88f4b0 + 8095d9e commit 649e2a3
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 84 deletions.

This file was deleted.

126 changes: 126 additions & 0 deletions app/examples/scrolling-a-row-into-view/ScrollRowIntoViewExamples.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
'use client';

import { Button, Grid, GridCol } from '@mantine/core';
import { DataTable } from '__PACKAGE__';
import { useRef } from 'react';
import { employees } from '~/data';

export function ScrollIntoViewExample() {
// example-start scroll-into-view
const scrollRowIntoView = (selector: string) => {
document.querySelector(selector)?.scrollIntoView(false);
};

return (
<>
<Grid mb="md">
<GridCol span={{ md: 4, lg: 3 }}>
<Button fullWidth onClick={() => scrollRowIntoView('[data-row-index="0"]')}>
Scroll to first row
</Button>
</GridCol>
<GridCol span={{ md: 4, lg: 6 }}>
<Button fullWidth onClick={() => scrollRowIntoView('[data-row-first-name="Alicia"]')}>
Scroll to first “Alicia”
</Button>
</GridCol>
<GridCol span={{ md: 4, lg: 3 }}>
<Button fullWidth onClick={() => scrollRowIntoView(`[data-row-index="${employees.length - 1}"]`)}>
Scroll to last row
</Button>
</GridCol>
</Grid>
<DataTable
records={employees}
customRowAttributes={({ firstName }, recordIndex) => ({
'data-row-first-name': firstName,
'data-row-index': recordIndex,
})}
// example-skip more table props
height={500}
withTableBorder
withColumnBorders
striped
columns={[
{ accessor: 'firstName' },
{ accessor: 'lastName' },
{ accessor: 'email' },
{ accessor: 'department.name', title: 'Department' },
{ accessor: 'department.company.name', title: 'Company', noWrap: true },
{ accessor: 'department.company.streetAddress', title: 'Address', noWrap: true },
{ accessor: 'department.company.city', title: 'City' },
{ accessor: 'department.company.state', title: 'State', textAlign: 'right' },
]}
rowColor={({ firstName }, index) =>
index === 0 || index === employees.length - 1 || firstName === 'Alicia' ? 'red' : undefined
}
// example-resume
/>
</>
);
// example-end
}

export function ScrollToExample() {
const viewportRef = useRef<HTMLDivElement>(null);

// example-start scroll-to

const scrollToRow = (selector: string) => {
const el = document.querySelector<HTMLElement>(selector)!;
viewportRef.current?.scrollTo({
top: el.offsetTop - el.clientHeight - 1,
behavior: 'smooth',
});
};

return (
<>
<Grid mb="md">
<GridCol span={{ md: 4, lg: 3 }}>
<Button fullWidth onClick={() => scrollToRow('[data-row-index="0"]')}>
Scroll to first row
</Button>
</GridCol>
<GridCol span={{ md: 4, lg: 6 }}>
<Button fullWidth onClick={() => scrollToRow('[data-row-first-name="Alicia"]')}>
Scroll to first “Alicia”
</Button>
</GridCol>
<GridCol span={{ md: 4, lg: 3 }}>
<Button fullWidth onClick={() => scrollToRow(`[data-row-index="${employees.length - 1}"]`)}>
Scroll to last row
</Button>
</GridCol>
</Grid>
<DataTable
scrollViewportRef={viewportRef}
records={employees}
customRowAttributes={({ firstName }, recordIndex) => ({
'data-row-first-name': firstName,
'data-row-index': recordIndex,
})}
// example-skip more table props
height={500}
withTableBorder
withColumnBorders
striped
columns={[
{ accessor: 'firstName' },
{ accessor: 'lastName' },
{ accessor: 'email' },
{ accessor: 'department.name', title: 'Department' },
{ accessor: 'department.company.name', title: 'Company', noWrap: true },
{ accessor: 'department.company.streetAddress', title: 'Address', noWrap: true },
{ accessor: 'department.company.city', title: 'City' },
{ accessor: 'department.company.state', title: 'State', textAlign: 'right' },
]}
rowColor={({ firstName }, index) =>
index === 0 || index === employees.length - 1 || firstName === 'Alicia' ? 'red' : undefined
}
// example-resume
/>
</>
);
// example-end
}
47 changes: 32 additions & 15 deletions app/examples/scrolling-a-row-into-view/page.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
import { Code, Text } from '@mantine/core';
import type { Route } from 'next';
import { PRODUCT_NAME } from '~/app/config';
import { CodeBlock } from '~/components/CodeBlock';
import { ExternalLink } from '~/components/ExternalLink';
import { InternalLink } from '~/components/InternalLink';
import { PageNavigation } from '~/components/PageNavigation';
import { PageSubtitle } from '~/components/PageSubtitle';
import { PageTitle } from '~/components/PageTitle';
import { Txt } from '~/components/Txt';
import { readCodeFile } from '~/lib/code';
import { getRouteMetadata } from '~/lib/utils';
import { ScrollRowIntoViewExample } from './ScrollRowIntoViewExample';
import { ScrollIntoViewExample, ScrollToExample } from './ScrollRowIntoViewExamples';

const PATH: Route = '/examples/scrolling-a-row-into-view';

export const metadata = getRouteMetadata(PATH);

export default async function ScrollableVsAutoHeightExamplePage() {
const code = await readCodeFile<string>(`${PATH}/ScrollRowIntoViewExample.tsx`);
export default async function ScrollIntoViewExamplesPage() {
const code = await readCodeFile<Record<'scroll-into-view' | 'scroll-to', string>>(
`${PATH}/ScrollRowIntoViewExamples.tsx`
);

return (
<>
<PageTitle of={PATH} />
<Txt>
One possible way to scroll a specific row into view is to use the{' '}
There are two possible approaches you could use to scroll a specific row into view in a {PRODUCT_NAME}. Both of
them rely on adding <Code>data-*</Code>{' '}
<InternalLink to="/examples/custom-row-or-cell-attributes">
<Code>customRowAttributes</Code> property
<Code>customRowAttributes</Code>
</InternalLink>{' '}
to add a custom <Code>data-*</Code> attribute to the row, and then use{' '}
<ExternalLink to="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">
<Code>document.querySelector</Code>
</ExternalLink>{' '}
to find the row and call{' '}
to the row, and then using DOM methods to find and scroll the row into view.
</Txt>
<PageSubtitle value="Using scrollIntoView" />
<Txt>
The simplest possible way is to use the{' '}
<ExternalLink to="https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView">
<Code>scrollIntoView</Code>
</ExternalLink>{' '}
on it.
method on the row element itself. Here is an example of how you could use it:
</Txt>
<ScrollRowIntoViewExample />
<ScrollIntoViewExample />
<Txt idea title="Keep in mind">
<Text inherit mb="xs">
Due to the fact that the <Code>DataTable</Code> header is fixed, using <Code>scrollIntoView()</Code> with no
arguments, or the equivalent{' '}
This method is simple and works well in most cases, but it has a limitation when the table is part of a more
complex layout - it will scroll the entire page to the top when bringing the row into view.
</Text>
<Text inherit mb="xs">
Also, due to the fact that the <Code>DataTable</Code> header is fixed, using <Code>scrollIntoView()</Code>{' '}
with no arguments, or the equivalent{' '}
<Code style={{ whiteSpace: 'nowrap' }}>{"scrollIntoView({ block: 'start' })"}</Code>, will not work as
expected.
</Text>
Expand All @@ -49,7 +58,15 @@ export default async function ScrollableVsAutoHeightExamplePage() {
</Text>
</Txt>
<Txt>Here is the code:</Txt>
<CodeBlock code={code} />
<CodeBlock code={code['scroll-into-view']} />
<PageSubtitle value="Using table viewport scrollTo" />
<Txt>
If the DataTable resides in a page with a more complex layout and you want to avoid scrolling the entire page
when bringing a row into view, you can use the <Code>scrollTo</Code> method of the table viewport element:
</Txt>
<ScrollToExample />
<Txt>Here is the code:</Txt>
<CodeBlock code={code['scroll-to']} />
<Txt>Head over to the next example to discover more features.</Txt>
<PageNavigation of={PATH} />
</>
Expand Down

0 comments on commit 649e2a3

Please sign in to comment.