# All files / src/interaction useHigherContrastChildren.tsx

100% Statements 90/90
100% Branches 9/9
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
    2159x
    2159x
    2159x
    2159x
    334x
    334x
    1825x
    1825x
    1825x
    1825x
    2140x
    2140x
    1611x
    1611x
    529x
    529x
    529x
    1825x
     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 INTERACTION_CONFIG.higherContrast} is set to `false`, 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;
      });
    }