feature/spoiler-flag (#25)
Some checks failed
CI / Check / Test (push) Has been cancelled

Reviewed-on: #25
This commit was merged in pull request #25.
This commit is contained in:
2026-10-25 18:52:11 +00:00
parent 9dd9df1f73
commit 4f3d99ec8e
66 changed files with 502 additions and 168 deletions

View File

@@ -0,0 +1,43 @@
import { useState } from "react"
import { useTranslation } from "react-i18next"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
type SpoilerVeilProps = {
content: string
/** Layout classes for the veiled text (line clamps, sizing, color). */
className?: string
}
/**
* Hides review text behind a blur with a reveal button — shown to every
* viewer, the author included. Once revealed, the text stays visible.
*/
export function SpoilerVeil({ content, className }: SpoilerVeilProps) {
const { t } = useTranslation()
const [revealed, setRevealed] = useState(false)
if (revealed) {
return <span className={cn("block whitespace-pre-wrap", className)}>{content}</span>
}
return (
<span className="relative block" aria-label={t("review.containsSpoilers")}>
<span
aria-hidden="true"
className={cn("pointer-events-none block select-none blur-[5px]", className)}
>
{content}
</span>
<Button
type="button"
variant="secondary"
size="sm"
className="absolute inset-y-0 left-0 h-6 self-center px-2 text-[10px]"
onClick={() => setRevealed(true)}
>
{t("review.showSpoilers")}
</Button>
</span>
)
}