All files / src/components EventCoverImage.tsx

82.22% Statements 37/45
50% Branches 3/6
75% Functions 3/4
82.22% Lines 37/45

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 661x 1x   37x 37x 37x 37x 37x 37x 37x   37x 37x 37x 37x 37x 37x 37x 37x 37x 37x 37x 37x 37x   37x   37x 37x 37x                       1x 37x 37x   37x 37x 37x 37x 37x   37x 37x   37x                      
import { useState } from 'react';
import './EventCoverImage.css';
 
function MountainMark() {
  return (
    <svg
      className="event-cover-mountain-svg"
      viewBox="0 0 80 56"
      aria-hidden
      focusable="false"
    >
      <path
        className="event-cover-mountain-sun"
        d="M58 8a6 6 0 1 1-12 0 6 6 0 0 1 12 0z"
      />
      <path
        className="event-cover-mountain-back"
        d="M8 52 L32 18 L52 52 H8 Z"
      />
      <path
        className="event-cover-mountain-front"
        d="M28 52 L44 28 L72 52 H28 Z"
      />
    </svg>
  );
}
 
function hasUsableSrc(src: string | null | undefined): boolean {
  return typeof src === 'string' && src.trim().length > 0;
}
 
type Variant = 'card' | 'hero';
 
export interface EventCoverImageProps {
  src: string | null | undefined;
  alt: string;
  /** Applied to the real `<img>` when shown */
  imgClassName: string;
  variant: Variant;
}
 
export function EventCoverImage({ src, alt, imgClassName, variant }: EventCoverImageProps) {
  const [failed, setFailed] = useState(false);
  const show = hasUsableSrc(src) && !failed;
 
  if (!show) {
    return (
      <div
        className={`event-cover-placeholder event-cover-placeholder--${variant}`}
        aria-hidden
      >
        <MountainMark />
      </div>
    );
  }
 
  return (
    <img
      src={src!.trim()}
      alt={alt}
      className={imgClassName}
      onError={() => setFailed(true)}
    />
  );
}