@@ -20,7 +20,6 @@ viewport.
2020 - [ options.viewport] ( #optionsviewport )
2121 - [ options.{modTop, modRight, modBottom, modLeft}] ( #optionsmodtop-modright-modbottom-modleft )
2222- [ Example usage] ( #example-usage )
23- - [ Tasks] ( #tasks )
2423
2524## Motivation
2625
@@ -246,37 +245,141 @@ const [isInViewport, targetRef] = useIsInViewport({
246245## Example usage
247246
248247A CRA based example app (which is also used in the test suite) can be found under
249- [ examples/cra] ( examples/cra ) . Inline examples showcasing use-cases are below.
248+ [ examples/cra] ( examples/cra ) . Inline examples showcasing some of the use-cases are below.
250249
251250### Example 1: Element with its parent document as viewport
252251
253- As soon as at least 1px of the child element is visible in the parent document viewport,
254- ` isInViewport ` evaluates to true.
252+ As soon as at least 1px of the target ` div ` is visible in the parent document viewport,
253+ ` isInViewport ` evaluates to ` true ` .
255254
256255``` jsx
257256import React from ' react'
258- import ReactDOM from ' react-dom'
259257import useIsInViewport from ' use-is-in-viewport'
260258
261- export default function SimpleElement () {
262- const [isInViewport , childElToWatch ] = useIsInViewport ()
259+ export default function MyElement () {
260+ const [isInViewport , targetRef ] = useIsInViewport ()
263261
264262 return (
265- < div ref= {childElToWatch }>
263+ < div ref= {targetRef }>
266264 < p> {isInViewport ? ' In viewport' : ' Out of viewport' }< / p>
267265 < / div>
268266 )
269267}
270268```
271269
272- More examples coming soon...
270+ ### Example 2: Element with a custom viewport
273271
274- ## Tasks
272+ As soon as at least 1px of the target ` div ` is visible in its parent ` div ` (chosen as the parent by
273+ passing ` viewportRef ` to it), ` isInViewport ` evaluates to ` true ` .
275274
276- - [x] Setup the hook to work with CRA, codesandbox and standalone react app
277- - [x] Write the hook in a way that can be tested with Cypress
278- - [x] Setup CI
279- - [x] Increase test coverage
280- - [x] Write awesome docs!
281- - [x] Deploy example app to [ useisinviewport.zdx.cat] ( https://useisinviewport.zdx.cat/ )
282- - [x] Document the motivation and API in the readme
275+ ``` jsx
276+ import React from ' react'
277+ import useIsInViewport from ' use-is-in-viewport'
278+
279+ export default function MyElement () {
280+ const [isInViewport , targetRef , viewportRef ] = useIsInViewport ()
281+
282+ return (
283+ < div ref= {viewportRef}>
284+ < div ref= {targetRef}>
285+ < p> {isInViewport ? ' In viewport' : ' Out of viewport' }< / p>
286+ < / div>
287+ < / div>
288+ )
289+ }
290+ ```
291+
292+ ### Example 3: Using a forwarded ref for the target element
293+
294+ In some cases, the parent element might want to control the ` ref ` of some element inside your
295+ component. It is obviously up to your component to decide what element to assign the incoming ` ref ` .
296+
297+ In this example, we assign the incoming ` ref ` to the target element that we are watching for in the
298+ document viewport. To do so, we thread it through ` useIsInViewport ` hook by using the ` target `
299+ option and assining the incoming ` ref ` to it. The hook takes care of updating the incoming ` ref `
300+ such that it is completely transparent to the parent element that passed the ` ref ` in.
301+
302+ ``` jsx
303+ import React from ' react'
304+ import useIsInViewport from ' use-is-in-viewport'
305+
306+ export const RefForwardingElement = React .forwardRef (function RefForwardingElement (
307+ props ,
308+ incomingTargetRef
309+ ) {
310+ const [isInViewport , targetRef ] = useIsInViewport ({
311+ target: incomingTargetRef // thread the incoming target ref through the hook
312+ })
313+
314+ return (
315+ < div ref= {targetRef}>
316+ < p> {isInViewport ? ' In viewport' : ' Out of viewport' }< / p>
317+ < / div>
318+ )
319+ })
320+ ```
321+
322+ ### Example 4: Using a forwarded ref for the viewport element
323+
324+ Same as the previous example, but here we thread the incoming ` ref ` into the viewport element
325+ instead of the target element.
326+
327+ ``` jsx
328+ import React from ' react'
329+ import useIsInViewport from ' use-is-in-viewport'
330+
331+ export const RefForwardingElement = React .forwardRef (function RefForwardingElement (
332+ props ,
333+ incomingViewportRef
334+ ) {
335+ const [isInViewport , targetRef , viewportRef ] = useIsInViewport ({
336+ viewport: incomingViewportRef // thread the incoming viewport ref through the hook
337+ })
338+
339+ return (
340+ < div ref= {viewportRef}>
341+ < div ref= {targetRef}>
342+ < p> {isInViewport ? ' In viewport' : ' Out of viewport' }< / p>
343+ < / div>
344+ < / div>
345+ )
346+ })
347+ ```
348+
349+ ### Example 5: Tracking visibility in a custom viewport of multiple elements
350+
351+ In this example, we have a custom viewport element and we want to track whether its child ` divs ` are
352+ in viewport or not. We have also chosen to use different ` threshold ` s for the two child target
353+ ` divs ` .
354+
355+ As you might notice, we thread the ` viewport ` ref from the first call to ` useIsInViewport ` into the
356+ second call to ` useIsInViewport ` . This is because an element can only be assigned one ` ref ` . And
357+ here that element is the viewport element. Therefore, we use the transparent ` ref ` update capability
358+ of ` useIsInViewport ` (as shown in the previous examples) to wrap the viewport ` ref ` from the first
359+ call of the hook with a new one that is then passed to the viewport ` div ` .
360+
361+ ``` jsx
362+ import React from ' react'
363+ import useIsInViewport from ' use-is-in-viewport'
364+
365+ export default function MyElement () {
366+ const [isDivOneInViewport , divOneTargetRef , viewportRefToChain ] = useIsInViewport ({
367+ threshold: 50
368+ })
369+ const [isDivTwoInViewport , divTwoTargetRef , viewportRef ] = useIsInViewport ({
370+ viewport: viewportRefToChain,
371+ threshold: 75
372+ })
373+
374+ return (
375+ < div ref= {viewportRef}>
376+ < div ref= {divOneTargetRef}>
377+ < p> {isDivOneInViewport ? ' Div one In viewport' : ' Div one out of viewport' }< / p>
378+ < / div>
379+ < div ref= {divTwoTargetRef}>
380+ < p> {isDivTwoInViewport ? ' Div two in viewport' : ' Div two out of viewport' }< / p>
381+ < / div>
382+ < / div>
383+ )
384+ }
385+ ```
0 commit comments