# All files / src/menu MenuItem.tsx

100% Statements 69/69
60% Branches 3/5
100% Functions 1/1
100% Lines 69/69

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
    701x
    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
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    20x
    20x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    252x
    1x
     "use client";
    import { cnb } from "cnbuilder";
    import { forwardRef } from "react";
    import { ListItem, type ListItemProps } from "../list/ListItem.js";
    import { useKeyboardMovementContext } from "../movement/useKeyboardMovementProvider.js";
    import { useEnsuredId } from "../useEnsuredId.js";

    /**
     * @remarks \@since 5.0.0
     */
    export interface MenuItemProps extends Omit<ListItemProps, "role"> {
      /**
       * @defaultValue `"menuitem"`
       */
      role?: string;

      /**
       * @defaultValue `-1`
       */
      tabIndex?: number;
    }

    /**
     * **Client Component**
     *
     * This component is used as an "action" within a `Menu`/`DropdownMenu` that
     * implements some keyboard focus behavior. This component should generally have
     * an `onClick` event handler.
     *
     * @remarks \@since 5.0.0
     */
    export const MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(
      function MenuItem(props, ref) {
        const {
          id: propId,
          role = "menuitem",
          tabIndex: propTabIndex,
          children,
          className,
          ...remaining
        } = props;

        const id = useEnsuredId(propId, "menuitem");
        const { tabIndexBehavior, activeDescendantId } =
          useKeyboardMovementContext();
        const focused = id === activeDescendantId;
        let tabIndex = propTabIndex ?? -1;
        if (tabIndexBehavior === "roving" && focused) {
          tabIndex = 0;
        }

        return (
          <ListItem
            {...remaining}
            id={id}
            ref={ref}
            role={role}
            tabIndex={tabIndex}
            className={cnb(
              "rmd-menu-item",
              tabIndexBehavior === "virtual" && focused && "rmd-menu-item--focused",
              className
            )}
          >
            {children}
          </ListItem>
        );
      }
    );