Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table row link preloading and accessibility #2596

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/heavy-radios-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@evidence-dev/core-components': patch
---

Table rows with links preload data on hover
Table rows with links have a chevron icon on the right side
Table rows dont have link styling if the link value is falsey
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@
import ButtonGroup from '../../../atoms/inputs/button-group/ButtonGroup.svelte';
import ButtonGroupItem from '../../../atoms/inputs/button-group/ButtonGroupItem.svelte';
import { getInputContext } from '@evidence-dev/sdk/utils/svelte';
import { expect, userEvent, within } from '@storybook/test';
import { expect, userEvent, within, fn } from '@storybook/test';

const mockGoto = fn();

/** @type {import("@storybook/svelte").Meta}*/
export const meta = {
title: 'Viz/Datatable',
component: DataTable
component: DataTable,
parameters: {
sveltekit_experimental: {
navigation: {
goto: mockGoto
}
}
}
};
</script>

Expand Down Expand Up @@ -118,3 +127,55 @@
<h2>Bottom of page</h2>
</div>
</Story>

<Story
name="Row links"
play={async ({ canvasElement }) => {
const canvas = within(canvasElement);

// This matches the devtools too, so we have to use index 1
const internals = await canvas.findAllByText('Internal', { exact: true });
const internal = internals[1];
await userEvent.click(internal);
expect(mockGoto).toHaveBeenCalledTimes(1);
expect(mockGoto).toHaveBeenCalledWith('?bingbong=true');

// TODO testing the external link is tricky because it navigates away from the storybook
}}
>
{@const data = Query.create(
`
SELECT 'Internal' as type, '?bingbong=true' as link UNION ALL
SELECT 'External' as type, 'https://example.com' as link UNION ALL
SELECT 'No link' as type, null as link
`,
query
)}
<DataTable {data} link="link" />
</Story>

<Story
name="Row links with showLinkCol"
play={async ({ canvasElement }) => {
const canvas = within(canvasElement);

// This matches the devtools too, so we have to use index 1
const internals = await canvas.findAllByText('Internal', { exact: true });
const internal = internals[1];
await userEvent.click(internal);
expect(mockGoto).toHaveBeenCalledTimes(1);
expect(mockGoto).toHaveBeenCalledWith('?bingbong=true');

// TODO testing the external link is tricky because it navigates away from the storybook
}}
>
{@const data = Query.create(
`
SELECT 'Internal' as type, '?bingbong=true' as link UNION ALL
SELECT 'External' as type, 'https://example.com' as link UNION ALL
SELECT 'No link' as type, null as link
`,
query
)}
<DataTable {data} link="link" showLinkCol />
</Story>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
export let sortBy = undefined;
export let wrapTitles = undefined;
export let compact = undefined;

/** @type {string | undefined} */
export let link = undefined;
</script>

<thead>
Expand Down Expand Up @@ -92,6 +95,13 @@
{/if}
</th>
{/each}

<!-- Extra column for Chevron icons -->
{#if link}
<th role="columnheader">
<span class="sr-only">Links</span>
</th>
{/if}
</tr>
</thead>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import { goto, preloadData } from '$app/navigation';
import { safeExtractColumn } from './datatable.js';
import Delta from '../core/Delta.svelte';
import {
Expand All @@ -8,6 +9,8 @@
import TableCell from './TableCell.svelte';
import chroma from 'chroma-js';
import { uiColours } from '@evidence-dev/component-utilities/colours';
import { Icon } from '@steeze-ui/svelte-icon';
import { ChevronRight } from '@steeze-ui/tabler-icons';

export let displayedData = undefined;
export let rowShading = undefined;
Expand All @@ -24,18 +27,38 @@
export let orderedColumns = undefined;
export let compact = undefined;

function handleRowClick(url) {
if (link) {
const isUrlExternal = (url) =>
new URL(url, window.location.origin).origin !== window.location.origin;

const preloadLink = async (row) => {
if (!link || !row[link]) return;
const url = row[link];

if (isUrlExternal(url)) return;

await preloadData(url);
};

const navigateToLink = async (row) => {
if (!link || !row[link]) return;
const url = row[link];

if (isUrlExternal(url)) {
window.location = url;
return;
}
}

await goto(row[link]);
};
</script>

{#each displayedData as row, i}
<tr
class:shaded-row={rowShading && i % 2 === 1}
class:row-link={link != undefined}
on:click={() => handleRowClick(row[link])}
class:row-link={link && row[link]}
on:mouseover={() => preloadLink(row)}
on:focus={() => preloadLink(row)}
on:click={() => navigateToLink(row)}
class:row-lines={rowLines}
>
{#if rowNumbers && groupType !== 'section'}
Expand Down Expand Up @@ -174,6 +197,13 @@
{/if}
</TableCell>
{/each}

{#if link && row[link]}
<TableCell {compact} width="16px">
<Icon src={ChevronRight} class="w-4 h-4" />
<a href={row[link]} class="sr-only">See more</a>
</TableCell>
{/if}
</tr>
{/each}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,11 @@
}

// Hide link column if columns have not been explicitly selected:
for (let i = 0; i < columnSummary.length; i++) {
columnSummary[i].show = showLinkCol === false && columnSummary[i].id === link ? false : true;
if (link) {
const linkColIndex = columnSummary.findIndex((d) => d.id === link);
if (linkColIndex !== -1 && !showLinkCol) {
columnSummary.splice(linkColIndex, 1);
}
}
} catch (e) {
error = e.message;
Expand Down Expand Up @@ -503,6 +506,7 @@
{formatColumnTitles}
{sortBy}
{wrapTitles}
{link}
/>

<QueryLoad data={filteredData}>
Expand Down
7 changes: 1 addition & 6 deletions sites/docs/pages/components/data-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -597,12 +597,7 @@ To apply styling to most HTML tags, you should add the `class=markdown` attribut
This example includes a column `country_url` which contains a country name as a search term in Google (e.g., `https://google.ca/search?q=canada`)

```svelte
<DataTable data={countries} search=true link=country_url>
<Column id=country />
<Column id=country_id align=center />
<Column id=category />
<Column id=value_usd />
</DataTable>
<DataTable data={countries} search=true link=country_url showLinkCol/>
```

Click on a row to navigate using the row link:
Expand Down