Skip to content

Commit

Permalink
Add useIsIntersecting and useIsIntersectingState hooks #270
Browse files Browse the repository at this point in the history
  • Loading branch information
leroykorterink committed Feb 9, 2024
1 parent 8c7973d commit 294ad43
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/hooks/useIsIntersecting/useIsIntersecting.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Meta } from '@storybook/blocks';

<Meta title="Hooks / useIsIntersecting" />

# useIsIntersecting

Please add a description about the `useIsIntersecting` hook.

## Reference

```ts
function useIsIntersecting(): void;
```

### Parameters

- `TODO` - Describe the parameters here.

### Returns

- `TODO` - Define the return value here.

## Usage

```tsx
function DemoComponent() {
useIsIntersecting();
return <div></div>;
}
```
37 changes: 37 additions & 0 deletions src/hooks/useIsIntersecting/useIsIntersecting.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Meta, StoryObj } from '@storybook/react';
import type { ReactElement } from 'react';
import { useIsIntersecting } from './useIsIntersecting.js';

const meta = {
title: 'Hooks / useIsIntersecting',
} satisfies Meta;

type Story = StoryObj<typeof meta>;

function DemoComponent(): ReactElement {
useIsIntersecting();

return (
<div>
<div className="alert alert-primary">
<h4 className="alert-heading">Instructions!</h4>
<p className="mb-0">Add instructions about the hook here.</p>
</div>
<div>
Value: <span className="badge rounded-pill bg-primary">{/* value */}</span>
</div>
<div className="card border-dark" data-ref="test-area">
<div className="card-header">Test Area</div>
<div className="card-body">
<p>TODO: Implement a test case for the hook.</p>
</div>
</div>
</div>
);
}

export const Demo: Story = {
render() {
return <DemoComponent />;
},
};
11 changes: 11 additions & 0 deletions src/hooks/useIsIntersecting/useIsIntersecting.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { renderHook } from '@testing-library/react';
import { describe, it } from 'vitest';
import { useIsIntersecting } from './useIsIntersecting.js';

describe('useIsIntersecting', () => {
it('should not crash', async () => {
renderHook(() => {
return useIsIntersecting();
});
});
});
23 changes: 23 additions & 0 deletions src/hooks/useIsIntersecting/useIsIntersecting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { RefObject, useRef, useState } from 'react';
import { useIntersectionObserver } from '../useIntersectionObserver/useIntersectionObserver.js';

/**
* @param targetOrTargets
* @param options
*/
export function useIsIntersecting(
targetOrTargets: RefObject<Element | ReadonlyArray<Element | null> | null>,
options?: IntersectionObserverInit,
): RefObject<boolean> {
const isIntersectingRef = useRef(false);

useIntersectionObserver(
targetOrTargets,
(entries) => {
isIntersectingRef.current = entries.every((entry) => entry.isIntersecting);
},
options,
);

return isIntersectingRef;
}
30 changes: 30 additions & 0 deletions src/hooks/useIsIntersectingState/useIsIntersectingState.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Meta } from '@storybook/blocks';

<Meta title="Hooks / useIsIntersectingState" />

# useIsIntersectingState

Please add a description about the `useIsIntersectingState` hook.

## Reference

```ts
function useIsIntersectingState(): void;
```

### Parameters

- `TODO` - Describe the parameters here.

### Returns

- `TODO` - Define the return value here.

## Usage

```tsx
function DemoComponent() {
useIsIntersectingState();
return <div></div>;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Meta, StoryObj } from '@storybook/react';
import type { ReactElement } from 'react';
import { useIsIntersectingState } from './useIsIntersectingState.js';

const meta = {
title: 'Hooks / useIsIntersectingState',
} satisfies Meta;

type Story = StoryObj<typeof meta>;

function DemoComponent(): ReactElement {
useIsIntersectingState();

return (
<div>
<div className="alert alert-primary">
<h4 className="alert-heading">Instructions!</h4>
<p className="mb-0">Add instructions about the hook here.</p>
</div>
<div>
Value: <span className="badge rounded-pill bg-primary">{/* value */}</span>
</div>
<div className="card border-dark" data-ref="test-area">
<div className="card-header">Test Area</div>
<div className="card-body">
<p>TODO: Implement a test case for the hook.</p>
</div>
</div>
</div>
);
}

export const Demo: Story = {
render() {
return <DemoComponent />;
},
};
11 changes: 11 additions & 0 deletions src/hooks/useIsIntersectingState/useIsIntersectingState.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { renderHook } from '@testing-library/react';
import { describe, it } from 'vitest';
import { useIsIntersectingState } from './useIsIntersectingState.js';

describe('useIsIntersectingState', () => {
it('should not crash', async () => {
renderHook(() => {
return useIsIntersectingState();
});
});
});
23 changes: 23 additions & 0 deletions src/hooks/useIsIntersectingState/useIsIntersectingState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { RefObject, useState } from 'react';
import { useIntersectionObserver } from '../useIntersectionObserver/useIntersectionObserver.js';

/**
* @param targetOrTargets
* @param options
*/
export function useIsIntersectingState(
targetOrTargets: RefObject<Element | ReadonlyArray<Element | null> | null>,
options?: IntersectionObserverInit,
): boolean {
const [isIntersecting, setIsIntersecting] = useState(false);

useIntersectionObserver(
targetOrTargets,
(entries) => {
setIsIntersecting(() => entries.every((entry) => entry.isIntersecting));
},
options,
);

return isIntersecting;
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export * from './hooks/useForceRerender/useForceRerender.js';
export * from './hooks/useHasFocus/useHasFocus.js';
export * from './hooks/useIntersectionObserver/useIntersectionObserver.js';
export * from './hooks/useInterval/useInterval.js';
export * from './hooks/useIsIntersecting/useIsIntersecting.js';
export * from './hooks/useIsIntersectingState/useIsIntersectingState.js';
export * from './hooks/useMediaDuration/useMediaDuration.js';
export * from './hooks/useMediaQuery/useMediaQuery.js';
export * from './hooks/useMutationObserver/useMutationObserver.js';
Expand Down

0 comments on commit 294ad43

Please sign in to comment.