From f715d360c020ff6d6be30f04d056f5b397c92efb Mon Sep 17 00:00:00 2001 From: tyler ford Date: Mon, 15 Jun 2026 13:04:49 -0400 Subject: [PATCH 1/3] fix(tooltip): prevent image clipping in tooltip --- packages/components/tooltip/src/tooltip.tsx | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/components/tooltip/src/tooltip.tsx b/packages/components/tooltip/src/tooltip.tsx index 8494da7d89..ad7b8addb9 100644 --- a/packages/components/tooltip/src/tooltip.tsx +++ b/packages/components/tooltip/src/tooltip.tsx @@ -106,6 +106,12 @@ export type TTooltipProps = { * Provides a way to fine-tune an appearance of underlying Popper tooltip element. For more information, please check [Popper.js documentation](https://popper.js.org/popper-documentation.html#modifiers). */ modifiers?: Modifiers; + /** + * Use CSS `position: fixed` for the popper element instead of `position: absolute`. + * Recommended when the tooltip body is rendered in a portal (e.g. via `TooltipWrapperComponent`) + * to prevent clipping caused by scrolled ancestors. + */ + positionFixed?: boolean; /** * Customize the appearance of certain elements of the tooltip. */ @@ -185,6 +191,7 @@ const Tooltip = ({ const { reference, popper, popperInstance } = usePopper({ placement: placement, modifiers: props.modifiers, + positionFixed: props.positionFixed, }); const [state, setState] = useState('closed'); @@ -373,6 +380,21 @@ const Tooltip = ({ }; }, [state, off, isControlled, popperInstance, handleLeave]); + // Recompute position when the tooltip body resizes (e.g. an image that loads + // after the initial position was calculated from a 0-height container). + useEffect(() => { + if (!tooltipIsOpen) return; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const inst = popperInstance as any; + const popperEl = inst?.popper as HTMLElement | null; + if (!popperEl) return; + const ro = new ResizeObserver(() => { + inst.scheduleUpdate?.(); + }); + ro.observe(popperEl); + return () => ro.disconnect(); + }, [tooltipIsOpen, popperInstance]); + const childrenProps = { // don't pass event listeners to children onFocus: null, From f8757b3641b2479c4a74ed55d6a5b08a6f2172e5 Mon Sep 17 00:00:00 2001 From: tyler ford Date: Mon, 15 Jun 2026 13:06:06 -0400 Subject: [PATCH 2/3] fix(tooltip): changeset two --- .changeset/tiny-bananas-beam.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tiny-bananas-beam.md diff --git a/.changeset/tiny-bananas-beam.md b/.changeset/tiny-bananas-beam.md new file mode 100644 index 0000000000..0cb528ad53 --- /dev/null +++ b/.changeset/tiny-bananas-beam.md @@ -0,0 +1,5 @@ +--- +'@commercetools-uikit/tooltip': patch +--- + +Prevents image clipping when Tooltip component is hovered. From f3ce9b48b1bf1e5cd49238715a525e4f5c5a4bd0 Mon Sep 17 00:00:00 2001 From: tyler ford Date: Mon, 15 Jun 2026 13:19:11 -0400 Subject: [PATCH 3/3] fix(tooltip): add resizeobserver stub --- test/setup-tests.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/setup-tests.js b/test/setup-tests.js index 16b80cb794..08256d0c75 100644 --- a/test/setup-tests.js +++ b/test/setup-tests.js @@ -29,6 +29,11 @@ Object.defineProperty(window, 'TextDecoder', { writable: true, value: TextDecoder, }); +global.ResizeObserver = class ResizeObserver { + observe() {} + unobserve() {} + disconnect() {} +}; const silenceConsoleWarnings = []; const notThrowWarnings = [