# All files / src/components tile.tsx

100% Statements 6/6
90.9% Branches 10/11
100% Functions 2/2
100% Lines 6/6

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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121

    7x
    2x

    7x

    2x
    2x

    2x

     import {
      type CSSProperties,
      type FC,
      type HTMLAttributes,
      type PropsWithChildren,
      type ReactElement,
      type ReactNode,
    } from 'react';
    import cn from 'classnames';

    import type { HeadingLevels } from '../types/common';

    import '../styles/components/tile.scss';

    type Props = {
      /**
       * The tile title
       */
      title: ReactNode;
      /**
       * The tile title heading level
       */
      headingLevel?: Exclude<HeadingLevels, 'h6'>;
      /**
       * The tile subtitle
       */
      subtitle?: ReactNode;
      /**
       * The background color
       */
      backgroundColor?: string;
      /**
       * The background image
       */
      backgroundImage?: ReactNode;
      /**
       * Whether to create a gradient based on the backgroung color or not
       */
      gradient?: boolean;
      /**
       * The width Tile square (css value). By default it will use the
       * width of the provided container.
       */
      width?: string;
      /**
       * Whether to slide up the description when the mouse is over the tile.
       * Can be useful if the description text is long.
       */
      descriptionSlideUp?: boolean;
      /**
       * Target/link of the list item when clicking on it
       */
      link?: ReactElement<{ [key: string]: unknown }>;
    };

    const nextHeading = (level: Exclude<HeadingLevels, 'h6'>): HeadingLevels =>
      `h${+level[1] + 1}` as HeadingLevels;

    export const Tile: FC<
      PropsWithChildren<Props> & HTMLAttributes<HTMLDivElement>
    > = ({
      title,
      headingLevel = 'h2',
      subtitle,
      backgroundColor,
      backgroundImage,
      gradient = false,
      width,
      className,
      style,
      children,
      descriptionSlideUp = false,
      link,
    }) => {
      const TitleHeadingLevel = headingLevel;
      const SubtitleHeadingLevel = nextHeading(headingLevel);

      return (
        <div
          className={cn(className, 'tile', {
            'tile-gradient': gradient,
            'tile--has-link': link,
          })}
          style={
            {
              ...style,
              '--tile-background': backgroundColor,
              width,
            } as CSSProperties
          }
        >
          {link && <link.type {...link.props} aria-hidden="true" tabIndex={-1} />}
          <div className="tile__background-image" aria-hidden="true">
            {backgroundImage}
          </div>
          <div className="tile__main-content">
            <TitleHeadingLevel className="tile__header big">
              {title}
            </TitleHeadingLevel>
            {subtitle && (
              <SubtitleHeadingLevel className="tile__subtitle small">
                {subtitle}
              </SubtitleHeadingLevel>
            )}
          </div>
          {children && (
            <small
              className={cn(
                'tile__description',
                descriptionSlideUp && 'tile__description--animated'
              )}
            >
              {children}
            </small>
          )}
        </div>
      );
    };

    export default Tile;