Skip to content

Commit

Permalink
feat: add clickable and hoverable rows to table (#265)
Browse files Browse the repository at this point in the history
* feat: add clickable and hoverable rows to table

* fix: add keyboard a11y

* fix: add keyboard nav and conditionnaly add event listeners.

* chore: export formatters and fix typing

* fix: rework focus state to avoid double expand icon
  • Loading branch information
etienneburdet authored Dec 9, 2024
1 parent 5873f6e commit a94553e
Show file tree
Hide file tree
Showing 33 changed files with 561 additions and 205 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions packages/visualizations-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [0.27.1-beta.1](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-29)


### Bug Fixes

* make colors more easily customizable ([7f1591b](https://github.com/opendatasoft/ods-dataviz-sdk/commit/7f1591bb2770751e813dea4c82ac9c43be4306ee))
* rename rows, lint, simplify callbacks ([1a10a98](https://github.com/opendatasoft/ods-dataviz-sdk/commit/1a10a98297e93e44415ffb49d917d6ef92d3d7c1))





## [0.27.1-beta.0](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-27)

**Note:** Version bump only for package @opendatasoft/visualizations-react





# [0.27.0](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-06)


Expand Down
4 changes: 2 additions & 2 deletions packages/visualizations-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opendatasoft/visualizations-react",
"version": "0.27.0",
"version": "0.27.1-beta.1",
"license": "MIT",
"author": "opendatasoft",
"homepage": "https://github.com/opendatasoft/ods-dataviz-sdk",
Expand Down Expand Up @@ -53,7 +53,7 @@
"arrowParens": "avoid"
},
"dependencies": {
"@opendatasoft/visualizations": "0.27.0",
"@opendatasoft/visualizations": "0.27.1-beta.1",
"use-callback-ref": "^1.2.4"
},
"devDependencies": {
Expand Down
42 changes: 42 additions & 0 deletions packages/visualizations-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import {
PoiMap as _PoiMap,
Table as _Table,
WebGlMap as _WebGlMap,
BooleanFormat as _BooleanFormat,
DateFormat as _DateFormat,
GeoFormat as _GeoFormat,
LongTextFormat as _LongTextFormat,
ShortTextFormat as _ShortTextFormat,
URLFormat as _URLFormat,
NumberFormat as _NumberFormat,
} from '@opendatasoft/visualizations';
import type {
ChartProps,
Expand All @@ -20,6 +27,13 @@ import type {
PoiMapProps,
WebGlMapProps,
TableProps,
BooleanFormatProps,
DateFormatProps,
GeoFormatProps,
LongTextFormatProps,
ShortTextFormatProps,
URLFormatProps,
NumberFormatProps,
} from '@opendatasoft/visualizations';
import reactifySvelte from 'reactify';

Expand All @@ -44,3 +58,31 @@ export const ChoroplethSvg = reactifySvelte<ChoroplethGeoJsonProps>(
export const PoiMap = reactifySvelte<PoiMapProps>(_PoiMap, 'ods-visualizations-poi-map');
export const WebGlMap = reactifySvelte<WebGlMapProps>(_WebGlMap, 'ods-visualizations-webgl-map');
export const Table = reactifySvelte<TableProps>(_Table, 'ods-visualizations-table');
export const BooleanFormat = reactifySvelte<BooleanFormatProps>(
_BooleanFormat,
'ods-visualizations-format-boolean'
);
export const DateFormat = reactifySvelte<DateFormatProps>(
_DateFormat,
'ods-visualizations-format-date'
);
export const GeoFormat = reactifySvelte<GeoFormatProps>(
_GeoFormat,
'ods-visualizations-format-geo'
);
export const ShortTextFormat = reactifySvelte<ShortTextFormatProps>(
_ShortTextFormat,
'ods-visualizations-format-shorttext'
);
export const LongTextFormat = reactifySvelte<LongTextFormatProps>(
_LongTextFormat,
'ods-visualizations-format-longtext'
);
export const NumberFormat = reactifySvelte<NumberFormatProps>(
_NumberFormat,
'ods-visualizations-format-number'
);
export const URLFormat = reactifySvelte<URLFormatProps>(
_URLFormat,
'ods-visualizations-format-url'
);
30 changes: 29 additions & 1 deletion packages/visualizations-react/stories/Table/Table.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import type { TableData, Async } from '@opendatasoft/visualizations';

Expand Down Expand Up @@ -39,6 +39,28 @@ const ScrollTemplate: ComponentStory<typeof Table> = args => (
</div>
);

const RowHoverTemplate: ComponentStory<typeof Table> = args => {
const { options: argOptions, data: argData } = args;
const [hoveredRecord, setHovered] = useState<Record<string, unknown> | undefined | null>(null);
const [lastClicked, setLastClicked] = useState<Record<string, unknown> | undefined | null>(null);

const onMouseEnter = (record?: Record<string, unknown>) => {setHovered(record);};
const onMouseLeave = () => {setHovered(null);};
const onClick = (record?: Record<string, unknown>) => {setLastClicked(record);};

return (
<>
<h3>Hovered</h3>
<pre>{JSON.stringify(hoveredRecord)}</pre>
<h3>Clicked</h3>
<pre>{JSON.stringify(lastClicked)}</pre>
<div style={{ maxWidth: '800px' }} className='design-system'>
<Table data={argData} options={{...argOptions, rowProps: { onClick, onMouseEnter, onMouseLeave}}}/>
</div>;
</>
);
};

const optionsWithPagination = {
...options,
pagination: {
Expand Down Expand Up @@ -107,3 +129,9 @@ RtlDirection.args = {
data,
options: optionsWithPagination,
};

export const RowHoverAndClick = RowHoverTemplate.bind({});
RowHoverAndClick.args = {
data,
options,
};
4 changes: 4 additions & 0 deletions packages/visualizations-react/stories/Table/custom-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
color: blue;
}

.design-system .ods-dataviz--default td button:hover {
background-color: #cbd2db;
}

.design-system svg {
--selected: #142e7b;
--neutral: #cbd2db;
Expand Down
2 changes: 1 addition & 1 deletion packages/visualizations-react/stories/Table/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const columns: Column[] = [
key: 'url',
dataFormat: 'url',
options: {
display: value => value.startsWith('https://') ? 'link' : 'broken link',
display: (value: string) => value.startsWith('https://') ? 'link' : 'broken link',
},
},
{
Expand Down
30 changes: 30 additions & 0 deletions packages/visualizations/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [0.27.1-beta.1](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-29)


### Bug Fixes

* make colors more easily customizable ([7f1591b](https://github.com/opendatasoft/ods-dataviz-sdk/commit/7f1591bb2770751e813dea4c82ac9c43be4306ee))
* rename rows, lint, simplify callbacks ([1a10a98](https://github.com/opendatasoft/ods-dataviz-sdk/commit/1a10a98297e93e44415ffb49d917d6ef92d3d7c1))


### Reverts

* Revert "chore: add accessor functiond and make warnings optionals" ([547cb6f](https://github.com/opendatasoft/ods-dataviz-sdk/commit/547cb6f820457a959b2314aa568268284a94cca5))





## [0.27.1-beta.0](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-27)


### Bug Fixes

* add keyboard a11y ([e2ed58d](https://github.com/opendatasoft/ods-dataviz-sdk/commit/e2ed58d8c9a8acc5379cb3df7a8e281c96f1a2de))
* change implem to extra column to avoid formatting issues ([f2108e7](https://github.com/opendatasoft/ods-dataviz-sdk/commit/f2108e7801b34dc658ea975dcf177a35191386ac))
* import alias and export old types ([f7080ac](https://github.com/opendatasoft/ods-dataviz-sdk/commit/f7080acab8e15329cbda1899a4c88bedb46d0fac))





# [0.27.0](https://github.com/opendatasoft/ods-dataviz-sdk/compare/@opendatasoft/[email protected]...@opendatasoft/[email protected]) (2024-11-06)


Expand Down
2 changes: 1 addition & 1 deletion packages/visualizations/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opendatasoft/visualizations",
"version": "0.27.0",
"version": "0.27.1-beta.1",
"license": "MIT",
"author": "opendatasoft",
"homepage": "https://github.com/opendatasoft/ods-dataviz-sdk",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<script lang="ts">
import { warn } from './utils';
import type { BooleanFormatProps } from './types';
export let rawValue: unknown;
export let display = (v: boolean) => v.toString();
type $$Props = BooleanFormatProps;
export let rawValue: $$Props['rawValue'];
export let display: $$Props['display'] = (v: boolean) => v.toString();
$: format = (v: unknown) => {
if (typeof v !== 'boolean') {
warn(v, 'boolean');
}
// Currently we return the raw value until we have alternative renders
return display(v as boolean);
if (display) {
return display(v as boolean);
}
return v;
};
$: value = format(rawValue);
Expand Down
30 changes: 30 additions & 0 deletions packages/visualizations/src/components/Format/DateFormat.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
import { warn } from './utils';
import type { DateFormatProps } from './types';
type $$Props = DateFormatProps;
export let rawValue: $$Props['rawValue'];
export let display: $$Props['display'] = (v: string) => v;
export let intl: $$Props['intl'] = {};
export let locale = 'en-En';
$: format = (v: unknown) => {
if (
(typeof v === 'string' || typeof v === 'number') &&
!Number.isNaN(new Date(v).getTime())
) {
const intlValue = Intl.DateTimeFormat(locale, intl).format(new Date(v));
if (display) {
return display(intlValue);
}
return v;
}
warn(v, 'date');
return v;
};
$: value = format(rawValue);
</script>

{value}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@
import type { Content } from 'tippy.js';
import { WebGlMap } from 'components/Map';
import type { WebGlMapOptions, WebGlMapData } from 'components/Map';
import type { WebGlMapData } from 'components/Map';
import tippy from 'components/utils/tippy';
import type { GeoFormatProps } from './types';
export let rawValue: unknown;
export let display = (v: unknown) => v;
export let mapOptions: WebGlMapOptions;
export let sources: (v: unknown) => WebGlMapData['sources'] = () => ({});
export let layers: (v: unknown) => WebGlMapData['layers'] = () => [];
type $$Props = GeoFormatProps;
export let rawValue: $$Props['rawValue'];
export let display: $$Props['display'] = (v: unknown) => v;
export let mapOptions: $$Props['mapOptions'] = {};
export let sources: $$Props['sources'] = () => ({});
export let layers: $$Props['layers'] = () => [];
let tooltipContent: Content;
let showMap = false;
let data: WebGlMapData;
$: data = {
sources: sources(rawValue),
layers: layers(rawValue),
};
$: if (sources && layers) {
data = {
sources: sources(rawValue),
layers: layers(rawValue),
};
}
</script>

<div
Expand All @@ -38,9 +44,9 @@
}}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="label">{display(rawValue)}</div>
<div class="label">{display && display(rawValue)}</div>
<!-- To run a WebGl instance only when tooltip is visible -->
{#if showMap}
{#if showMap && data && mapOptions}
<div bind:this={tooltipContent} class="table-cell-map-container">
<WebGlMap options={mapOptions} {data} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { warn } from './utils';
import type { LongTextFormatProps } from './types';
type $$Props = LongTextFormatProps;
export let rawValue: $$Props['rawValue'];
export let display: $$Props['display'] = (v: string) => v;
$: format = (v: unknown) => {
if (typeof v !== 'string') {
warn(v, 'text');
}
if (display) {
return display(v as string);
}
return v;
};
$: value = format(rawValue);
</script>

<!-- Wrap value to style properly line clamp -->
<span>{value}</span>
27 changes: 27 additions & 0 deletions packages/visualizations/src/components/Format/NumberFormat.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts">
import { warn } from './utils';
import type { NumberFormatProps } from './types';
type $$Props = NumberFormatProps;
export let rawValue: $$Props['rawValue'];
export let display: $$Props['display'] = (v: string) => v;
export let intl: $$Props['intl'] = {};
export let locale = 'en-EN';
$: format = (v: unknown) => {
if (!Number.isFinite(v)) {
warn(v, 'number');
return v;
}
const intlValue = new Intl.NumberFormat(locale, intl).format(v as number);
if (display) {
return display(intlValue);
}
return intlValue;
};
$: value = format(rawValue);
</script>

{value}
Loading

1 comment on commit a94553e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage for this commit

94.71%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   index.ts100%100%100%100%
src/client
   constants.ts100%100%100%100%
   error.ts100%100%100%100%
   index.ts84.14%74.03%100%95.31%102–103, 124, 13, 146, 148, 148–149, 15, 15, 151, 162, 169, 169, 17, 17, 171, 176, 179, 182, 184, 52, 82
   types.ts100%100%100%100%
src/odsql
   clauses.ts82.61%71.43%80%90.91%14, 32, 42
   index.ts92.05%83.72%95.74%94.19%111, 146, 25, 28, 56–57, 57, 57–58, 68, 78–79

Please sign in to comment.