From 93221eb38b65a6007171d517c7e6c6812b0384c1 Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Tue, 13 Oct 2026 10:44:27 +0200 Subject: [PATCH 1/2] fix(shared-charts): keep chart design preview within its parent --- .../area-chart-web/CHANGELOG.md | 4 ++ .../bar-chart-web/CHANGELOG.md | 4 ++ .../bubble-chart-web/CHANGELOG.md | 4 ++ .../column-chart-web/CHANGELOG.md | 4 ++ .../heatmap-chart-web/CHANGELOG.md | 4 ++ .../line-chart-web/CHANGELOG.md | 4 ++ .../pie-doughnut-chart-web/CHANGELOG.md | 4 ++ .../time-series-chart-web/CHANGELOG.md | 4 ++ .../charts/src/components/ChartPreview.tsx | 48 ++++++++++---- .../__tests__/ChartPreview.spec.tsx | 62 +++++++++++++++++++ 10 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 packages/shared/charts/src/components/__tests__/ChartPreview.spec.tsx diff --git a/packages/pluggableWidgets/area-chart-web/CHANGELOG.md b/packages/pluggableWidgets/area-chart-web/CHANGELOG.md index c45322fa1b..7273741d53 100644 --- a/packages/pluggableWidgets/area-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/area-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/bar-chart-web/CHANGELOG.md b/packages/pluggableWidgets/bar-chart-web/CHANGELOG.md index 7fc505c3f9..e955ee7ddf 100644 --- a/packages/pluggableWidgets/bar-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/bar-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/bubble-chart-web/CHANGELOG.md b/packages/pluggableWidgets/bubble-chart-web/CHANGELOG.md index 4ce50367b9..6e8fd8fb49 100644 --- a/packages/pluggableWidgets/bubble-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/bubble-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/column-chart-web/CHANGELOG.md b/packages/pluggableWidgets/column-chart-web/CHANGELOG.md index fb72fb4f43..b0db5626a4 100644 --- a/packages/pluggableWidgets/column-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/column-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/heatmap-chart-web/CHANGELOG.md b/packages/pluggableWidgets/heatmap-chart-web/CHANGELOG.md index 5fa0a56688..fd686fee4a 100644 --- a/packages/pluggableWidgets/heatmap-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/heatmap-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Fixed diff --git a/packages/pluggableWidgets/line-chart-web/CHANGELOG.md b/packages/pluggableWidgets/line-chart-web/CHANGELOG.md index a823c0960c..8ba188d875 100644 --- a/packages/pluggableWidgets/line-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/line-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/pie-doughnut-chart-web/CHANGELOG.md b/packages/pluggableWidgets/pie-doughnut-chart-web/CHANGELOG.md index 58e0177daa..def51cf8b5 100644 --- a/packages/pluggableWidgets/pie-doughnut-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/pie-doughnut-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/pluggableWidgets/time-series-chart-web/CHANGELOG.md b/packages/pluggableWidgets/time-series-chart-web/CHANGELOG.md index 10ad211b5f..73c92b90db 100644 --- a/packages/pluggableWidgets/time-series-chart-web/CHANGELOG.md +++ b/packages/pluggableWidgets/time-series-chart-web/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We added a "Refresh time (in seconds)" property that periodically reloads the chart data. +### Fixed + +- We fixed an issue where the chart in design mode overlapped other widgets on the page. The design mode preview now follows the configured width and height and stays within its parent. + ## [6.2.1] - 2025-07-15 ### Changed diff --git a/packages/shared/charts/src/components/ChartPreview.tsx b/packages/shared/charts/src/components/ChartPreview.tsx index 44b17af8fc..32d9a12136 100644 --- a/packages/shared/charts/src/components/ChartPreview.tsx +++ b/packages/shared/charts/src/components/ChartPreview.tsx @@ -1,8 +1,12 @@ -import { ComponentType, ReactElement, ReactNode } from "react"; +import { ComponentType, CSSProperties, ReactElement, ReactNode } from "react"; export interface ChartPreviewProps { class: string; showLegend: boolean; + widthUnit: "percentage" | "pixels"; + width: number | null; + heightUnit: "percentageOfWidth" | "pixels" | "percentageOfParent"; + height: number | null; playground: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; showPlaygroundSlot?: boolean; image: ReactNode; @@ -12,7 +16,7 @@ export interface ChartPreviewProps { export function ChartPreview(props: ChartPreviewProps): ReactElement { const { renderer: PlaygroundSlot } = props.playground ?? { renderer: () => null }; return ( -
+
{ - return {props.alt}; + return ( + {props.alt} + ); }; ChartPreview.PlotLegend = (props: { src: string; alt: string }) => { - return {props.alt}; + return {props.alt}; }; +// Mirrors the runtime dimensions, but never lets the preview grow past its parent. +function getPreviewDimensions(props: ChartPreviewProps): CSSProperties { + const style: CSSProperties = { boxSizing: "border-box", maxWidth: "100%", maxHeight: "100%" }; + + if (props.width) { + style.width = props.widthUnit === "percentage" ? `${props.width}%` : `${props.width}px`; + } + + if (props.height) { + if (props.heightUnit === "percentageOfWidth") { + style.aspectRatio = `100 / ${props.height}`; + } else if (props.heightUnit === "pixels") { + style.height = `${props.height}px`; + } else { + style.height = `${props.height}%`; + } + } + + return style; +} + function Chart(props: ChartPreviewProps): ReactElement { return ( -
+
{props.image} {props.showLegend ? props.legend : null}
diff --git a/packages/shared/charts/src/components/__tests__/ChartPreview.spec.tsx b/packages/shared/charts/src/components/__tests__/ChartPreview.spec.tsx new file mode 100644 index 0000000000..5e85921f15 --- /dev/null +++ b/packages/shared/charts/src/components/__tests__/ChartPreview.spec.tsx @@ -0,0 +1,62 @@ +import { render } from "@testing-library/react"; +import { ChartPreview, ChartPreviewProps } from "../ChartPreview"; + +function renderChart(props: Partial = {}): HTMLElement { + const { container } = render( + null }} + widthUnit="percentage" + width={100} + heightUnit="percentageOfWidth" + height={75} + image={} + legend={} + {...props} + /> + ); + return container.querySelector(".chart-under-test")!; +} + +describe("ChartPreview", () => { + it("never grows past its parent", () => { + const chart = renderChart({ widthUnit: "pixels", width: 2000, heightUnit: "pixels", height: 2000 }); + + expect(chart.style.maxWidth).toBe("100%"); + expect(chart.style.maxHeight).toBe("100%"); + expect(chart.parentElement!.style.display).toBe("flex"); + expect(chart.parentElement!.style.maxWidth).toBe("100%"); + }); + + it("applies percentage width", () => { + expect(renderChart({ widthUnit: "percentage", width: 50 }).style.width).toBe("50%"); + }); + + it("applies pixel width and height", () => { + const chart = renderChart({ widthUnit: "pixels", width: 400, heightUnit: "pixels", height: 250 }); + + expect(chart.style.width).toBe("400px"); + expect(chart.style.height).toBe("250px"); + }); + + it("applies height as percentage of parent", () => { + expect(renderChart({ heightUnit: "percentageOfParent", height: 60 }).style.height).toBe("60%"); + }); + + it("leaves height to the aspect ratio when height is a percentage of width", () => { + expect(renderChart({ heightUnit: "percentageOfWidth", height: 50 }).style.height).toBe(""); + }); + + it("lets the plot image shrink with the chart", () => { + const image = renderChart().querySelector("img[alt='Plot']")!; + + expect(image.style.width).toBe(""); + expect(image.style.minWidth).toBe("0"); + }); + + it("renders the legend only when enabled", () => { + expect(renderChart({ showLegend: false }).querySelector("img[alt='Legend']")).toBeNull(); + expect(renderChart({ showLegend: true }).querySelector("img[alt='Legend']")).not.toBeNull(); + }); +}); From cbb55a0ea9fcee749034070d780af2513ad509f5 Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Wed, 14 Oct 2026 11:29:32 +0200 Subject: [PATCH 2/2] refactor(shared-charts): move chart preview styles into getPreviewDimensions --- packages/shared/charts/src/components/ChartPreview.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/shared/charts/src/components/ChartPreview.tsx b/packages/shared/charts/src/components/ChartPreview.tsx index 32d9a12136..cab26a4531 100644 --- a/packages/shared/charts/src/components/ChartPreview.tsx +++ b/packages/shared/charts/src/components/ChartPreview.tsx @@ -49,7 +49,13 @@ ChartPreview.PlotLegend = (props: { src: string; alt: string }) => { // Mirrors the runtime dimensions, but never lets the preview grow past its parent. function getPreviewDimensions(props: ChartPreviewProps): CSSProperties { - const style: CSSProperties = { boxSizing: "border-box", maxWidth: "100%", maxHeight: "100%" }; + const style: CSSProperties = { + display: "flex", + overflow: "hidden", + boxSizing: "border-box", + maxWidth: "100%", + maxHeight: "100%" + }; if (props.width) { style.width = props.widthUnit === "percentage" ? `${props.width}%` : `${props.width}px`; @@ -70,7 +76,7 @@ function getPreviewDimensions(props: ChartPreviewProps): CSSProperties { function Chart(props: ChartPreviewProps): ReactElement { return ( -
+
{props.image} {props.showLegend ? props.legend : null}