57 lines
2.0 KiB
TypeScript
57 lines
2.0 KiB
TypeScript
import { Children, useEffect, useRef, useState, type ReactNode } from "react";
|
|
import "./wisch-reihe.css";
|
|
|
|
type WischReiheProps = {
|
|
/** Beschreibung für Screenreader, z. B. „Vier Leistungen, seitlich wischen“ */
|
|
ariaLabel: string;
|
|
children: ReactNode;
|
|
className?: string;
|
|
/** Zähler „2 / 4“ unter der Reihe anzeigen (Standard: ja) */
|
|
zaehler?: boolean;
|
|
};
|
|
|
|
/**
|
|
* Horizontale Wisch-Reihe für Handys (Spezifikation 9.4): natives Scroll-Snap ohne Bibliothek,
|
|
* die nächste Karte ist angeschnitten sichtbar, darunter ein Zähler. Keine automatische Bewegung.
|
|
* Ab 900 px entscheidet der Abschnitt selbst, ob er die Reihe überhaupt zeigt.
|
|
*/
|
|
const WischReihe = ({ ariaLabel, children, className, zaehler = true }: WischReiheProps) => {
|
|
const karten = Children.toArray(children);
|
|
const reiheRef = useRef<HTMLUListElement>(null);
|
|
const [aktiv, setAktiv] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const reihe = reiheRef.current;
|
|
if (!reihe || typeof IntersectionObserver === "undefined") return;
|
|
const beobachter = new IntersectionObserver(
|
|
(eintraege) => {
|
|
for (const e of eintraege) {
|
|
if (e.isIntersecting) setAktiv(Number((e.target as HTMLElement).dataset.index));
|
|
}
|
|
},
|
|
{ root: reihe, threshold: 0.6 },
|
|
);
|
|
reihe.querySelectorAll<HTMLElement>(":scope > li").forEach((li) => beobachter.observe(li));
|
|
return () => beobachter.disconnect();
|
|
}, [karten.length]);
|
|
|
|
return (
|
|
<div className={`wk-wisch${className ? ` ${className}` : ""}`}>
|
|
<ul ref={reiheRef} className="wk-wisch__reihe" role="list" tabIndex={0} aria-label={ariaLabel}>
|
|
{karten.map((karte, i) => (
|
|
<li key={i} className="wk-wisch__karte" data-index={i}>
|
|
{karte}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
{zaehler && karten.length > 1 && (
|
|
<p className="wk-wisch__zaehler wk-num" aria-hidden>
|
|
{aktiv + 1} / {karten.length}
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default WischReihe;
|