diff --git a/webview/src/plots/components/App.test.tsx b/webview/src/plots/components/App.test.tsx index 74af9b206d..10de1b232c 100644 --- a/webview/src/plots/components/App.test.tsx +++ b/webview/src/plots/components/App.test.tsx @@ -2637,6 +2637,78 @@ describe('App', () => { expect(clickEvent.stopPropagation).toHaveBeenCalledTimes(1) }) + it('should have a tooltip on the plot if the title is cut', () => { + const title = 'Plot with a long title' + renderAppWithOptionalData({ + template: { + ...templatePlotsFixture, + plots: [ + { + entries: [ + { + ...templatePlotsFixture.plots[0].entries[0], + content: { + ...templatePlotsFixture.plots[0].entries[0].content, + title: '… with a long title' + } as unknown as VisualizationSpec, + id: title + } + ], + group: TemplatePlotGroup.SINGLE_VIEW + } + ] + } + }) + + expect(screen.queryByText(title)).not.toBeInTheDocument() + + const plot = within(screen.getByTestId(`plot_${title}`)).getAllByRole( + 'button' + )[0] + fireEvent.mouseEnter(plot, { + bubbles: true, + cancelable: true + }) + + expect(screen.getByText(title)).toBeInTheDocument() + }) + + it('should not have a tooltip on the plot if the title is not cut', () => { + const title = 'Short title' + renderAppWithOptionalData({ + template: { + ...templatePlotsFixture, + plots: [ + { + entries: [ + { + ...templatePlotsFixture.plots[0].entries[0], + content: { + ...templatePlotsFixture.plots[0].entries[0].content, + title + } as unknown as VisualizationSpec, + id: title + } + ], + group: TemplatePlotGroup.SINGLE_VIEW + } + ] + } + }) + + expect(screen.queryByText(title)).not.toBeInTheDocument() + + const plot = within(screen.getByTestId(`plot_${title}`)).getAllByRole( + 'button' + )[0] + fireEvent.mouseEnter(plot, { + bubbles: true, + cancelable: true + }) + + expect(screen.queryByText(title)).not.toBeInTheDocument() + }) + describe('Smooth Plots', () => { const waitSetValuePostMessage = (value: number) => waitFor( diff --git a/webview/src/plots/components/ZoomablePlot.tsx b/webview/src/plots/components/ZoomablePlot.tsx index d426009284..806e27bbc0 100644 --- a/webview/src/plots/components/ZoomablePlot.tsx +++ b/webview/src/plots/components/ZoomablePlot.tsx @@ -4,6 +4,7 @@ import React, { useEffect, useRef } from 'react' import { useDispatch } from 'react-redux' import { VisualizationSpec } from 'react-vega' import VegaLite, { VegaLiteProps } from 'react-vega/lib/VegaLite' +import { ZoomablePlotWrapper } from './ZoomablePlotWrapper' import { TemplateVegaLite } from './templatePlots/TemplateVegaLite' import { setZoomedInPlot } from './webviewSlice' import styles from './styles.module.scss' @@ -77,39 +78,41 @@ export const ZoomablePlot: React.FC = ({ } return ( - + + { + event.stopPropagation() + handleOnClick(true) + }} + onKeyDown={event => { + if (event.key === 'Enter') { + handleOnClick(true) + } + }} + role="button" + tabIndex={0} + aria-label="See Plot Export Options" + > + + + {currentPlotProps.current && + (isTemplatePlot ? ( + + ) : ( + + ))} + + ) } diff --git a/webview/src/plots/components/ZoomablePlotWrapper.tsx b/webview/src/plots/components/ZoomablePlotWrapper.tsx new file mode 100644 index 0000000000..5a7540b319 --- /dev/null +++ b/webview/src/plots/components/ZoomablePlotWrapper.tsx @@ -0,0 +1,21 @@ +import React, { ReactElement, PropsWithChildren } from 'react' +import Tooltip from '../../shared/components/tooltip/Tooltip' + +interface ZoomablePlotWrapperProps { + title?: string + id: string +} + +export const ZoomablePlotWrapper: React.FC< + PropsWithChildren +> = ({ title, id, children }) => { + const isTitleCut = title?.indexOf('…') === 0 + + return isTitleCut ? ( + + {children as ReactElement} + + ) : ( + children + ) +} diff --git a/webview/src/plots/components/ZoomedInPlot.tsx b/webview/src/plots/components/ZoomedInPlot.tsx index ebbf80024f..3cf2bfebfe 100644 --- a/webview/src/plots/components/ZoomedInPlot.tsx +++ b/webview/src/plots/components/ZoomedInPlot.tsx @@ -9,6 +9,7 @@ import { } from 'dvc/src/plots/vega/util' import { TemplateVegaLite } from './templatePlots/TemplateVegaLite' import styles from './styles.module.scss' +import { ZoomablePlotWrapper } from './ZoomablePlotWrapper' import { getThemeValue, ThemeProperty } from '../../util/styles' import { exportPlotDataAsCsv, @@ -101,20 +102,22 @@ export const ZoomedInPlot: React.FC = ({ } return ( -
- {isTemplatePlot ? ( - - ) : ( - - )} -
+ +
+ {isTemplatePlot ? ( + + ) : ( + + )} +
+
) }