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 | ReactElement;
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" style={props.style}>
<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;
|