since3-website/modules/landingPage/ui/components/tools/contrast-tool.tsx
2026-09-25 18:53:25 +02:00

80 lines
2.4 KiB
TypeScript

"use client"
import { useId, useState } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { parseHex, runContrastCheck, type OutputLine } from "@/modules/landingPage/lib/tools"
import { ToolOutput } from "./tool-output"
export function ContrastTool() {
const id = useId()
const [fg, setFg] = useState("#767676")
const [bg, setBg] = useState("#ffffff")
const [lines, setLines] = useState<OutputLine[] | null>(null)
// parseHex accepts values without "#" (e.g. "1a1a1a"), but CSS doesn't —
// build the preview from the parsed RGB channels instead of the raw input
const fgRgb = parseHex(fg)
const bgRgb = parseHex(bg)
const preview =
fgRgb && bgRgb
? { color: `rgb(${fgRgb.join(" ")})`, background: `rgb(${bgRgb.join(" ")})` }
: undefined
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
setLines(runContrastCheck(fg, bg))
}
return (
<form onSubmit={onSubmit} className="grid gap-6">
<p className="text-ink-300">
Prüft, ob Text auf einem Hintergrund die WCAG-Kontrastwerte erfüllt, die
das BFSG verlangt.
</p>
<div className="grid gap-4 sm:grid-cols-[1fr_1fr_auto] sm:items-end">
<div className="grid gap-2.5">
<Label htmlFor={`${id}-fg`}>Textfarbe</Label>
<Input
id={`${id}-fg`}
value={fg}
onChange={(event) => setFg(event.target.value)}
spellCheck={false}
autoComplete="off"
className="font-mono"
/>
</div>
<div className="grid gap-2.5">
<Label htmlFor={`${id}-bg`}>Hintergrund</Label>
<Input
id={`${id}-bg`}
value={bg}
onChange={(event) => setBg(event.target.value)}
spellCheck={false}
autoComplete="off"
className="font-mono"
/>
</div>
<div
aria-hidden="true"
style={preview}
className="grid h-12 place-items-center rounded-xl border border-white/10 px-5 text-sm font-medium sm:w-24"
>
Aa
</div>
</div>
<div>
<Button type="submit" variant="solid">
Kontrast prüfen
</Button>
</div>
<ToolOutput lines={lines} placeholder="Ergebnis erscheint hier." />
</form>
)
}