Blueprint

LoadingOverlay

A modal loading overlay that blocks all user interaction while displaying a spinner.

Design guidance

When and how to use this

Use a LoadingOverlay to indicate that an action or request is in progress, and the user cannot interact with the page until it is complete. Some examples include:

  • The initial data request(s) made when a page first loads, and there is no content for the user to interact with
  • When a user submits a form and the subsequent state of the application is determined based on the submission results.

When to consider something else

A LoadingOverlay should only be used when blocking user interaction is required. If the asynchronous action is not critical to the user's experience, consider using a Loader, the isLoading prop on the Button that initiated the action, or a LoadingState on the pending section of interface.

React


import { LoadingOverlay } from '@hover/blueprint';

Render the LoadingOverlay component itself unconditionally using the isLoading prop to control its open state. Provide an accessible label to describe the pending action.

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 2000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={hLoader} onClick={on} shape="box">
Load
</Button>
<LoadingOverlay isLoading={isLoading} label="I'm waiting on something" />
</>
);
};

Label

By default, the label prop is only used for accessibility purposes. Pass isCaptioned to also display the label visually beneath the spinner.

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 5000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={hLoader} onClick={on} shape="box">
Load with caption
</Button>
<LoadingOverlay isLoading={isLoading} label="Making memes..." isCaptioned />
</>
);
};

Color

Any system can be applied to a Loader, though in most cases the primary or neutral palette should be preferred.

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 2000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={hLoader} onClick={on} shape="box">
Color
</Button>
<LoadingOverlay isLoading={isLoading} color="neutral.900" />
</>
);
};

Speed

The animation speed is controlled via the speed prop and defaults to 500.

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 2000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={hLoader} onClick={on} shape="box">
Speed
</Button>
<LoadingOverlay isLoading={isLoading} speed={700} />
</>
);
};