Skip to content

Commit

Permalink
refactor(tooltip): Updated Tooltip to use new Hover Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Apr 18, 2021
1 parent 4f5ce2f commit 386f47b
Show file tree
Hide file tree
Showing 16 changed files with 1,273 additions and 1,375 deletions.
124 changes: 83 additions & 41 deletions packages/tooltip/src/Tooltip.tsx
Expand Up @@ -8,6 +8,10 @@ import cn from "classnames";
import CSSTransition, {
CSSTransitionClassNames,
} from "react-transition-group/CSSTransition";
import {
ConditionalPortal,
RenderConditionalPortalProps,
} from "@react-md/portal";
import {
OverridableTransitionProps,
TransitionTimeout,
Expand All @@ -16,26 +20,33 @@ import { bem, SimplePosition } from "@react-md/utils";

import {
DEFAULT_TOOLTIP_CLASSNAMES,
DEFAULT_TOOLTIP_POSITION,
DEFAULT_TOOLTIP_TIMEOUT,
} from "./constants";

/** @remarks \@since 2.8.0 */
export type TooltipTransitionProps = Pick<
OverridableTransitionProps,
| "onEnter"
| "onEntering"
| "onEntered"
| "onExit"
| "onExiting"
| "onExited"
| "mountOnEnter"
| "unmountOnExit"
>;

/**
* The base props for the `Tooltip` component. This can be extended when
* creating custom tooltip implementations.
*
* @remarks \@since 2.8.0 Supports the {@link RenderConditionalPortalProps}
*/
export interface TooltipProps
extends Pick<
OverridableTransitionProps,
| "onEnter"
| "onEntering"
| "onEntered"
| "onExit"
| "onExiting"
| "onExited"
| "mountOnEnter"
| "unmountOnExit"
>,
HTMLAttributes<HTMLSpanElement> {
extends TooltipTransitionProps,
HTMLAttributes<HTMLSpanElement>,
RenderConditionalPortalProps {
/**
* An id for the tooltip. This is required for accessibility and finding an
* element to attach event listeners to show and hide the tooltip.
Expand Down Expand Up @@ -114,6 +125,28 @@ const block = bem("rmd-tooltip");
* with an animation when the visibility changes. If this component is used, you
* will need to manually add all the event listeners and triggers to change the
* `visible` prop.
*
* @example
* Simple Usage
* ```tsx
* import { Button } from "@react-md/button";
* import { useTooltip, Tooltip } from "@react-md/tooltip";
*
* function Example() {
* const { tooltipProps, elementProps } = useTooltip({
* baseId: 'my-element',
* });
*
* return (
* <>
* <Button {...elementProps}>Button</Button>
* <Tooltip {...tooltipProps}>
* Tooltip Content
* </Tooltip>
* </>
* );
* }
* ```
*/
export const Tooltip = forwardRef<HTMLSpanElement, TooltipProps>(
function Tooltip(
Expand All @@ -124,51 +157,60 @@ export const Tooltip = forwardRef<HTMLSpanElement, TooltipProps>(
timeout = DEFAULT_TOOLTIP_TIMEOUT,
dense = false,
lineWrap = true,
position = "below",
position = DEFAULT_TOOLTIP_POSITION,
children,
onEnter,
onEntering,
onEntered,
onExit,
onExiting,
onExited,
portal = true,
portalInto,
portalIntoId,
mountOnEnter = true,
unmountOnExit = true,
...props
},
ref
) {
return (
<CSSTransition
classNames={classNames}
in={visible}
timeout={timeout}
onEnter={onEnter}
onEntering={onEntering}
onEntered={onEntered}
onExit={onExit}
onExiting={onExiting}
onExited={onExited}
mountOnEnter={mountOnEnter}
unmountOnExit={unmountOnExit}
<ConditionalPortal
portal={portal}
portalInto={portalInto}
portalIntoId={portalIntoId}
>
<span
{...props}
ref={ref}
role="tooltip"
className={cn(
block({
dense,
"line-wrap": lineWrap,
"dense-line-wrap": dense && lineWrap,
[position]: true,
}),
className
)}
<CSSTransition
classNames={classNames}
in={visible}
timeout={timeout}
onEnter={onEnter}
onEntering={onEntering}
onEntered={onEntered}
onExit={onExit}
onExiting={onExiting}
onExited={onExited}
mountOnEnter={mountOnEnter}
unmountOnExit={unmountOnExit}
>
{children}
</span>
</CSSTransition>
<span
{...props}
ref={ref}
role="tooltip"
className={cn(
block({
dense,
"line-wrap": lineWrap,
"dense-line-wrap": dense && lineWrap,
[position]: true,
}),
className
)}
>
{children}
</span>
</CSSTransition>
</ConditionalPortal>
);
}
);
Expand Down
41 changes: 13 additions & 28 deletions packages/tooltip/src/TooltipHoverModeConfig.tsx
@@ -1,12 +1,8 @@
import React, { ReactElement, ReactNode, useMemo } from "react";
/* istanbul ignore file */
import React, { ReactElement, ReactNode } from "react";
import { HoverModeProvider } from "@react-md/utils";

import { DEFAULT_TOOLTIP_DELAY } from "./constants";
import {
HoverModeActions,
HoverModeDelay,
HoverModeEnabled,
useTooltipHoverModeState,
} from "./useTooltipHoverMode";

interface TooltipHoverModeConfigProps {
children: ReactNode;
Expand All @@ -19,38 +15,27 @@ interface TooltipHoverModeConfigProps {
* This component is used so that tooltips can gain the "hover mode"
* functionality in that once a tooltip has become visible by hover, all other
* tooltips will become visible immediately until 3 seconds have passed.
*
* @deprecated \@since 2.8.0 Use the {@link @react-md/utils#HoverModeProvider}
* instead.
*/
export function TooltipHoverModeConfig({
defaultDelay = DEFAULT_TOOLTIP_DELAY,
delayTimeout = DEFAULT_TOOLTIP_DELAY,
enabled = true,
children,
}: TooltipHoverModeConfigProps): ReactElement {
const { delay, enable, startDisableTimer } = useTooltipHoverModeState(
defaultDelay,
delayTimeout
);

const actions = useMemo(
() => ({
enable,
startDisableTimer,
}),
[enable, startDisableTimer]
);

return (
<HoverModeDelay.Provider value={delay}>
<HoverModeActions.Provider value={actions}>
<HoverModeEnabled.Provider value={enabled}>
{children}
</HoverModeEnabled.Provider>
</HoverModeActions.Provider>
</HoverModeDelay.Provider>
<HoverModeProvider
disabled={!enabled}
defaultVisibleInTime={defaultDelay}
deactivateTime={delayTimeout}
>
{children}
</HoverModeProvider>
);
}

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

0 comments on commit 386f47b

Please sign in to comment.