All files / Rindu/components/PresentationCard PresentationCard.tsx

100% Statements 8/8
54.54% Branches 6/11
100% Functions 1/1
100% Lines 7/7

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    19x   19x                                                 16x 16x     16x 16x                                                                                                                                                           19x  
import { HTMLAttributes, ReactElement } from "react";
 
import { CardContent, PlayButton } from "components";
import { CardType } from "components/CardContent";
import { useAuth, useSpotify } from "hooks";
import { ITrack } from "types/spotify";
 
export interface PresentationCardProps {
  type: CardType;
  id: string;
  images?: SpotifyApi.ImageObject[];
  title: string;
  subTitle: string | JSX.Element;
  track?: ITrack;
  isSingle?: boolean;
  url?: string;
}
 
function PresentationCard({
  images,
  title,
  subTitle,
  id,
  type,
  isSingle,
  track,
  url,
  ...props
}: PresentationCardProps & HTMLAttributes<HTMLAnchorElement>): ReactElement {
  const unsupportedUris = ["genre", "user"];
  const uri = unsupportedUris.includes(type ?? "")
    ? undefined
    : `spotify:${type || "track"}:${id}`;
  const { isPremium } = useAuth();
  const { allTracks } = useSpotify();
 
  return (
    <div className="container">
      <CardContent
        id={id}
        type={type}
        images={images}
        title={title}
        subTitle={subTitle}
        url={url}
        tabIndex={props.tabIndex}
        aria-hidden={props["aria-hidden"]}
      />
      <span>
        {!url && (
          <PlayButton
            uri={uri}
            track={track}
            isSingle={isSingle}
            centerSize={24}
            size={48}
            tabIndex={props.tabIndex}
            aria-hidden={props["aria-hidden"]}
            allTracks={allTracks}
          />
        )}
      </span>
      <style jsx>{`
        .container {
          --card-container-border-radius: clamp(
            4px,
            (var(--left-panel-width, 0px) - 32px) * 0.025,
            8px
          );
          color: inherit;
          cursor: pointer;
          border: none;
          background: unset;
          margin: 0;
          padding: 0;
          text-decoration: none;
          position: relative;
          background-color: #181818;
          transition: background-color 0.25s ease;
          border-radius: calc(var(--card-container-border-radius) + 2px);
          scroll-snap-align: start;
        }
        span {
          position: absolute;
          bottom: 100px;
          right: 24px;
          transition: all 0.25s ease;
          opacity: 0;
          display: ${!isPremium || !uri ? "none" : "flex"};
          z-index: 2;
        }
        .container:hover,
        .container:focus-within {
          background-color: #282828;
        }
        .container:focus-within span,
        .container:hover span {
          transform: translateY(-8px);
          opacity: 1;
        }
        @media screen and (max-width: 768px) {
          .container,
          .container:hover,
          .container:focus-within {
            background: transparent;
          }
        }
      `}</style>
    </div>
  );
}
 
export default PresentationCard;