An open API service indexing awesome lists of open source software.

https://github.com/filipchalupa/shared-loading-indicator

NPM package simplifying loading state sharing in React.
https://github.com/filipchalupa/shared-loading-indicator

loading npm-package react react-hooks

Last synced: 20 days ago
JSON representation

NPM package simplifying loading state sharing in React.

Awesome Lists containing this project

README

        

# Shared loading indicator [![npm](https://img.shields.io/npm/v/shared-loading-indicator.svg)](https://www.npmjs.com/package/shared-loading-indicator) ![npm type definitions](https://img.shields.io/npm/types/shared-loading-indicator.svg)

Simplifies loading state sharing in React.

![Demo](https://raw.githubusercontent.com/FilipChalupa/shared-loading-indicator/HEAD/screencast.gif)

You can play with it yourself here [filipchalupa.cz/shared-loading-indicator](https://filipchalupa.cz/shared-loading-indicator/).

## Installation

```bash
npm install shared-loading-indicator
```

## How to use

Wrap all by one ``.

```jsx
import { SharedLoadingIndicatorContextProvider } from 'shared-loading-indicator'

export const App => () => {
return (

My app

)
}
```

### Component ``

Place `SharedProgressLoadingIndicator` inside `SharedLoadingIndicatorContextProvider` to use prestyled loading indicator. See [demo](https://shared-loading-indicator.netlify.app) to change color or placement.

```jsx
import { SharedLoadingIndicatorContextProvider, SharedProgressLoadingIndicator } from 'shared-loading-indicator'

export const App => () => {
return (


My app

)
}
```

You can change the `` color by setting a CSS custom property on its parent named `--ProgressLoadingIndicator-color`. Or you can build your own indicator using `useSharedLoading` hook.

#### CSS example

```css
:root {
--ProgressLoadingIndicator-color: #ff00ff;
}
```

![magenta indicator](https://raw.githubusercontent.com/FilipChalupa/shared-loading-indicator/HEAD/magenta-indicator.gif)

### Hook `useSharedLoading()`

Hook `useSharedLoading` returns `true` if some component is in loading state. Use this information to show your own loading indicator (spinner, progress bar, …).

```jsx
import { useSharedLoading } from 'shared-loading-indicator'

export const LoadingIndicator => () => {
const isLoading = useSharedLoading()

if (!isLoading) {
return null
}

return (


App is loading something

)
}
```

#### Options

You can optionally configure `startDelay` and `minimalDuration` in milliseconds.

```js
const isLoading = useSharedLoading({
startDelay: 300, // isLoading won't be true if all local loads get finished under 300 milliseconds
minimalDuration: 1000, // isLoading will be true for at least 1000 milliseconds
})
```

### Component ``

Place `` inside `` to signalize something is loading.

```jsx
import { SharedLoadingIndicatorContextProvider, Loading } from 'shared-loading-indicator'

export const App => () => {
const somethingIsLoading = true // Hook this to a state

return (

{somethingIsLoading && }
My app

)
}
```

### Hook `useLocalLoading()`

Hook `useLocalLoading` works similarly to `useState`. It returns array with `boolean` state indicating that component is loading and set function.

```jsx
import { useLocalLoading } from 'shared-loading-indicator'

export const MyComponent => () => {
const [isLoading, setIsLoading] = useLocalLoading()

return (



Is loading: {isLoading ? 'yes' : 'no'}

{
setIsLoading(!isLoading)
}}>

)
}
```

```jsx
import { useLocalLoading } from 'shared-loading-indicator'
import { useEffect } from 'react'

export const LazyComponent => () => {
const [isLoading, setIsLoading] = useLocalLoading()
const [data, setData] = useState(null)

useEffect(() => {
setIsLoading(true)
fetch('https://example.com')
.then(response => response.json())
.then(receivedData => {
setData(receivedData)
})
.finally(() => {
setIsLoading(false)
})
}, [])

return (



Is loading: {isLoading ? 'yes' : 'no'}


{JSON.stringify(data, null, 2)}


)
}
```

### Hook `useMirrorLoading()`

Mirrors first argument to `useLocalMirror` under the hood.

```jsx
import { useMirrorLoading } from 'shared-loading-indicator'
import { useQuery } from '@tanstack/react-query'

const Mirror = () => {
const query = useQuery([], getData)
useMirrorLoading(query.isLoading)

return

{query.data}

}
```

### Suspense by ``

To capture loading state using Suspense wrap your content by ``.

```jsx
import { LoadingSuspense } from 'shared-loading-indicator'

const LazyWithSuspense = () => {
return (



)
}
```

## Tips

- [Page navigation in Next.js](tips/nextjs.md)
- [Custom indicator with Material UI](tips/materialui.md)

## Development

- Install dependencies: `npm ci`
- Run: `npm run dev`