@achmadk/react-loading-overlay
TypeScript icon, indicating that this package has built-in type declarations

3.0.5 • Public • Published

@achmadk/react-loading-overlay

npm version minified + gzipped downloads

A customizable, simple loading overlay with spinner, transitions.

Comparing to react-loading-overlay, this library support ES Module and Typescript friendly, and also have another features like ref forwarding and using latest version of @emotion/css instead emotion.



Quick start 🏃‍♀️

Install this library and its peer dependencies using your favorite package manager (npm/yarn/pnpm)

# npm
npm i @achmadk/react-loading-overlay react @emotion/css react-transition-group
# yarn
yarn add @achmadk/react-loading-overlay react @emotion/css react-transition-group
# pnpm
pnpm add @achmadk/react-loading-overlay react @emotion/css react-transition-group

Wrap your components in it and toggle the active prop as necessary.

import { useState, useCallback } from 'react';
import { LoadingOverlay } from '@achmadk/react-loading-overlay';

const Sample = () => {
  const [isActive, setActive] = useState(true)
  const handleButtonClicked = useCallback(() => {
    setActive(value => !value)
  }, [])
  return (
    <LoadingOverlay
      active={isActive}
      spinner
      text='Loading your content...'
    >
      <div style={{ height: 200 }}>
        <p>Some content or children or something.</p>
        <button onClick={handleButtonClick}>Toggle active</button>
      </div>
    </LoadingOverlay>
  )
}

Usage in nextjs

This library has built-in support for nextjs. You can import LoadingOverlay component from @achmadk/react-loading-overlay/nextjs

import { useState, useCallback } from 'react';
- import { LoadingOverlay } from '@achmadk/react-loading-overlay';
+ import { LoadingOverlay } from '@achmadk/react-loading-overlay/nextjs';

const Sample = () => {
  const [isActive, setActive] = useState(true)
  const handleButtonClicked = useCallback(() => {
    setActive(value => !value)
  }, [])
  return (
    <LoadingOverlay
      active={isActive}
      spinner
      text='Loading your content...'
    >
      <div style={{ height: 200 }}>
        <p>Some content or children or something.</p>
        <button onClick={handleButtonClick}>Toggle active</button>
      </div>
    </LoadingOverlay>
  )
}

Props 🛠️

props name data type default value description
*active boolean true whether the loader is visible.
fadeSpeed number (millisecond) 500 the transition speed for fading out the overlay.
onClick (event?: MouseEvent<HTMLDivElement>) => void OR Promise<void> OR undefined undefined click handler for the overlay when active.
className string OR undefined undefined the class name for the wrapping <div /> that is present whether active or not.
classNamePrefix string _loading_overlay_ the prefix for all classNames on the generated elements. see Styling for more info.
spinner boolean or ReactNode false renders the default spinner when true (and when the loader is active). Otherwise you can provide any valid react node to use your own spinner.
text ReactNode or undefined undefined the text or react node to render in the loader overlay when active.
styles object or undefined undefined see Styling for more info.
ref HTMLDivElement or undefined undefined this will refer to wrapper element (see here), if you use it with either useRef or createRef.

Custom Spinner ♻️

Adding a custom spinner is super easy, here's an example:

Acquire the spinner you want to use. Doesn't matter where you get it, as long as you're rendering a valid React node. It can be a custom svg in your codebase if you want. For this example let's use react-spinners.

npm install react-spinners

Then simply provide it to the spinner prop for your loader.

import { LoadingOverlay } from '@achmadk/react-loading-overlay'
import BounceLoader from 'react-spinners/BounceLoader'

export default function MyLoader({ active, children }) {
  return (
    <LoadingOverlay
      active={active}
      spinner={<BounceLoader />}
    >
      {children}
    </LoadingOverlay>
  )
}

Custom styling 💅

Previous versions were difficult to customize because of limited configuration props. This iteration uses a form of styling heavily inspired by Style configuration was inspired by react-select. Internally using emotion to style elements and providing a styles interface to either extend the base styling or completely overwrite it. Additionally, a classNamePrefix prop is available to customize the classNames used on each element, allowing you to define your own styles with your own regular css setup.

Keep reading for details on each option.

Styles with emotion 👩‍🎤

The styles prop accepts an object where each key represents one of the following elements:

  • wrapper - main wrapping element, always present.
  • overlay - the overlay positioned over top of the children.
  • content - element inside the overlay containing the spinner and text.
  • spinner - default spinner element.

Each value must be an object or a function (where the first parameter is the base default styles) that returns an object. In either case, the resulting object will be applied as the final set of styles via emotion.css. See examples below.

  • Custom overlay background (extending base styles)

    export default function MyLoader({ active, children }) {
      return (
        <LoadingOverlay
          active={active}
          styles={{
            overlay: (base) => ({
              ...base,
              background: 'rgba(255, 0, 0, 0.5)'
            })
          }}
        >
          {children}
        </LoadingOverlay>
      )
    }
  • Custom spinner size + color (extending base styles)

    export default function MyLoader({ active, children }) {
      return (
        <LoadingOverlay
          active={active}
          styles={{
            spinner: (base) => ({
              ...base,
              width: '100px',
              '& svg circle': {
                stroke: 'rgba(255, 0, 0, 0.5)'
              }
            })
          }}
        >
          {children}
        </LoadingOverlay>
      )
    }
  • Custom wrapper (non-extended)

    export default function MyLoader({ active, children }) {
      return (
        <LoadingOverlay
          active={active}
          styles={{
            wrapper: {
              width: '400px',
              height: '400px',
              overflow: active ? 'hidden' : 'scroll'
            }
          }}
        >
          {children}
        </LoadingOverlay>
      )
    }

Styles with css

Every element has a classname you can target via your own css configuration.

  • _loading_overlay_wrapper
  • _loading_overlay_overlay
  • _loading_overlay_content
  • _loading_overlay_spinner

You can also specify your own classNamePrefix if you wish. For example, if using: classNamePrefix="MyLoader_":

  • MyLoader_wrapper
  • MyLoader_overlay
  • MyLoader_content
  • MyLoader_spinner

The base styles will still be applied, but you could negate all of these using the styles prop:

  • Remove all default styles

    export default function MyLoader({ active, children }) {
      return (
        <LoadingOverlay
          active={active}
          styles={{
            wrapper: {},
            overlay: {},
            content: {},
            spinner: {}
          }}
          classNamePrefix='MyLoader_'
        >
          {children}
        </LoadingOverlay>
      )
    }

Styles with styled-components 💅

You can style the loader using styled-component as you might expect.

Simply include the nested elements in your style definition:

  • styled-components example

    import styled from 'styled-components'
    
    const StyledLoader = styled(LoadingOverlay)`
      width: 250px;
      height: 400px;
      overflow: scroll;
      .MyLoader_overlay {
        background: rgba(255, 0, 0, 0.5);
      }
      &.MyLoader_wrapper--active {
        overflow: hidden;
      }
    `
    
    export default function MyLoader({ active, children }) {
      return (
        <StyledLoader
          active={active}
          classNamePrefix='MyLoader_'
        >
          {children}
        </StyledLoader>
      )
    }

Migrate from react-loading-overlay-ts

This library is improvement of existing react-loading-overlay-ts in order to:

  • support React 19, which no longer use Component or PureComponent class anymore.
  • wrap my open source libraries into one repository instead of multi repository.
  • use vite and vitest for faster development.

Here is a few steps to migrate react-loading-overlay-ts to @achmadk/react-loading-overlay:

  1. install peer dependencies of @achmadk/react-loading-overlay, because @emotion/css and react-transition-group have been moved from dependencies into peer ones instead:
npm i @emotion/css react-transition-group # npm
yarn add @emotion/css react-transition-group # yarn
pnpm add @emotion/css react-transition-group # pnpm
  1. Use named component instead of default one to use loading overlay component.
- import LoadingOverlay from 'react-loading-overlay-ts'
+ import { LoadingOverlay } from '@achmadk/react-loading-overlay'

You can still use default component but it was deprecated in this version and will be deleted in the next major version (v4).

Dependencies (1)

Dev Dependencies (6)

Package Sidebar

Install

npm i @achmadk/react-loading-overlay

Weekly Downloads

149

Version

3.0.5

License

MIT

Unpacked Size

52.6 kB

Total Files

17

Last publish

Collaborators

  • achmadkurnianto