From c9b1e81ed2a5d7da3a2bff9637c1dbfeea614e5c Mon Sep 17 00:00:00 2001 From: Kyle Cunningham Date: Wed, 3 Jul 2024 14:10:54 -0500 Subject: [PATCH] Table panel: Add alt and title text options to image cell type (#89930) * Various updates * Update form callbacks * Use defaultValue as opposed to value on input * Fix things up * Docs * Prettier * Update docs * Update label text * Prettier --- .../visualizations/table/index.md | 4 ++ .../grafana-schema/src/common/common.gen.ts | 2 + packages/grafana-schema/src/common/table.cue | 2 + .../src/components/Table/ImageCell.tsx | 38 +++++++++---------- .../panel/table/TableCellOptionEditor.tsx | 4 ++ .../table/cells/ImageCellOptionsEditor.tsx | 33 ++++++++++++++++ 6 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 public/app/plugins/panel/table/cells/ImageCellOptionsEditor.tsx diff --git a/docs/sources/panels-visualizations/visualizations/table/index.md b/docs/sources/panels-visualizations/visualizations/table/index.md index 3bdacc05ec8..f304c302823 100644 --- a/docs/sources/panels-visualizations/visualizations/table/index.md +++ b/docs/sources/panels-visualizations/visualizations/table/index.md @@ -209,6 +209,10 @@ If you have a field value that is an image URL or a base64 encoded image you can {{< figure src="/static/img/docs/v73/table_hover.gif" max-width="900px" caption="Table hover" >}} +Use the **Alt text** option to set the alternative text of an image. The text will be available for screen readers and in cases when images can't be loaded. + +Use the **Title text** option to set the text that's displayed when the image is hovered over with a cursor. + #### Sparkline Shows values rendered as a sparkline. You can show sparklines using the [Time series to table transformation](ref:time-series-to-table-transformation) on data with multiple time series to process it into a format the table can show. diff --git a/packages/grafana-schema/src/common/common.gen.ts b/packages/grafana-schema/src/common/common.gen.ts index 960abb68275..ff3fce0def6 100644 --- a/packages/grafana-schema/src/common/common.gen.ts +++ b/packages/grafana-schema/src/common/common.gen.ts @@ -771,6 +771,8 @@ export interface TableJsonViewCellOptions { * Json view cell options */ export interface TableImageCellOptions { + alt?: string; + title?: string; type: TableCellDisplayMode.Image; } diff --git a/packages/grafana-schema/src/common/table.cue b/packages/grafana-schema/src/common/table.cue index 417d9768ea6..9dc54fe5ec4 100644 --- a/packages/grafana-schema/src/common/table.cue +++ b/packages/grafana-schema/src/common/table.cue @@ -48,6 +48,8 @@ TableJsonViewCellOptions: { // Json view cell options TableImageCellOptions: { type: TableCellDisplayMode & "image" + alt?: string + title?: string } @cuetsy(kind="interface") // Show data links in the cell diff --git a/packages/grafana-ui/src/components/Table/ImageCell.tsx b/packages/grafana-ui/src/components/Table/ImageCell.tsx index 83b8b888911..4e9543659ec 100644 --- a/packages/grafana-ui/src/components/Table/ImageCell.tsx +++ b/packages/grafana-ui/src/components/Table/ImageCell.tsx @@ -3,41 +3,41 @@ import * as React from 'react'; import { getCellLinks } from '../../utils'; import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu'; -import { TableCellProps } from './types'; +import { TableCellDisplayMode, TableCellProps } from './types'; +import { getCellOptions } from './utils'; const DATALINKS_HEIGHT_OFFSET = 10; export const ImageCell = (props: TableCellProps) => { const { field, cell, tableStyles, row, cellProps } = props; - + const cellOptions = getCellOptions(field); + const { title, alt } = + cellOptions.type === TableCellDisplayMode.Image ? cellOptions : { title: undefined, alt: undefined }; const displayValue = field.display!(cell.value); - const hasLinks = Boolean(getCellLinks(field, row)?.length); + // The image element + const img = ( + {alt} + ); + return (
- {!hasLinks && ( - - )} + {/* If there are no links we simply render the image */} + {!hasLinks && img} + {/* Otherwise render data links with image */} {hasLinks && ( getCellLinks(field, row) || []} > {(api) => { - const img = ( - - ); if (api.openMenu) { return (
{ {cellType === TableCellDisplayMode.Sparkline && ( )} + {cellType === TableCellDisplayMode.Image && ( + + )}
); }; diff --git a/public/app/plugins/panel/table/cells/ImageCellOptionsEditor.tsx b/public/app/plugins/panel/table/cells/ImageCellOptionsEditor.tsx new file mode 100644 index 00000000000..51e711cd367 --- /dev/null +++ b/public/app/plugins/panel/table/cells/ImageCellOptionsEditor.tsx @@ -0,0 +1,33 @@ +import { FormEvent } from 'react'; + +import { TableImageCellOptions } from '@grafana/schema'; +import { Field, Input } from '@grafana/ui'; + +import { TableCellEditorProps } from '../TableCellOptionEditor'; + +export const ImageCellOptionsEditor = ({ cellOptions, onChange }: TableCellEditorProps) => { + const onAltChange = (e: FormEvent) => { + cellOptions.alt = e.currentTarget.value; + onChange(cellOptions); + }; + + const onTitleChange = (e: FormEvent) => { + cellOptions.title = e.currentTarget.value; + onChange(cellOptions); + }; + + return ( + <> + + + + + + + + + ); +};