87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import type { Mod } from "@/data/content";
|
|
import "../styles/mods.css";
|
|
|
|
type Props = {
|
|
mod: Mod;
|
|
visible?: boolean;
|
|
};
|
|
|
|
/** One mod: the list item card inside a game's mod list. */
|
|
export default function ModCard({ mod, visible = true }: Props) {
|
|
const [hovered, setHovered] = useState(false);
|
|
|
|
return (
|
|
<a
|
|
className="mod-card"
|
|
href={mod.link}
|
|
target="_blank"
|
|
rel="noreferrer noopener"
|
|
onMouseEnter={() => setHovered(true)}
|
|
onMouseLeave={() => setHovered(false)}
|
|
style={{
|
|
background: hovered ? "var(--surface-hover)" : "var(--surface)",
|
|
border: `1px solid ${hovered ? "var(--accent)" : "var(--border)"}`,
|
|
transform: visible ? (hovered ? "translateY(-2px)" : "none") : "translateY(8px)",
|
|
opacity: visible ? 1 : 0,
|
|
boxShadow: hovered ? "var(--shadow-md)" : "none",
|
|
}}
|
|
>
|
|
<div className="mod-card-head">
|
|
<span
|
|
className="mod-card-title"
|
|
style={{ color: hovered ? "var(--accent)" : "var(--fg)" }}
|
|
>
|
|
{mod.title}
|
|
</span>
|
|
|
|
{mod.version && <span className="mod-card-version">v{mod.version}</span>}
|
|
</div>
|
|
|
|
<p className="mod-card-description">{mod.description}</p>
|
|
|
|
<div className="mod-card-foot">
|
|
{mod.tags && mod.tags.length > 0 && (
|
|
<div className="mod-card-tags">
|
|
{mod.tags.map((tag) => (
|
|
<span key={tag} className="mod-tag">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<span
|
|
className="mod-card-link"
|
|
style={{
|
|
borderColor: hovered ? "var(--accent)" : "var(--border)",
|
|
color: hovered ? "var(--accent)" : "var(--fg-secondary)",
|
|
}}
|
|
>
|
|
{mod.linkLabel ?? "Repository"}
|
|
<svg
|
|
width="11"
|
|
height="11"
|
|
viewBox="0 0 14 14"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
aria-hidden="true"
|
|
>
|
|
<path d="M5 1h8v8" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
<path d="M13 1L6 8" strokeWidth="1.5" strokeLinecap="round" />
|
|
<path
|
|
d="M11 9v4H1V3h4"
|
|
strokeWidth="1.5"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
</div>
|
|
</a>
|
|
);
|
|
}
|