Examples
The Action component can catch the in-view and out-of-view events emitted by InView with its data-on:<event> attributes, because $emit dispatches them as native CustomEvents on the component's root element. Mounting both components on the same element (data-component="Action InView") is all it takes to react to viewport crossings declaratively. No custom JavaScript class is required.
Reveal on scroll
Each card carries both Action and InView. When it enters the viewport, InView emits in-view and the Action adds the is-visible class; when it leaves, out-of-view removes it again. Because InView re-fires on every crossing, the reveal replays each time you scroll a card back into view. The animation itself is plain CSS driven by the is-visible class.
Playing a Transition on scroll
For a more capable reveal, share the element with the Transition component and let the Action drive it: in-view plays Transition.enter() and out-of-view plays Transition.leave(). The enter/leave states are described with the usual data-option-enter-* / data-option-leave-* attributes, and data-option-enter-keep / data-option-leave-keep hold the final state between crossings.
TIP
The Action component can also target a sibling component instead of one mounted on the same element, using its Name(#selector) -> target.method() syntax. For example, data-on:in-view="Transition(#panel) -> target.enter()" lets an InView element play the enter() method of the Transition with the panel id.
Custom threshold and root margin
The intersectionObserver option is forwarded to the underlying IntersectionObserver, so you can tune when the crossing is detected. A negative rootMargin delays in-view until the element is comfortably inside the viewport:
<div
data-component="Action InView"
data-option-intersection-observer='{ "rootMargin": "-15% 0px" }'
data-on:in-view="$el.classList.add('is-visible')">
…
</div>