# All files / card ClickableCard.tsx

100% Statements 105/105
100% Branches 13/13
100% Functions 4/4
100% Lines 105/105

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
    1061x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    4x
    4x
    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
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    3x
    1x
    1x
    2x
    2x
    2x
    5x
    4x
    4x
    2x
    2x
    2x
    2x
    4x
    2x
    1x
    1x
    2x
    2x
    2x
    4x
    5x
    5x
    5x
    5x
    5x
    5x
    1x
     "use client";
    import { cnb } from "cnbuilder";
    import { forwardRef, type MouseEventHandler } from "react";
    import { useElementInteraction } from "../interaction/useElementInteraction.js";
    import { useHigherContrastChildren } from "../interaction/useHigherContrastChildren.js";
    import { Card, type CardProps } from "./Card.js";

    const noop = (): void => {
      // do nothing
    };

    /**
     * @remarks \@since 6.0.0
     */
    export interface ClickableCardProps extends CardProps {
      onClick: MouseEventHandler<HTMLDivElement>;

      /**
       * Set this to `true` to disable all click events.
       *
       * Note: Any disabled styling will need to be manually applied.
       *
       * @defaultValue `false`
       */
      disabled?: boolean;
    }

    /**
     * A Small wrapper around the `Card` component that is clickable and has the
     * element interaction enabled (ripples).
     *
     * @example
     * SImple Example
     * ```tsx
     * import { CardContent, ClickableCard } from "@react-md/core";
     * import { type ReactElement } from "react";
     *
     * export default function ClickableCardExample(): ReactElement {
     *   return (
     *     <ClickableCard
     *       onClick={() => {
     *         // do something
     *       }}
     *     >
     *       <CardContent>Wow</CardContent>
     *     </ClickableCard>
     *   );
     * }
     * ```
     *
     * @remarks \@since 6.0.0
     */
    export const ClickableCard = forwardRef<HTMLDivElement, ClickableCardProps>(
      function ClickableCard(props, ref) {
        const {
          role = "button",
          disabled,
          tabIndex = disabled ? undefined : 0,
          onClick,
          onKeyDown = noop,
          className,
          children: propChildren,
          ...remaining
        } = props;
        const { handlers, ripples } = useElementInteraction(remaining);
        const children = useHigherContrastChildren(propChildren);

        return (
          <Card
            {...remaining}
            {...handlers}
            aria-disabled={disabled || undefined}
            ref={ref}
            role={role}
            tabIndex={tabIndex}
            className={cnb("rmd-card--clickable", className)}
            onClick={(event) => {
              if (disabled) {
                return;
              }

              onClick(event);
            }}
            onKeyDown={(event) => {
              onKeyDown(event);
              if (disabled) {
                return;
              }

              const isSpace = event.key === " ";
              if (isSpace || event.key === "Enter") {
                if (isSpace) {
                  event.preventDefault();
                }

                event.currentTarget.click();
              }
            }}
          >
            {children}
            {ripples}
          </Card>
        );
      }
    );