# All files / menu MenuVisibilityProvider.tsx

97.89% Statements 93/95
100% Branches 3/3
66.66% Functions 2/3
97.89% Lines 93/95

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
    961x
    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
    135x
    135x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    135x
    135x
    135x
    135x
    135x
    135x
    135x
    68x
    68x
    68x
    68x
    135x
    135x
    135x
    135x
    135x
     "use client";
    import {
      createContext,
      useContext,
      useMemo,
      type ReactElement,
      type ReactNode,
    } from "react";
    import { type NonNullMutableRef, type UseStateObject } from "../types.js";

    /**
     * @remarks
     * \@since 5.0.0
     * \@since 6.0.0 Added the `defaultFocusIndex` ref.
     */
    export interface MenuVisibilityContext
      extends UseStateObject<"visible", boolean> {
      defaultFocusIndex: NonNullMutableRef<number>;
    }

    /**
     * @internal
     * @remarks \@since 5.0.0
     */
    const context = createContext<MenuVisibilityContext>({
      visible: false,
      setVisible() {
        throw new Error('"MenuVisibilityProvider" must be a parent component');
      },
      defaultFocusIndex: { current: 0 },
    });
    context.displayName = "MenuVisibility";

    /**
     * @internal
     * @remarks \@since 5.0.0
     */
    const { Provider } = context;

    /**
     * This hook allows you control the visibility of a parent menu. The main
     * use-case for this hook is adding a custom sheet header/footer.
     *
     * @example
     * Simple Example
     * ```tsx
     * function SheetFooter(): ReactElement {
     *   const { setVisible } = useMenuVisibility();
     *
     *   return (
     *     <DialogFooter>
     *       <Button onClick={() => setVisible(false)}>Cancel</Button>
     *     </DialogFooter>
     *   );
     * }
     * ```
     *
     * @returns the {@link MenuVisibilityContext}
     * @remarks \@since 5.0.0
     */
    export function useMenuVisibility(): Readonly<MenuVisibilityContext> {
      return useContext(context);
    }

    /**
     * @internal
     * @remarks \@since 5.0.0
     */
    export interface MenuVisibilityProviderProps extends MenuVisibilityContext {
      children: ReactNode;
    }

    /**
     * **Client Component**
     *
     * @internal
     * @remarks \@since 5.0.0
     */
    export function MenuVisibilityProvider({
      visible,
      setVisible,
      defaultFocusIndex,
      children,
    }: MenuVisibilityProviderProps): ReactElement {
      const value = useMemo<MenuVisibilityContext>(
        () => ({
          visible,
          setVisible,
          defaultFocusIndex,
        }),
        [visible, setVisible, defaultFocusIndex]
      );

      return <Provider value={value}>{children}</Provider>;
    }