Skip to content

Commit 7827445

Browse files
authored
Merge pull request #671 from thebuilder/feat/use-stackblitz
ci: replace codesandbox with stackblitz
2 parents f53fad6 + e33bf14 commit 7827445

File tree

2 files changed

+49
-89
lines changed

2 files changed

+49
-89
lines changed

.codesandbox/ci.json

-11
This file was deleted.

README.md

+49-78
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ to tell you when an element enters or leaves the viewport. Contains both a
1212
[Hooks](#useinview-hook), [render props](#render-props) and
1313
[plain children](#plain-children) implementation.
1414

15-
**Storybook Demo:**
16-
[https://react-intersection-observer.vercel.app](https://react-intersection-observer.vercel.app)
17-
1815
## Features
1916

2017
- 🪝 **Hooks or Component API** - With `useInView` it's easier than ever to
@@ -30,15 +27,11 @@ to tell you when an element enters or leaves the viewport. Contains both a
3027
- 💥 **Tiny bundle** - Around **~1.15kB** for `useInView` and **~1.6kB** for
3128
`<InView>`
3229

33-
## Installation
34-
35-
Install using [Yarn](https://yarnpkg.com):
30+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/thebuilder/react-intersection-observer)
3631

37-
```sh
38-
yarn add react-intersection-observer
39-
```
32+
## Installation
4033

41-
or NPM:
34+
Install the package with your package manager of choice:
4235

4336
```sh
4437
npm install react-intersection-observer --save
@@ -65,8 +58,8 @@ Assign the `ref` to the DOM element you want to monitor, and the hook will
6558
report the status.
6659

6760
```jsx
68-
import React from 'react';
69-
import { useInView } from 'react-intersection-observer';
61+
import React from "react";
62+
import { useInView } from "react-intersection-observer";
7063

7164
const Component = () => {
7265
const { ref, inView, entry } = useInView({
@@ -82,8 +75,6 @@ const Component = () => {
8275
};
8376
```
8477

85-
[![Edit useInView](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/useinview-ud2vo?fontsize=14&hidenavigation=1&theme=dark)
86-
8778
### Render props
8879

8980
To use the `<InView>` component, you pass it a function. It will be called
@@ -98,7 +89,7 @@ on `entry`, giving you access to all the details about the current intersection
9889
state.
9990

10091
```jsx
101-
import { InView } from 'react-intersection-observer';
92+
import { InView } from "react-intersection-observer";
10293

10394
const Component = () => (
10495
<InView>
@@ -113,8 +104,6 @@ const Component = () => (
113104
export default Component;
114105
```
115106

116-
[![Edit InView render props](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/inview-render-props-hvhcb?fontsize=14&hidenavigation=1&theme=dark)
117-
118107
### Plain children
119108

120109
You can pass any element to the `<InView />`, and it will handle creating the
@@ -123,19 +112,17 @@ state in your own component. Any extra props you add to `<InView>` will be
123112
passed to the HTML element, allowing you set the `className`, `style`, etc.
124113

125114
```jsx
126-
import { InView } from 'react-intersection-observer';
115+
import { InView } from "react-intersection-observer";
127116

128117
const Component = () => (
129-
<InView as="div" onChange={(inView, entry) => console.log('Inview:', inView)}>
118+
<InView as="div" onChange={(inView, entry) => console.log("Inview:", inView)}>
130119
<h2>Plain children are always rendered. Use onChange to monitor state.</h2>
131120
</InView>
132121
);
133122

134123
export default Component;
135124
```
136125

137-
[![Edit InView plain children](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/inview-plain-children-vv51y?fontsize=14&hidenavigation=1&theme=dark)
138-
139126
> **Note**<br> When rendering a plain child, make sure you keep your HTML output
140127
> semantic. Change the `as` to match the context, and add a `className` to style
141128
> the `<InView />`. The component does not support Ref Forwarding, so if you
@@ -149,7 +136,7 @@ Provide these as the options argument in the `useInView` hook or as props on the
149136
**`<InView />`** component.
150137

151138
| Name | Type | Default | Description |
152-
|------------------------|---------------------------|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
139+
| ---------------------- | ------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
153140
| **root** | `Element` | `document` | The Intersection Observer interface's read-only root property identifies the Element or Document whose bounds are treated as the bounding box of the viewport for the element which is the observer's target. If the root is `null`, then the bounds of the actual document viewport are used. |
154141
| **rootMargin** | `string` | `'0px'` | Margin around the root. Can have values similar to the CSS margin property, e.g. `"10px 20px 30px 40px"` (top, right, bottom, left). Also supports percentages, to check if an element intersects with the center of the viewport for example "-50% 0% -50% 0%". |
155142
| **threshold** | `number` or `number[]` | `0` | Number between `0` and `1` indicating the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. |
@@ -166,7 +153,7 @@ Provide these as the options argument in the `useInView` hook or as props on the
166153
The **`<InView />`** component also accepts the following props:
167154

168155
| Name | Type | Default | Description |
169-
|--------------|------------------------------------------------------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
156+
| ------------ | ---------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
170157
| **as** | `IntrinsicElement` | `'div'` | Render the wrapping element as this element. Defaults to `div`. If you want to use a custom component, please use the `useInView` hook or a render prop instead to manage the reference explictly. |
171158
| **children** | `({ref, inView, entry}) => ReactNode` or `ReactNode` | `undefined` | Children expects a function that receives an object containing the `inView` boolean and a `ref` that should be assigned to the element root. Alternatively pass a plain child, to have the `<InView />` deal with the wrapping element. You will also get the `IntersectionObserverEntry` as `entry`, giving you more details. |
172159

@@ -213,8 +200,8 @@ few ideas for how you can use it.
213200
You can wrap multiple `ref` assignments in a single `useCallback`:
214201
215202
```jsx
216-
import React, { useRef, useCallback } from 'react';
217-
import { useInView } from 'react-intersection-observer';
203+
import React, { useRef, useCallback } from "react";
204+
import { useInView } from "react-intersection-observer";
218205

219206
function Component(props) {
220207
const ref = useRef();
@@ -259,7 +246,7 @@ will emulate the real IntersectionObserver, allowing you to validate that your
259246
components are behaving as expected.
260247
261248
| Method | Description |
262-
|-----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
249+
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
263250
| `mockAllIsIntersecting(isIntersecting)` | Set `isIntersecting` on all current Intersection Observer instances. The value of `isIntersecting` should be either a `boolean` or a threshold between 0 and 1. |
264251
| `mockIsIntersecting(element, isIntersecting)` | Set `isIntersecting` for the Intersection Observer of a specific `element`. The value of `isIntersecting` should be either a `boolean` or a threshold between 0 and 1. |
265252
| `intersectionMockInstance(element)` | Call the `intersectionMockInstance` method with an element, to get the (mocked) `IntersectionObserver` instance. You can use this to spy on the `observe` and`unobserve` methods. |
@@ -285,11 +272,11 @@ Jest. Otherwise, you'll need to manually setup/reset the mocking in either the
285272
individual tests, or a [setup file](https://vitest.dev/config/#setupfiles).
286273
287274
```js
288-
import { vi, beforeEach, afterEach } from 'vitest';
275+
import { vi, beforeEach, afterEach } from "vitest";
289276
import {
290277
setupIntersectionMocking,
291278
resetIntersectionMocking,
292-
} from 'react-intersection-observer/test-utils';
279+
} from "react-intersection-observer/test-utils";
293280

294281
beforeEach(() => {
295282
setupIntersectionMocking(vi.fn);
@@ -321,7 +308,7 @@ were you actively import `react-intersection-observer/test-utils`.
321308
**test-setup.js**
322309
323310
```js
324-
import { defaultFallbackInView } from 'react-intersection-observer';
311+
import { defaultFallbackInView } from "react-intersection-observer";
325312

326313
defaultFallbackInView(true); // or `false` - whichever consistent behavior makes the most sense for your use case.
327314
```
@@ -334,21 +321,21 @@ Vitest.
334321
335322
```js
336323
module.exports = {
337-
setupFilesAfterEnv: ['react-intersection-observer/test-utils'],
324+
setupFilesAfterEnv: ["react-intersection-observer/test-utils"],
338325
};
339326
```
340327
341328
### Test Example
342329
343330
```js
344-
import React from 'react';
345-
import { screen, render } from '@testing-library/react';
346-
import { useInView } from 'react-intersection-observer';
331+
import React from "react";
332+
import { screen, render } from "@testing-library/react";
333+
import { useInView } from "react-intersection-observer";
347334
import {
348335
mockAllIsIntersecting,
349336
mockIsIntersecting,
350337
intersectionMockInstance,
351-
} from 'react-intersection-observer/test-utils';
338+
} from "react-intersection-observer/test-utils";
352339

353340
const HookComponent = ({ options }) => {
354341
const { ref, inView } = useInView(options);
@@ -359,37 +346,37 @@ const HookComponent = ({ options }) => {
359346
);
360347
};
361348

362-
test('should create a hook inView', () => {
363-
render(<HookComponent/>);
349+
test("should create a hook inView", () => {
350+
render(<HookComponent />);
364351

365352
// This causes all (existing) IntersectionObservers to be set as intersecting
366353
mockAllIsIntersecting(true);
367-
screen.getByText('true');
354+
screen.getByText("true");
368355
});
369356

370-
test('should create a hook inView with threshold', () => {
371-
render(<HookComponent options={{ threshold: 0.3 }}/>);
357+
test("should create a hook inView with threshold", () => {
358+
render(<HookComponent options={{ threshold: 0.3 }} />);
372359

373360
mockAllIsIntersecting(0.1);
374-
screen.getByText('false');
361+
screen.getByText("false");
375362

376363
// Once the threshold has been passed, it will trigger inView.
377364
mockAllIsIntersecting(0.3);
378-
screen.getByText('true');
365+
screen.getByText("true");
379366
});
380367

381-
test('should mock intersecing on specific hook', () => {
382-
render(<HookComponent/>);
383-
const wrapper = screen.getByTestId('wrapper');
368+
test("should mock intersecing on specific hook", () => {
369+
render(<HookComponent />);
370+
const wrapper = screen.getByTestId("wrapper");
384371

385372
// Set the intersection state on the wrapper.
386373
mockIsIntersecting(wrapper, 0.5);
387-
screen.getByText('true');
374+
screen.getByText("true");
388375
});
389376

390-
test('should create a hook and call observe', () => {
391-
const { getByTestId } = render(<HookComponent/>);
392-
const wrapper = getByTestId('wrapper');
377+
test("should create a hook and call observe", () => {
378+
const { getByTestId } = render(<HookComponent />);
379+
const wrapper = getByTestId("wrapper");
393380
// Access the `IntersectionObserver` instance for the wrapper Element.
394381
const instance = intersectionMockInstance(wrapper);
395382

@@ -422,7 +409,7 @@ application can correctly handle all your observers firing either `true` or
422409
You can set the fallback globally:
423410
424411
```js
425-
import { defaultFallbackInView } from 'react-intersection-observer';
412+
import { defaultFallbackInView } from "react-intersection-observer";
426413

427414
defaultFallbackInView(true); // or 'false'
428415
```
@@ -431,8 +418,8 @@ You can also define the fallback locally on `useInView` or `<InView>` as an
431418
option. This will override the global fallback value.
432419
433420
```jsx
434-
import React from 'react';
435-
import { useInView } from 'react-intersection-observer';
421+
import React from "react";
422+
import { useInView } from "react-intersection-observer";
436423

437424
const Component = () => {
438425
const { ref, inView, entry } = useInView({
@@ -461,7 +448,7 @@ yarn add intersection-observer
461448
Then import it in your app:
462449
463450
```js
464-
import 'intersection-observer';
451+
import "intersection-observer";
465452
```
466453
467454
If you are using Webpack (or similar) you could use
@@ -474,8 +461,8 @@ like this:
474461
* Do feature detection, to figure out which polyfills needs to be imported.
475462
**/
476463
async function loadPolyfills() {
477-
if (typeof window.IntersectionObserver === 'undefined') {
478-
await import('intersection-observer');
464+
if (typeof window.IntersectionObserver === "undefined") {
465+
await import("intersection-observer");
479466
}
480467
}
481468
```
@@ -488,13 +475,13 @@ IntersectionObserver instances. This allows you to handle more advanced use
488475
cases, where you need full control over when and how observers are created.
489476
490477
```js
491-
import { observe } from 'react-intersection-observer';
478+
import { observe } from "react-intersection-observer";
492479

493480
const destroy = observe(element, callback, options);
494481
```
495482
496483
| Name | Type | Required | Description |
497-
|--------------|----------------------------|----------|------------------------------------------------------------|
484+
| ------------ | -------------------------- | -------- | ---------------------------------------------------------- |
498485
| **element** | `Element` | true | DOM element to observe |
499486
| **callback** | `ObserverInstanceCallback` | true | The callback function that Intersection Observer will call |
500487
| **options** | `IntersectionObserverInit` | false | The options for the Intersection Observer |
@@ -507,29 +494,13 @@ order to destroy the observer again.
507494
> how instances are created.
508495
509496
[package-url]: https://npmjs.org/package/react-intersection-observer
510-
511497
[npm-version-svg]: https://img.shields.io/npm/v/react-intersection-observer.svg
512-
513-
[npm-minzip-svg]:
514-
https://img.shields.io/bundlephobia/minzip/react-intersection-observer.svg
515-
516-
[bundlephobia-url]:
517-
https://bundlephobia.com/result?p=react-intersection-observer
518-
498+
[npm-minzip-svg]: https://img.shields.io/bundlephobia/minzip/react-intersection-observer.svg
499+
[bundlephobia-url]: https://bundlephobia.com/result?p=react-intersection-observer
519500
[license-image]: http://img.shields.io/npm/l/react-intersection-observer.svg
520-
521501
[license-url]: LICENSE
522-
523502
[downloads-image]: http://img.shields.io/npm/dm/react-intersection-observer.svg
524-
525-
[downloads-url]:
526-
http://npm-stat.com/charts.html?package=react-intersection-observer
527-
528-
[test-image]:
529-
https://github.com/thebuilder/react-intersection-observer/workflows/Test/badge.svg
530-
531-
[test-url]:
532-
https://github.com/thebuilder/react-intersection-observer/actions?query=workflow%3ATest
533-
534-
[test-utils-url]:
535-
https://github.com/thebuilder/react-intersection-observer/blob/master/src/test-utils.ts
503+
[downloads-url]: http://npm-stat.com/charts.html?package=react-intersection-observer
504+
[test-image]: https://github.com/thebuilder/react-intersection-observer/workflows/Test/badge.svg
505+
[test-url]: https://github.com/thebuilder/react-intersection-observer/actions?query=workflow%3ATest
506+
[test-utils-url]: https://github.com/thebuilder/react-intersection-observer/blob/master/src/test-utils.ts

0 commit comments

Comments
 (0)