72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
import { useEffect, useRef, useState } from "react";
|
|
import "./StickyBuyBar.css";
|
|
|
|
function StickyBuyBar({ label, price, onBuy, observeRef, sizes, selectedSize, onSizeChange, alwaysVisibleMobile }) {
|
|
const [visible, setVisible] = useState(false);
|
|
const sentinelRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
const target = observeRef?.current ?? sentinelRef.current;
|
|
if (!target) return;
|
|
|
|
const observer = new IntersectionObserver(
|
|
([entry]) => setVisible(!entry.isIntersecting),
|
|
{ threshold: 0 }
|
|
);
|
|
|
|
observer.observe(target);
|
|
return () => observer.disconnect();
|
|
}, [observeRef]);
|
|
|
|
const classes = [
|
|
"sticky-buy-bar",
|
|
visible && "is-visible",
|
|
alwaysVisibleMobile && "is-always-visible",
|
|
].filter(Boolean).join(" ");
|
|
|
|
const currentPrice = sizes
|
|
? sizes.find((s) => s.key === selectedSize)?.price
|
|
: price;
|
|
|
|
return (
|
|
<>
|
|
{!observeRef && <span ref={sentinelRef} aria-hidden="true" />}
|
|
<div className={classes}>
|
|
<div className="sticky-buy-bar__inner">
|
|
{sizes ? (
|
|
<div className="sticky-buy-bar__left">
|
|
<div className="sticky-buy-bar__toggle">
|
|
{sizes.map((s) => (
|
|
<button
|
|
key={s.key}
|
|
type="button"
|
|
className={`sticky-buy-bar__tab ${selectedSize === s.key ? "active" : ""}`}
|
|
onClick={() => onSizeChange(s.key)}
|
|
>
|
|
{s.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
<strong className="sticky-buy-bar__price">{currentPrice}</strong>
|
|
</div>
|
|
) : (
|
|
<div className="sticky-buy-bar__left">
|
|
<span className="sticky-buy-bar__label">{label}</span>
|
|
<strong className="sticky-buy-bar__price">{currentPrice}</strong>
|
|
</div>
|
|
)}
|
|
<button
|
|
type="button"
|
|
className="atmos-btn atmos-btn--primary atmos-btn--uppercase atmos-btn--sm"
|
|
onClick={onBuy}
|
|
>
|
|
Kaufen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default StickyBuyBar;
|