Attach visible(handler) with use:ref and the handler fires with
each IntersectionObserverEntry change. The second argument is
forwarded to IntersectionObserver as the options bag (root,
rootMargin, threshold), plus a pota-specific once: when true,
the handler fires once on the first entry where isIntersecting is
true and later entries are ignored — handy for reveal-on-scroll
styles that only need to flip a class once. It is the declarative
use:ref form of onVisible. Part of
pota/use/intersection.
| Argument | Type | Description |
|---|---|---|
handler |
(entry: IntersectionObserverEntry) => void |
Called with each real intersection change. |
opts |
IntersectionObserverInit & { once?: boolean } |
Optional. root / rootMargin / threshold, plus once to fire only on first arrival. |
Returns: a ref function (node: Element) => void for use:ref.
Flips each card's background the first time it scrolls into view. The
handler writes a signal on intersection and the reactive style value
reads it back.
import { render, signal } from 'pota'
import { visible } from 'pota/use/intersection'
function Card({ index }) {
const seen = signal(false)
return (
<div
use:ref={visible(
entry => entry.isIntersecting && seen.write(true),
)}
style={{
height: '40vh',
margin: '2rem 0',
background: () => (seen.read() ? 'mediumseagreen' : '#222'),
color: 'white',
display: 'grid',
'place-items': 'center',
}}
>
card #{index} —{' '}
{() => (seen.read() ? 'in view' : 'scroll me into view')}
</div>
)
}
render(
<div>
{[1, 2, 3, 4].map(i => (
<Card index={i} />
))}
</div>,
)