import type { CSSProperties, HTMLAttributes, Ref } from "react"; import type { FixedPositioningTransitionCallbacks, TransitionCallbacks } from "@react-md/transition"; import type { HoverModeEventHandlers, HoverModeHookReturnValue, UserInteractionMode } from "@react-md/utils"; import type { TooltipProps } from "./Tooltip"; import type { TooltipPositionHookOptions } from "./useTooltipPosition"; /** * @internal * @remarks \@since 2.8.0 */ export declare type TooltipInitiatedBy = UserInteractionMode | null; /** @remarks \@since 2.8.0 */ export declare type TooltipTouchEventHandlers = Pick, "onTouchStart" | "onContextMenu">; /** @remarks \@since 2.8.0 */ export declare type TooltipKeyboardEventHandlers = Pick, "onBlur" | "onFocus" | "onKeyDown">; /** * These are all the event handlers that are required to control the visibility * of a tooltip-like element. * * @remarks \@since 2.8.0 */ export declare type TooltippedElementEventHandlers = TooltipTouchEventHandlers & TooltipKeyboardEventHandlers & Pick, keyof HoverModeEventHandlers>; /** @remarks \@since 2.8.0 */ export interface TooltipHookProvidedElementProps extends Required> { /** * The DOM `id` required for a11y that is based off of the * {@link TooltipHookOptions.baseId}. */ id: string; /** * An optional `aria-describedby` that will be provided only while the tooltip * is visible or the {@link TooltipHookOptions.describedBy} is provided. */ "aria-describedby"?: string; } /** @remarks \@since 2.8.0 */ export interface TooltipPositioningOptions { /** * An optional style object to merge and override the generated fixed * positioning styles. */ style?: CSSProperties; /** * This is the viewport width margin to use in the positioning calculation. * This is just used so that the tooltip can be placed with some spacing * between the left and right edges of the viewport if desired. */ vwMargin?: number; /** * This is the viewport height margin to use in the positioning calculation. * This is just used so that the tooltip can be placed with some spacing * between the top and bottom edges of the viewport if desired. */ vhMargin?: number; /** * Boolean if the tooltip is using the dense spec. This will reduce the * padding, margin and font size for the tooltip and is usually used for * desktop displays. */ dense?: boolean; /** * The amount of spacing to use for a non-dense tooltip. This is the distance * between the container element and the tooltip. */ spacing?: number | string; /** * The amount of spacing to use for a dense tooltip. This is the distance * between the container element and the tooltip. */ denseSpacing?: number | string; /** * Boolean if the auto-swapping behavior should be disabled. When this value * is `undefined`, it'll be treated as `true` when the `position` prop is * defined, otherwise `false`. */ disableSwapping?: boolean; /** * Since `react-md` provides mixins to automatically apply a dense spec * through mixins via media queries, the dense spec might be applied in css * instead of in JS. This component will actually check the current spacing * amount that has been applied when the tooltip becomes visible. * * If this behavior is not desired, you can enable this prop and it will only * use the provided `spacing` or `denseSpacing` props based on the `dense` * prop. * * Note: This will be defaulted to `true` when the * `process.env.NODE_ENV === 'test'` since test environments normally don't * have a default `window.getComputedStyle` value that is not `NaN` * which will display errors in your tests. */ disableAutoSpacing?: boolean; } /** @remarks \@since 2.8.0 */ export interface BaseTooltipHookOptions extends TransitionCallbacks, TooltipPositionHookOptions, TooltipPositioningOptions, TooltippedElementEventHandlers { /** * The amount of time to wait (in ms) before showing the tooltip after * triggering a `touchstart` event. You _probably_ won't ever need to change * this value. * * The default time is about the same it takes to display the context menu * with a "long touch" and cancel displaying the context menu. */ touchTime?: number; /** * The amount of time to wait (in ms) before showing the tooltip after a * keyboard user has triggered a `focus` event. You _probably_ won't ever need * to change this value. */ focusTime?: number; /** * Boolean if the hover mode functionality should be disabled for this * instance instead of inheriting the value from the * {@link HoverModeProvider}. */ disableHoverMode?: boolean; /** * Boolean if the event handlers should no longer attempt to show a tooltip. This * should be set to `true` when your component might not have a tooltip associated * with it. * * @example * Real World Example * ```tsx * import type { ReactElement, ReactNode } from "react"; * import { Button, ButtonProps } from "@react-md/button"; * import { Tooltip, useTooltip } from "@react-md/tooltip": * * export interface TooltippedButtonProps extends ButtonProps { * id: string; * tooltip?: ReactNode; * } * * export function TooltippedButton({ * id, * tooltip, * children, * onClick, * onBlur, * onFocus, * onKeyDown, * onMouseEnter, * onMouseLeave, * onTouchStart, * onContextMenu, * ...props * }: TooltippedButtonProps): ReactElement { * const { elementProps, tooltipProps } = useTooltip({ * disabled: !tooltip, * baseId: id, * onClick, * onBlur, * onFocus, * onKeyDown, * onMouseEnter, * onMouseLeave, * onTouchStart, * onContextMenu, * }); * * return ( * <> * * {tooltip} * * ); * } * ``` * * @defaultValue `false` * @remarks \@since 5.1.0 */ disabled?: boolean; } /** @remarks \@since 2.8.0 */ export interface TooltipHookOptions extends BaseTooltipHookOptions { /** * This is the DOM `id` to use for the tooltipped element and is used to * generate an `id` for the `Tooltip` component as: * * ```ts * const tooltipId = `${baseId}-tooltip` * ``` */ baseId: string; /** * An optional `aria-describedby` DOM `id` string to merge with the returned * `aria-describedby` string since it only exists when the tooltip is visible. */ describedBy?: string; } /** * The props that will be created from the {@link useTooltip} hook that should * be passed to the {@link Tooltip} component to work correctly. * * @remarks \@since 2.8.0 */ export declare type TooltipHookProvidedTooltipProps = Pick & Required & Required> & { ref: Ref; }; /** * Note: This is _really_ an internal type since this is handled automatically * from the {@link Tooltipped} component. * * @remarks \@since 2.8.0 */ export interface TooltipHookReturnValue extends Omit { /** {@inheritDoc TooltippedElementEventHandlers} */ handlers: Required>; /** * These are the props that should be provided to the element the tooltip is * attached to. */ elementProps: TooltipHookProvidedElementProps; /** * These props should be provided to the {@link Tooltip} component. */ tooltipProps: TooltipHookProvidedTooltipProps; } /** * This hook is used to handle the positioning and visibility of the tooltip * component mostly within the {@link Tooltipped} component. * * @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 ( * <> * * * Tooltip Content * * * ); * } * ``` * * @remarks \@since 2.8.0 * @param options - All the {@link TooltipHookOptions} to configure the tooltip behavior. * @returns The {@link TooltipHookReturnValue} */ export declare function useTooltip({ baseId, style: propStyle, describedBy, dense, spacing, denseSpacing, position: determinedPosition, defaultPosition, vwMargin, vhMargin, threshold, touchTime, focusTime, onFocus: propOnFocus, onBlur: propOnBlur, onKeyDown: propOnKeyDown, onClick, onMouseEnter, onMouseLeave, onTouchStart: propOnTouchStart, onContextMenu: propOnContextMenu, onEnter, onEntering, onEntered, onExited, disabled, disableSwapping, disableHoverMode: propDisableHoverMode, disableAutoSpacing, }: TooltipHookOptions): TooltipHookReturnValue;