Skip to content

Commit 386f47b

Browse files
committed
refactor(tooltip): Updated Tooltip to use new Hover Mode
1 parent 4f5ce2f commit 386f47b

16 files changed

+1273
-1375
lines changed

packages/tooltip/src/Tooltip.tsx

Lines changed: 83 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import cn from "classnames";
88
import CSSTransition, {
99
CSSTransitionClassNames,
1010
} from "react-transition-group/CSSTransition";
11+
import {
12+
ConditionalPortal,
13+
RenderConditionalPortalProps,
14+
} from "@react-md/portal";
1115
import {
1216
OverridableTransitionProps,
1317
TransitionTimeout,
@@ -16,26 +20,33 @@ import { bem, SimplePosition } from "@react-md/utils";
1620

1721
import {
1822
DEFAULT_TOOLTIP_CLASSNAMES,
23+
DEFAULT_TOOLTIP_POSITION,
1924
DEFAULT_TOOLTIP_TIMEOUT,
2025
} from "./constants";
2126

27+
/** @remarks \@since 2.8.0 */
28+
export type TooltipTransitionProps = Pick<
29+
OverridableTransitionProps,
30+
| "onEnter"
31+
| "onEntering"
32+
| "onEntered"
33+
| "onExit"
34+
| "onExiting"
35+
| "onExited"
36+
| "mountOnEnter"
37+
| "unmountOnExit"
38+
>;
39+
2240
/**
2341
* The base props for the `Tooltip` component. This can be extended when
2442
* creating custom tooltip implementations.
43+
*
44+
* @remarks \@since 2.8.0 Supports the {@link RenderConditionalPortalProps}
2545
*/
2646
export interface TooltipProps
27-
extends Pick<
28-
OverridableTransitionProps,
29-
| "onEnter"
30-
| "onEntering"
31-
| "onEntered"
32-
| "onExit"
33-
| "onExiting"
34-
| "onExited"
35-
| "mountOnEnter"
36-
| "unmountOnExit"
37-
>,
38-
HTMLAttributes<HTMLSpanElement> {
47+
extends TooltipTransitionProps,
48+
HTMLAttributes<HTMLSpanElement>,
49+
RenderConditionalPortalProps {
3950
/**
4051
* An id for the tooltip. This is required for accessibility and finding an
4152
* element to attach event listeners to show and hide the tooltip.
@@ -114,6 +125,28 @@ const block = bem("rmd-tooltip");
114125
* with an animation when the visibility changes. If this component is used, you
115126
* will need to manually add all the event listeners and triggers to change the
116127
* `visible` prop.
128+
*
129+
* @example
130+
* Simple Usage
131+
* ```tsx
132+
* import { Button } from "@react-md/button";
133+
* import { useTooltip, Tooltip } from "@react-md/tooltip";
134+
*
135+
* function Example() {
136+
* const { tooltipProps, elementProps } = useTooltip({
137+
* baseId: 'my-element',
138+
* });
139+
*
140+
* return (
141+
* <>
142+
* <Button {...elementProps}>Button</Button>
143+
* <Tooltip {...tooltipProps}>
144+
* Tooltip Content
145+
* </Tooltip>
146+
* </>
147+
* );
148+
* }
149+
* ```
117150
*/
118151
export const Tooltip = forwardRef<HTMLSpanElement, TooltipProps>(
119152
function Tooltip(
@@ -124,51 +157,60 @@ export const Tooltip = forwardRef<HTMLSpanElement, TooltipProps>(
124157
timeout = DEFAULT_TOOLTIP_TIMEOUT,
125158
dense = false,
126159
lineWrap = true,
127-
position = "below",
160+
position = DEFAULT_TOOLTIP_POSITION,
128161
children,
129162
onEnter,
130163
onEntering,
131164
onEntered,
132165
onExit,
133166
onExiting,
134167
onExited,
168+
portal = true,
169+
portalInto,
170+
portalIntoId,
135171
mountOnEnter = true,
136172
unmountOnExit = true,
137173
...props
138174
},
139175
ref
140176
) {
141177
return (
142-
<CSSTransition
143-
classNames={classNames}
144-
in={visible}
145-
timeout={timeout}
146-
onEnter={onEnter}
147-
onEntering={onEntering}
148-
onEntered={onEntered}
149-
onExit={onExit}
150-
onExiting={onExiting}
151-
onExited={onExited}
152-
mountOnEnter={mountOnEnter}
153-
unmountOnExit={unmountOnExit}
178+
<ConditionalPortal
179+
portal={portal}
180+
portalInto={portalInto}
181+
portalIntoId={portalIntoId}
154182
>
155-
<span
156-
{...props}
157-
ref={ref}
158-
role="tooltip"
159-
className={cn(
160-
block({
161-
dense,
162-
"line-wrap": lineWrap,
163-
"dense-line-wrap": dense && lineWrap,
164-
[position]: true,
165-
}),
166-
className
167-
)}
183+
<CSSTransition
184+
classNames={classNames}
185+
in={visible}
186+
timeout={timeout}
187+
onEnter={onEnter}
188+
onEntering={onEntering}
189+
onEntered={onEntered}
190+
onExit={onExit}
191+
onExiting={onExiting}
192+
onExited={onExited}
193+
mountOnEnter={mountOnEnter}
194+
unmountOnExit={unmountOnExit}
168195
>
169-
{children}
170-
</span>
171-
</CSSTransition>
196+
<span
197+
{...props}
198+
ref={ref}
199+
role="tooltip"
200+
className={cn(
201+
block({
202+
dense,
203+
"line-wrap": lineWrap,
204+
"dense-line-wrap": dense && lineWrap,
205+
[position]: true,
206+
}),
207+
className
208+
)}
209+
>
210+
{children}
211+
</span>
212+
</CSSTransition>
213+
</ConditionalPortal>
172214
);
173215
}
174216
);

packages/tooltip/src/TooltipHoverModeConfig.tsx

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
import React, { ReactElement, ReactNode, useMemo } from "react";
1+
/* istanbul ignore file */
2+
import React, { ReactElement, ReactNode } from "react";
3+
import { HoverModeProvider } from "@react-md/utils";
24

35
import { DEFAULT_TOOLTIP_DELAY } from "./constants";
4-
import {
5-
HoverModeActions,
6-
HoverModeDelay,
7-
HoverModeEnabled,
8-
useTooltipHoverModeState,
9-
} from "./useTooltipHoverMode";
106

117
interface TooltipHoverModeConfigProps {
128
children: ReactNode;
@@ -19,38 +15,27 @@ interface TooltipHoverModeConfigProps {
1915
* This component is used so that tooltips can gain the "hover mode"
2016
* functionality in that once a tooltip has become visible by hover, all other
2117
* tooltips will become visible immediately until 3 seconds have passed.
18+
*
19+
* @deprecated \@since 2.8.0 Use the {@link @react-md/utils#HoverModeProvider}
20+
* instead.
2221
*/
2322
export function TooltipHoverModeConfig({
2423
defaultDelay = DEFAULT_TOOLTIP_DELAY,
2524
delayTimeout = DEFAULT_TOOLTIP_DELAY,
2625
enabled = true,
2726
children,
2827
}: TooltipHoverModeConfigProps): ReactElement {
29-
const { delay, enable, startDisableTimer } = useTooltipHoverModeState(
30-
defaultDelay,
31-
delayTimeout
32-
);
33-
34-
const actions = useMemo(
35-
() => ({
36-
enable,
37-
startDisableTimer,
38-
}),
39-
[enable, startDisableTimer]
40-
);
41-
4228
return (
43-
<HoverModeDelay.Provider value={delay}>
44-
<HoverModeActions.Provider value={actions}>
45-
<HoverModeEnabled.Provider value={enabled}>
46-
{children}
47-
</HoverModeEnabled.Provider>
48-
</HoverModeActions.Provider>
49-
</HoverModeDelay.Provider>
29+
<HoverModeProvider
30+
disabled={!enabled}
31+
defaultVisibleInTime={defaultDelay}
32+
deactivateTime={delayTimeout}
33+
>
34+
{children}
35+
</HoverModeProvider>
5036
);
5137
}
5238

53-
/* istanbul ignore next */
5439
if (process.env.NODE_ENV !== "production") {
5540
try {
5641
const PropTypes = require("prop-types");

0 commit comments

Comments
 (0)