# All files / src/menu useMenuBarProvider.ts

100% Statements 88/88
100% Branches 6/6
100% Functions 2/2
100% Lines 88/88

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    891x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    978x
    978x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    213x
    213x
    213x
    213x
    213x
    213x
    213x
    213x
    213x
    213x
    213x
    180x
    180x
    180x
    180x
    213x
    213x
    213x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    213x
    213x
    213x
     "use client";
    import { createContext, useContext, useMemo } from "react";
    import type { HoverModeContext } from "../hoverMode/useHoverModeProvider.js";
    import {
      createHoverModeContext,
      useHoverModeProvider,
    } from "../hoverMode/useHoverModeProvider.js";

    /**
     * @internal
     * @remarks \@since 5.0.0
     * @remarks \@since 6.0.0 Updated to use the new `HoverModeContext` behavior.
     */
    export interface MenuBarContext extends HoverModeContext {
      root: boolean;
      menubar: boolean;
      menuitem: boolean;
    }

    const context = createContext<MenuBarContext>({
      ...createHoverModeContext(),
      root: false,
      menubar: false,
      menuitem: false,
    });
    context.displayName = "MenuBar";

    /**
     * @internal
     * @remarks \@since 6.0.0
     */
    export const { Provider: MenuBarProvider } = context;

    /**
     * @internal
     * @remarks \@since 5.0.0
     */
    export function useMenuBarContext(): Readonly<MenuBarContext> {
      return useContext(context);
    }

    /**
     * @internal
     * @remarks \@since 6.0.0
     */
    export interface MenuBarProviderOptions {
      root: boolean;
      menubar: boolean;
      hoverTimeout: number | undefined;

      /** @defaultValue `""` */
      defaultActiveId?: string;
    }

    /**
     * @internal
     * @remarks \@since 6.0.0
     */
    export function useMenuBarProvider(
      options: MenuBarProviderOptions
    ): Readonly<MenuBarContext> {
      const { hoverTimeout, root, menubar, defaultActiveId = "" } = options;

      const hoverMode = useHoverModeProvider({
        hoverTimeout,
        forceRerender: true,
        defaultActiveId,
      });

      if (defaultActiveId) {
        // without this "fix", first-level nested dropdown menus will only disable
        // the animation the first time they are shown.
        hoverMode.animatedOnceRef.current = true;
      }

      return useMemo<MenuBarContext>(
        () => ({
          // when not within a menubar, disable all the hover mode functionality by
          // creating an empty hover mode context. This makes it so nested dropdown
          // menus don't trigger the hover mode timeouts and behavior
          ...(menubar ? hoverMode : createHoverModeContext()),
          root,
          menubar,
          menuitem: true,
        }),
        [hoverMode, menubar, root]
      );
    }