import { type RefObject } from "react"; /** @since 6.0.0 */ export interface SimpleHoverModeContext { /** * @example Main Usage * ```ts * onMouseEnter(event) { * const hoverTimeout = hoverTimeoutRef.current; * if (typeof hoverTimeout !== "number" || mode === "touch") { * return; * } * * const { id } = event.currentTarget; * clearDisableTimer(); * window.clearTimeout(visibilityTimeout.current); * visibilityTimeout.current = window.setTimeout(() => { * enableHoverMode(id); * setVisible(true); * }, hoverTimeout); * } * ``` */ hoverTimeoutRef: RefObject; /** * @example Main Usage * ```ts * onMouseLeave() { * if (mode === "touch") { * return * } * * startDisableTimer(); * window.clearTimeout(visibilityTimeout.current); * visibilityTimeout.current = window.setTimeout(() => { * setVisible(false) * }, leaveTimeoutRef.current); * } * ``` */ leaveTimeoutRef: RefObject; /** * When this is called, the {@link hoverTimeoutRef} will be set to `0` and the * {@link HoverModeContext.activeId} will be set to this `activeId` value. * * @see {@link hoverTimeoutRef} for an example. */ enableHoverMode: (activeId: string) => void; /** * Disables all hover mode behavior by clearing all timeouts and resetting * internal state. */ disableHoverMode: () => void; /** * @see {@link leaveTimeoutRef} for an example. */ startDisableTimer: () => void; /** * @see {@link hoverTimeoutRef} for an example. */ clearDisableTimer: () => void; } /** * @since 2.8.0 * @since 6.0.0 Uses refs to increase performance by preventing unneeded * re-renders of the entire hover mode provider's component tree. The API also * changed to support custom hover mode providers. */ export interface HoverModeContext extends SimpleHoverModeContext { /** * This will only be updated if {@link HoverModeConfiguration.forceRerender} is `true` */ activeId: string; /** * This ref contains the current DOM `id` for the element that is being * hovered within the `HoverModeProvider`. This will be an empty string * when the hover mode is not active. */ activeIdRef: RefObject; /** * This ref can be used to disable transitions for a group of components using * the same hover mode provider. The general flow would be: * * - set `disableTransition: animatedOnceRef.current` on hover mode components * - set `animatedOnceRef.current = true` when the `onEntered` transition callback fires * - set `animatedOnceRef.current = false` when the hover mode behavior is * disabled. This would normally be after a timeout for the `onExited` * callback */ animatedOnceRef: RefObject; } /** * @since 6.0.0 */ export interface CreateHoverModeContextOptions { /** * This should only be used if creating nested hover mode behavior where the * hover mode should default to being enabled if a parent element is hovered. * So set this to an element's `id` if a parent element is being hovered when * the component **mounts**. * * The use case for this is the `MenuBar` component since after clicking a * menu button or hovering it long enough to enable the hover mode, all child * menus should also be in the hover mode until the top-most element is * closed. * * @defaultValue `""` */ defaultActiveId?: string; /** * When this is `undefined`, the hover mode behavior will be disabled. * Otherwise, this will be the amount of time to wait on a `mouseenter` event * before setting the visibility to `true`. * * @defaultValue `undefined` */ hoverTimeout?: number; /** * The amount of time to wait after a `mouseleave` event before setting the * visibility to `false`. * * @defaultValue `0` * @since 6.0.0 This was renamed from `exitVisibilityDelay` and the * default value changed from `300` to `0`. */ leaveTimeout?: number; } /** * @since 6.0.0 */ export declare function createHoverModeContext(options?: CreateHoverModeContextOptions): Readonly; /** @since 6.0.0 */ export interface HoverModeConfiguration extends CreateHoverModeContextOptions { /** * The amount of time to wait before disabling the hover mode behavior if none * of the components are being hovered. * * If this is `undefined`, {@link HoverModeContext.startDisableTimer} will do * nothing. You must manually call {@link HoverModeContext.disableHoverMode} * to disable the hover mode instead. */ disableTimeout?: number; /** * @defaultValue `false` */ forceRerender?: boolean; } /** * @example Creating a Hover Mode Group * ```tsx * import { * type HoverModeContext, * createHoverModeContext, * useHoverModeProvider, * } from "@react-md/core/hoverMode/useHoverModeProvider"; * import { * type ReactElement, * type ReactNode, * createContext, * useContext, * } from "react"; * * export interface CustomHoverContext extends HoverModeContext { * // any additional fields in the context * } * * const context = createContext( * createHoverModeContext() * // you can also provide default values if needed when the context provider * // isn't a parent component. the following are the defaults * // createHoverModeContext({ * // hoverTimeout: undefined, * // leaveTimeout: 0, * // defaultActiveId: "", * // }) * ); * const { Provider } = context; * * interface Props extends HoverModeConfiguration { * children: ReactNode; * } * * export function CustomHoverModeProvider({ * children, * // change to whatever defaults you want * hoverTimeout = 3000, * leaveTimeout = 3000, * defaultActiveId = "", * disableTimeout = 5000, * }: Props): ReactElement { * const context = useHoverModeProvider({ * hoverTimeout, * leaveTimeout, * defaultActiveId, * disableTimeout, * }); * * return {children}; * } * ``` * * @see {@link CreateHoverModeContextOptions} * @see {@link useHoverMode} * @since 6.0.0 The `HoverModeProvider` component was replaced by this * hook implementation. After developing the `MenuBar`, I realized the hover * mode should normally be grouped by related components or types instead of a * top-level catch all. */ export declare function useHoverModeProvider(options: HoverModeConfiguration): Readonly;