Design System

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 '@hoverinc/design-system-react-web';

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={iconArrowForward} onClick={on}>
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 brand loader.

live

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

Progress Mode

By default, the overlay uses the brand loader. You can switch over to a FauxProgress version via the variant prop with a value of progress to also display the progress loader. It also takes in some optional props for controlling the duration as well as

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 5000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={iconArrowForward} onClick={on}>
Load with progress
</Button>
<LoadingOverlay
isLoading={isLoading}
variant="progress"
duration={5}
loadingTexts={[
'Lets get started...',
'Here we go...',
'Almost there...',
'Helpful tips!',
]}
loadingTextInterval={1500}
loadingTextsShouldLoop={false}
/>
</>
);
};

Color Mode

The progress overlay also supports light and dark color mode

live

() => {
const [isLoading, { on, off }] = useBoolean();
useEffect(() => {
const id = isLoading && setTimeout(off, 5000);
return () => clearTimeout(id);
}, [isLoading]);
return (
<>
<Button iconBefore={iconArrowForward} onClick={on}>
Dark mode
</Button>
<LoadingOverlay
colorMode="dark"
isLoading={isLoading}
variant="progress"
duration={5}
loadingTexts={[
'Lets get started...',
'Here we go...',
'Almost there...',
'Helpful tips!',
]}
loadingTextInterval={1500}
/>
</>
);
};


Copyright ยฉ 2025 Hover Inc. All Rights Reserved.