You can use our useInView
hook which uses the Intersection Observer underneath.
You have to install @frontity/hooks
in your project and then import it using:
import useInView from "@frontity/hooks/use-in-view";
It returns an array with
- A boolean variable that is
true
when the HTML enters the screen and false
when it leaves
- A ref to attach to the HTML element that you want to use to control the boolean variable.
You can pass an object of options with the rootMargin
that will be passed down to the intersection observer and an onlyOnce
property in case you want it to trigger only the first time (it never goes back to false
).
In your case, you can create a ClientIntro
component that uses an action to set some part to the state to a certain value when it enters the screen.
Create the state and the action:
export default {
state: {
theme: {
// other state...
clientOnScreen: false
}
},
actions: {
theme: {
setClientOnScreen: ({ state }) => isVisible => {
state.theme.clientOnScreen = isVisible;
}
}
}
}
Create the component that triggers the change:
const ClientIntro = ({ actions, children }) => {
const [isVisible, scrollRef] = useInView({
rootMargin: "100px",
onlyOnce: false
});
// When isVisible changes, we trigger an action to update the state.
React.useEffect(() => {
actions.theme.setClientOnScreen(isVisible);
}, [isVisible]);
return (
<div ref={scrollRef}>
{children}
</div>
);
};
export default connect(ClientIntro);
Finally, consume the state somewhere else in your app:
const BorderContainer = ({ state, children }) => (
<Border isVisible={state.theme.isVisible}>
{children}
</Border>
);
export default connect(BorderContainer);
const Border = styled.button`
color: ${props => props.isVisible ? "red" : "blue";
`
I have no idea how to create a border around the in-browser-view (I’m really bad with CSS!) so I wrote the example with a normal button, but I hope you get the idea. Maybe someone else can help with that