# All files / src/menu MenuBar.tsx

100% Statements 119/119
100% Branches 3/3
100% Functions 2/2
100% Lines 119/119

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
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    1201x
    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
    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
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    12x
    4x
    4x
    12x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    33x
    1x
     "use client";
    import { forwardRef } from "react";
    import { List, type ListProps } from "../list/List.js";
    import {
      KeyboardMovementProvider,
      useKeyboardMovementProvider,
    } from "../movement/useKeyboardMovementProvider.js";
    import { MenuBarProvider, useMenuBarProvider } from "./useMenuBarProvider.js";

    export interface MenuBarProps extends Omit<ListProps, "role"> {
      /**
       * @defaultValue `true`
       */
      horizontal?: boolean;

      /**
       * Set this to a number greater than 0 to allow opening dropdown menus within
       * the menubar after hovering for the duration in milliseconds. Once a menu
       * becomes visible within the menubar, all subsequent menus will become
       * visible immediately on hover as well until the hover mode is ended.
       *
       * For example:
       *
       * - `0` - the dropdown menus become visible immediately on hover
       * - `1000` - the first dropdown menu becomes visible after hovering for 1
       *   second
       * - `undefined` - the hover mode can only be activate after a click with
       *   mouse, touch, or keyboard
       *
       * @defaultValue `undefined`
       */
      hoverTimeout?: number;
    }

    /**
     * **Client Component**
     *
     * @example
     * Simple Example
     * ```tsx
     * import { DropdownMenu, MenuBar, MenuItem } from "@react-md/core";
     * import type { ReactElement } from "react";
     *
     * export function SimpleExample(): ReactElement {
     *   return (
     *     <MenuBar>
     *       <DropdownMenu buttonChildren="Item 1">
     *         <MenuItem>Menu Item 1</MenuItem>
     *         <MenuItem>Menu Item 2</MenuItem>
     *         <MenuItem>Menu Item 3</MenuItem>
     *       </DropdownMenu>
     *       <DropdownMenu buttonChildren="Item 2">
     *         <MenuItem>Menu Item 1</MenuItem>
     *         <MenuItem>Menu Item 2</MenuItem>
     *         <MenuItem>Menu Item 3</MenuItem>
     *       </DropdownMenu>
     *       <DropdownMenu buttonChildren="Item 3">
     *         <MenuItem>Menu Item 1</MenuItem>
     *         <MenuItem>Menu Item 2</MenuItem>
     *         <MenuItem>Menu Item 4</MenuItem>
     *       </DropdownMenu>
     *     </MenuBar>
     *   );
     * }
     * ```
     *
     * @remarks \@since 5.0.0
     * @remarks \@since 6.0.0 Combined with the previous `MenuBarWidget`
     */
    export const MenuBar = forwardRef<HTMLUListElement, MenuBarProps>(
      function MenuBar(props, ref) {
        const {
          onClick,
          onFocus,
          onKeyDown,
          horizontal = true,
          hoverTimeout,
          children,
          ...remaining
        } = props;
        const menuBarContext = useMenuBarProvider({
          root: true,
          menubar: true,
          hoverTimeout,
        });
        const { activeId, enableHoverMode } = menuBarContext;
        const { movementProps, movementContext } = useKeyboardMovementProvider({
          onClick,
          onFocus,
          onKeyDown,
          loopable: true,
          searchable: true,
          horizontal,
          includeDisabled: true,
          tabIndexBehavior: "roving",
          onFocusChange(event) {
            if (activeId) {
              enableHoverMode(event.element.id);
            }
          },
        });

        return (
          <KeyboardMovementProvider value={movementContext}>
            <MenuBarProvider value={menuBarContext}>
              <List
                {...remaining}
                {...movementProps}
                ref={ref}
                role="menubar"
                horizontal={horizontal}
              >
                {children}
              </List>
            </MenuBarProvider>
          </KeyboardMovementProvider>
        );
      }
    );