# All files useHigherContrastChildren.tsx

100% Statements 90/90
100% Branches 8/8
100% Functions 1/1
100% Lines 90/90

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
    911x
    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
    1x
    1850x
    1850x
    1850x
    1850x
    328x
    328x
    1522x
    1522x
    1522x
    1522x
    1638x
    1638x
    1324x
    1324x
    314x
    314x
    314x
    1522x
     import { Children, type ReactNode } from "react";
    import { INTERACTION_CONFIG } from "./config.js";

    /**
     * This hook is used to wrap any `number` and `string` children with a `<span>`
     * so that the ripple/hover/focus background colors do not cause the text to
     * become dimmed.
     *
     * If the {@link ElementInteractionProviderProps.disableHigherContrast} is set
     * to `true`, this hook will just return the `children` unmodified.
     *
     * Note: This should generally be used with the {@link useElementInteraction}
     * hook.
     *
     * @example
     * Simple Example
     * ```tsx
     * import {
     *   useElementInteraction,
     *   useHigherContrastChildren,
     * } from "@react-md/core";
     * import type { ButtonHTMLAttributes, ReactElement, ReactNode } from "react";
     *
     * function Example(props: ButtonHTMLAttributes<HTMLButtonElement>): ReactElement {
     *   const {
     *     children: propChildren,
     *     disabled = false,
     *     onClick,
     *     onKeyDown,
     *     onKeyUp,
     *     onMouseDown,
     *     onMouseUp,
     *     onMouseLeave,
     *     onTouchStart,
     *     onTouchEnd,
     *     onTouchMove,
     *     ...remaining
     *   } = props;
     *   const { pressedClassName, ripples, handlers } =
     *     useElementInteraction({
     *       disabled,
     *       onClick,
     *       onKeyDown,
     *       onKeyUp,
     *       onMouseDown,
     *       onMouseUp,
     *       onMouseLeave,
     *       onTouchStart,
     *       onTouchEnd,
     *       onTouchMove,
     *     });
     *
     *   const children = useHigherContrastChildren(propChildren)
     *
     *   return (
     *     <button {...remaining} {...handlers} className={pressedClassName}>
     *       {children}
     *       {ripples}
     *     </button>
     *   );
     * }
     * ```
     *
     * @param propChildren - The children to conditionally wrap in spans.
     * @param disable - Manually disable this functionality even if the higher
     * contrast mode is enabled. This is really used within `ListItem`s so there
     * aren't unneeded `<span>`s for string/number children when there are addons.
     * @returns the children to render
     * @remarks \@since 6.0.0
     * @internal
     */
    export function useHigherContrastChildren(
      propChildren: ReactNode,
      disable = false
    ): ReactNode {
      if (!INTERACTION_CONFIG.higherContrast || disable) {
        return propChildren;
      }

      // Note: This will fail if the child is wrapped in a Fragment, but that use
      // case doesn't matter to me
      return Children.map(propChildren, (child) => {
        const t = typeof child;
        if (t === "string" || t === "number") {
          return <span>{child}</span>;
        }

        return child;
      });
    }