Skip to content

Commit 645b65e

Browse files
committed
fix(Tooltip): dynamic label case
1 parent 5283d57 commit 645b65e

File tree

5 files changed

+56
-32
lines changed

5 files changed

+56
-32
lines changed

src/components/actions/Menu/Menu.test.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ describe('<Menu />', () => {
477477
it('should handle keyboard navigation', async () => {
478478
const onAction = jest.fn();
479479

480-
const { getByRole } = render(
480+
const { getByRole } = renderWithRoot(
481481
<Menu id="test-menu" aria-label="Test menu" onAction={onAction}>
482482
{basicItems}
483483
</Menu>,
@@ -496,7 +496,7 @@ describe('<Menu />', () => {
496496
});
497497

498498
it('should handle keyboard navigation with focus wrapping', async () => {
499-
const { getByRole } = render(
499+
const { getByRole } = renderWithRoot(
500500
<Menu shouldFocusWrap id="test-menu" aria-label="Test menu">
501501
{basicItems}
502502
</Menu>,
@@ -516,7 +516,7 @@ describe('<Menu />', () => {
516516
});
517517

518518
it('should handle keyboard navigation with arrow keys', async () => {
519-
const { getByRole } = render(
519+
const { getByRole } = renderWithRoot(
520520
<Menu id="test-menu" aria-label="Test menu">
521521
{basicItems}
522522
</Menu>,
@@ -549,7 +549,7 @@ describe('<Menu />', () => {
549549
});
550550

551551
it('should handle focus with first strategy', () => {
552-
const { container } = render(
552+
const { container } = renderWithRoot(
553553
<Menu id="test-menu" aria-label="Test menu" autoFocus="first">
554554
{basicItems}
555555
</Menu>,
@@ -561,7 +561,7 @@ describe('<Menu />', () => {
561561
});
562562

563563
it('should handle focus with last strategy', () => {
564-
const { container } = render(
564+
const { container } = renderWithRoot(
565565
<Menu id="test-menu" aria-label="Test menu" autoFocus="last">
566566
{basicItems}
567567
</Menu>,

src/components/content/ItemBase/ItemBase.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,12 @@ export function useAutoTooltip({
414414
tooltip,
415415
children,
416416
labelProps,
417+
isDynamicLabel = false, // if actions are set
417418
}: {
418419
tooltip: CubeItemBaseProps['tooltip'];
419420
children: ReactNode;
420421
labelProps?: Props;
422+
isDynamicLabel?: boolean;
421423
}) {
422424
// Determine if auto tooltip is enabled
423425
// Auto tooltip only works when children is a string (overflow detection needs text)
@@ -551,12 +553,15 @@ export function useAutoTooltip({
551553

552554
// Boolean tooltip - auto tooltip on overflow
553555
if (tooltip === true) {
554-
if (children || labelProps) {
556+
if (
557+
(children || labelProps) &&
558+
(isLabelOverflowed || isDynamicLabel)
559+
) {
555560
return (
556561
<TooltipProvider
557562
placement={defaultTooltipPlacement}
558563
title={children}
559-
isDisabled={!isLabelOverflowed}
564+
isDisabled={!isLabelOverflowed && isDynamicLabel}
560565
>
561566
{(triggerProps, ref) => renderElement(triggerProps, ref)}
562567
</TooltipProvider>
@@ -581,13 +586,18 @@ export function useAutoTooltip({
581586
}
582587

583588
// If title is provided with auto=true, OR no title but auto behavior enabled
584-
if (children || labelProps) {
589+
if (
590+
(children || labelProps) &&
591+
(isLabelOverflowed || isDynamicLabel)
592+
) {
585593
return (
586594
<TooltipProvider
587595
placement={defaultTooltipPlacement}
588596
title={tooltipProps.title ?? children}
589597
isDisabled={
590-
!isLabelOverflowed && tooltipProps.isDisabled !== true
598+
!isLabelOverflowed &&
599+
isDynamicLabel &&
600+
tooltipProps.isDisabled !== true
591601
}
592602
{...tooltipProps}
593603
>
@@ -753,7 +763,12 @@ const ItemBase = <T extends HTMLElement = HTMLDivElement>(
753763
labelProps: finalLabelProps,
754764
labelRef,
755765
renderWithTooltip,
756-
} = useAutoTooltip({ tooltip, children, labelProps });
766+
} = useAutoTooltip({
767+
tooltip,
768+
children,
769+
labelProps,
770+
isDynamicLabel: !!actions,
771+
});
757772

758773
// Create a stable render function that doesn't call hooks
759774
const renderItemElement = useCallback(

src/components/overlays/Tooltip/Tooltip.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function Tooltip(
174174

175175
const styles = extractStyles(otherProps, CONTAINER_STYLES);
176176

177-
let { tooltipProps } = useTooltip(props, state);
177+
let { tooltipProps } = useTooltip({ ...props, isDismissable: false }, state);
178178

179179
// Sync ref with overlayRef from context.
180180
useImperativeHandle(ref, () => createDOMRef(finalOverlayRef));

src/components/overlays/Tooltip/TooltipProvider.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export interface CubeTooltipProviderProps
2626

2727
export function TooltipProvider(props: CubeTooltipProviderProps): ReactElement {
2828
const [rendered, setRendered] = useState(false);
29-
const { title, children, tooltipStyles, width, ...otherProps } = props;
29+
const { title, children, tooltipStyles, width, isDisabled, ...otherProps } =
30+
props;
3031

3132
useEffect(() => {
3233
setRendered(true);
@@ -48,17 +49,25 @@ export function TooltipProvider(props: CubeTooltipProviderProps): ReactElement {
4849
// Both patterns pass through to TooltipTrigger
4950
// The difference is whether we pass function or element as first child
5051
return (
51-
<TooltipTrigger {...otherProps} disableFocusableProvider={isFunction}>
52+
<TooltipTrigger
53+
{...otherProps}
54+
isDisabled={isDisabled}
55+
disableFocusableProvider={isFunction}
56+
>
5257
{isFunction ||
5358
isValidElement(children) ||
5459
typeof children === 'string' ? (
5560
children
5661
) : (
5762
<>{children}</>
5863
)}
59-
<Tooltip styles={tooltipStyles} {...(width ? { width } : null)}>
60-
{title}
61-
</Tooltip>
64+
{isDisabled ? (
65+
<div />
66+
) : (
67+
<Tooltip styles={tooltipStyles} {...(width ? { width } : null)}>
68+
{title}
69+
</Tooltip>
70+
)}
6271
</TooltipTrigger>
6372
);
6473
}

src/components/overlays/Tooltip/TooltipTrigger.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,15 @@ export function TooltipTrigger(props: CubeTooltipTriggerProps) {
144144
let tooltipTriggerRef = externalRef ?? internalRef;
145145
let overlayRef = useRef<HTMLElement | null>(null);
146146

147-
let state = useTooltipTriggerState({ delay, ...props });
147+
let state = useTooltipTriggerState({ delay, ...props, isDismissable: false });
148148

149149
let { triggerProps, tooltipProps } = useTooltipTrigger(
150150
{
151151
trigger: triggerAction,
152152
delay,
153153
isOpen,
154154
onOpenChange,
155+
isDismissable: false,
155156
defaultOpen,
156157
},
157158
state,
@@ -165,6 +166,7 @@ export function TooltipTrigger(props: CubeTooltipTriggerProps) {
165166
overlayRef,
166167
offset,
167168
crossOffset,
169+
isDismissable: false,
168170
isOpen: state.isOpen,
169171
});
170172

@@ -227,21 +229,19 @@ export function TooltipTrigger(props: CubeTooltipTriggerProps) {
227229
trigger
228230
)}
229231
<DisplayTransition isShown={state.isOpen && !isDisabled}>
230-
{({ phase, isShown, ref: transitionRef }) =>
231-
isDisabled ? null : (
232-
<TooltipContext.Provider
233-
value={{
234-
...tooltipContextValue,
235-
phase,
236-
isShown,
237-
ref: overlayRef,
238-
transitionRef,
239-
}}
240-
>
241-
<Portal>{tooltip}</Portal>
242-
</TooltipContext.Provider>
243-
)
244-
}
232+
{({ phase, isShown, ref: transitionRef }) => (
233+
<TooltipContext.Provider
234+
value={{
235+
...tooltipContextValue,
236+
phase,
237+
isShown,
238+
ref: overlayRef,
239+
transitionRef,
240+
}}
241+
>
242+
<Portal>{tooltip}</Portal>
243+
</TooltipContext.Provider>
244+
)}
245245
</DisplayTransition>
246246
</>
247247
);

0 commit comments

Comments
 (0)