Skip to content

Commit

Permalink
chore(Table): restrict media column to image column
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinFabre-ods committed Jul 2, 2024
1 parent d9d5a15 commit f73d635
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 77 deletions.
22 changes: 22 additions & 0 deletions packages/visualizations-react/stories/Table/custom-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@
color: #808080;
}

.ods-visualization-table__image-error-container {
color: red;
}

.ods-visualization-table__image-loading-container .loader {
display: inline-block;
width: 50px;
height: 50px;
border: 3px solid white;
border-radius: 50%;
border-top-color: red;
animation: spin 1s ease-in-out infinite;
-webkit-animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
to { -webkit-transform: rotate(360deg); }
}
@-webkit-keyframes spin {
to { -webkit-transform: rotate(360deg); }
}

.design-system {
color: blue;
}
Expand Down
18 changes: 9 additions & 9 deletions packages/visualizations-react/stories/Table/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default [
wordCount: 1200,
readingTime: 5.5,
url: 'https://example.com/lorem-ipsum',
media: 'https://gravatar.com/avatar/1?s=400&d=robohash',
image: 'https://gravatar.com/avatar/1?s=400&d=robohash',
},
{
title: 'pellentesque nec blog post',
Expand All @@ -20,7 +20,7 @@ export default [
wordCount: 800,
readingTime: 3.8,
url: 'https://example.com/pellentesque-nec',
media: 'https://gravatar.com/unkown-url',
image: 'https://gravatar.com/unkown-url',
},
{
title: 'fusce sit amet blog post',
Expand All @@ -32,7 +32,7 @@ export default [
wordCount: 1500,
readingTime: 7.2,
url: 'https://example.com/fusce-sit-amet',
media: 'https://loremflickr.com/cache/resized/65535_52821605306_fb553abe7e_k_673_1280_nofilter.jpg',
image: 'https://loremflickr.com/cache/resized/65535_52821605306_fb553abe7e_k_673_1280_nofilter.jpg',
},
{
title: 'vestibulum nec blog post',
Expand All @@ -43,7 +43,7 @@ export default [
wordCount: 1000,
readingTime: 4.5,
url: 'https://example.com/vestibulum-nec',
media: 'https://gravatar.com/avatar/4?s=400&d=robohash',
image: 'https://gravatar.com/avatar/4?s=400&d=robohash',
},
{
title: 'Cras At Blog Post',
Expand All @@ -55,7 +55,7 @@ export default [
wordCount: 1300,
readingTime: 6.0,
url: 'https://example.com/cras-at',
media: 'https://gravatar.com/avatar/5?s=400&d=robohash',
image: 'https://gravatar.com/avatar/5?s=400&d=robohash',
},
{
title: 'Quisque A Blog Post',
Expand All @@ -67,7 +67,7 @@ export default [
wordCount: 900,
readingTime: 4.0,
url: 'https://example.com/quisque-a',
media: 'https://gravatar.com/avatar/6?s=400&d=robohash',
image: 'https://gravatar.com/avatar/6?s=400&d=robohash',
},
{
title: 'Ut Vitae Blog Post',
Expand All @@ -79,7 +79,7 @@ export default [
wordCount: 1100,
readingTime: 5.0,
url: 'https://example.com/ut-vitae',
media: 'https://gravatar.com/avatar/7?s=400&d=robohash',
image: 'https://gravatar.com/avatar/7?s=400&d=robohash',
},
{
title: 'Integer Id Blog Post',
Expand All @@ -91,7 +91,7 @@ export default [
wordCount: 950,
readingTime: 4.2,
url: 'https://example.com/integer-id',
media: 'https://gravatar.com/avatar/8?s=400&d=robohash',
image: 'https://gravatar.com/avatar/8?s=400&d=robohash',
},
{
title: 'Undefined row',
Expand All @@ -102,7 +102,7 @@ export default [
wordCount: undefined,
readingTime: null,
url: undefined,
media: undefined,
image: undefined,
},
{
title: 'Empty row',
Expand Down
9 changes: 6 additions & 3 deletions packages/visualizations-react/stories/Table/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,12 @@ export const columns: Column[] = [
},
},
{
title: 'Media',
key: 'media',
dataFormat: 'media',
title: 'Image',
key: 'image',
dataFormat: 'image',
options: {
loadingContent: () => '<div class="loader"></div>'
}
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script lang="ts">
import type { Instance } from 'tippy.js';
import tippy from '../../../utils/tippy';
import { warn } from './utils';
export let rawValue: string;
export let display = (v: string) => v;
export let alt: (v: string) => string = () => '';
export let loadingContent: (v: string) => string = () => 'Loading...';
export let errorContent: (v: string) => string = () => 'Error while fetching image';
let tooltipContent: Element;
let image: HTMLImageElement | null = null;
let imageLoaded = false;
let hasError = false;
async function loadImage(tippyInstance: Instance) {
if (image !== null || hasError) return;
image = new Image();
image.src = rawValue;
try {
await image.decode();
image.alt = alt(rawValue);
image.classList.add('ods-visualization-table__image');
imageLoaded = true;
} catch (error) {
warn(rawValue, 'Image');
hasError = true;
}
tippyInstance.setContent(tooltipContent);
}
</script>

<div
role="button"
tabindex="0"
use:tippy={{
content: tooltipContent,
theme: 'ods-visualization-table',
delay: [500, 0],
duration: [275, 0],
maxWidth: 'none',
onTrigger(instance) {
loadImage(instance);
},
}}
>
<div class="ods-visualization-table__image-label">{display(rawValue)}</div>
<div bind:this={tooltipContent}>
{#if imageLoaded}
{@html image?.outerHTML}
{:else if hasError}
<div class="ods-visualization-table__image-error-container">
{@html errorContent(rawValue)}
</div>
{:else}
<div class="ods-visualization-table__image-loading-container">
{@html loadingContent(rawValue)}
</div>
{/if}
</div>
</div>

<style lang="scss">
div[role='button'] {
display: inline-block;
}
.ods-visualization-table__image-label {
cursor: pointer;
text-decoration: underline;
}
:global(.ods-visualization-table__image) {
object-fit: contain;
border-radius: 3px;
width: 360px;
height: 240px;
}
</style>

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import NumberFormat from './NumberFormat.svelte';
import URLFormat from './URLFormat.svelte';
import ShortTextFormat from './ShortTextFormat.svelte';
import LongTextFormat from './LongTextFormat.svelte';
import MediaFormat from './MediaFormat.svelte';
import ImageFormat from './ImageFormat.svelte';
import { isValidRawValue } from './utils';

const Format = {
Expand All @@ -14,7 +14,7 @@ const Format = {
'long-text': LongTextFormat,
url: URLFormat,
number: NumberFormat,
media: MediaFormat,
image: ImageFormat,
};

export { isValidRawValue };
Expand Down
2 changes: 1 addition & 1 deletion packages/visualizations/src/components/Table/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export const DATA_FORMAT = {
number: 'number',
boolean: 'boolean',
url: 'url',
media: 'media',
image: 'image',
} as const;
8 changes: 5 additions & 3 deletions packages/visualizations/src/components/Table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ export type URLColumn = BaseColumn & {
/**
* Render an interactive text that displays an image in a tooltip on tab/hover.
*/
export type MediaColumn = BaseColumn & {
dataFormat: typeof DATA_FORMAT.media;
export type ImageColumn = BaseColumn & {
dataFormat: typeof DATA_FORMAT.image;
options?: {
display?: (v: string) => string;
alt?: (v: string) => string;
loadingContent?: (v: string) => string;
errorContent?: (v: string) => string;
};
};

Expand All @@ -103,7 +105,7 @@ export type Column =
| DateColumn
| BooleanColumn
| URLColumn
| MediaColumn;
| ImageColumn;

export type TableOptions = {
columns: Column[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ $tippy-box-shadow: 0 6px 13px 0 rgba(0, 0, 0, 0.26);
.tippy-box[data-theme~='#{$table-theme}'] > .tippy-content {
padding: 6px;
border-radius: 6px;
color: black;
}

.tippy-box[data-theme~='#{$table-theme}'][data-placement^='top'] > .tippy-arrow::before {
Expand Down

0 comments on commit f73d635

Please sign in to comment.