Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tiny-bananas-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-uikit/tooltip': patch
---

Prevents image clipping when Tooltip component is hovered.
22 changes: 22 additions & 0 deletions packages/components/tooltip/src/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -185,6 +191,7 @@ const Tooltip = ({
const { reference, popper, popperInstance } = usePopper({
placement: placement,
modifiers: props.modifiers,
positionFixed: props.positionFixed,
});
const [state, setState] = useState<TTooltipState>('closed');

Expand Down Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions test/setup-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ Object.defineProperty(window, 'TextDecoder', {
writable: true,
value: TextDecoder,
});
global.ResizeObserver = class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
};

const silenceConsoleWarnings = [];
const notThrowWarnings = [
Expand Down
Loading