-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add new hook useContentLoadingIndicator (#126)
## Description <!-- Write and explain of the changes introduced by this PR for the reviewers to fully understand --> ## Screenshot <!-- Provide a screenshot or gif of the change to demonstrate it --> ## Test Plan <!-- Explain what you tested and why --> <!-- Have any questions? Check out the contributing doc for more -->
- Loading branch information
Showing
7 changed files
with
138 additions
and
6 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
documentation/docs/api/Hooks/useContentLoadingIndicator.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
id: 'useContentLoadingIndicator' | ||
title: 'useContentLoadingIndicator' | ||
sidebar_label: 'useContentLoadingIndicator' | ||
sidebar_position: 3.1 | ||
--- | ||
|
||
```ts | ||
import { useContentLoadingIndicator } from '@orfium/toolbox'; | ||
``` | ||
|
||
:::info | ||
Only descendants of [`Scaffold`](../components/Scaffold) can use this hook. | ||
::: | ||
|
||
## Description | ||
|
||
A hook that simply activates/deactivates an indeterminate loader meant to indicate that the content of the page is | ||
still loading. | ||
|
||
The hook will automatically reset the value to `false` upon unmounting, so you do not have to manually clean up anything. | ||
|
||
**Example usage** | ||
|
||
```tsx | ||
import { useContentLoadingIndicator } from '@orfium/toolbox'; | ||
import { useQuery } from '@tanstack/react-query'; | ||
|
||
function Page() { | ||
const {data, isLoading} = useQuery(/***/) | ||
useContentLoadingIndicator(isLoading); | ||
|
||
return <div>{data ? data.toString() : '-'}</div>; | ||
} | ||
``` | ||
|
||
## Parameters | ||
|
||
- `active: boolean` - Indicates whether the loading indicator should be shown or not. | ||
|
||
## Return value | ||
|
||
Ƭ `undefined` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { createContext, Dispatch, SetStateAction } from 'react'; | ||
|
||
export type ContentLoadingIndicatorContextValue = { | ||
loadingIndicator: boolean; | ||
setLoadingIndicator: Dispatch<SetStateAction<boolean>>; | ||
}; | ||
|
||
export const defaultContentLoadingIndicatorContextValue: ContentLoadingIndicatorContextValue = { | ||
loadingIndicator: false, | ||
setLoadingIndicator: new Proxy(() => {}, { | ||
apply: () => { | ||
throw new Error( | ||
'You can only use useContentLoadingIndicator inside descendants of the Scaffold component' | ||
); | ||
}, | ||
}), | ||
}; | ||
export const ContentLoadingIndicatorContext = createContext<ContentLoadingIndicatorContextValue>( | ||
defaultContentLoadingIndicatorContextValue | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useContext, useEffect } from 'react'; | ||
import { ContentLoadingIndicatorContext } from '../contexts/content-loading-indicator'; | ||
|
||
export const _useContentLoadingIndicator = () => useContext(ContentLoadingIndicatorContext); | ||
export const useContentLoadingIndicator = (active: boolean) => { | ||
const { setLoadingIndicator } = useContext(ContentLoadingIndicatorContext); | ||
|
||
useEffect(() => { | ||
setLoadingIndicator(active); | ||
|
||
return function () { | ||
setLoadingIndicator(false); | ||
}; | ||
}, [setLoadingIndicator, active]); | ||
}; | ||
|
||
export type UseLoadingIndicatorReturnValue = undefined; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ReactNode, useState } from 'react'; | ||
import { ContentLoadingIndicatorContext } from '../contexts/content-loading-indicator'; | ||
|
||
export function ContentLoadingIndicator(props: { children: ReactNode }) { | ||
const { children } = props; | ||
const [loadingIndicator, setLoadingIndicator] = useState<boolean>(false); | ||
|
||
return ( | ||
<ContentLoadingIndicatorContext.Provider | ||
value={{ | ||
loadingIndicator, | ||
setLoadingIndicator, | ||
}} | ||
> | ||
{children} | ||
</ContentLoadingIndicatorContext.Provider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,52 @@ | ||
import { Global } from '@emotion/react'; | ||
import { useTheme } from '@orfium/ictinus'; | ||
import { Loader, useTheme } from '@orfium/ictinus'; | ||
import { type ReactElement, type ReactNode } from 'react'; | ||
import { backGround, Contents, GridContainer, Header, SideNav } from './Scaffold.styles'; | ||
import { _useContentLoadingIndicator } from '../../hooks/useContentLoadingIndicator'; | ||
import { ContentLoadingIndicator } from '../../providers/ContentLoadingIndicator'; | ||
import { | ||
Contents, | ||
GridContainer, | ||
Header, | ||
LoadingBarWrapper, | ||
SideNav, | ||
backGround, | ||
} from './Scaffold.styles'; | ||
|
||
export type ScaffoldProps = { | ||
navigationSlot: ReactElement; | ||
headerSlot: ReactElement; | ||
children: ReactNode; | ||
}; | ||
|
||
export function Scaffold(props: ScaffoldProps) { | ||
function ScaffoldInternal(props: ScaffoldProps) { | ||
const { navigationSlot, headerSlot, children } = props; | ||
const { loadingIndicator } = _useContentLoadingIndicator(); | ||
|
||
const theme = useTheme(); | ||
|
||
return ( | ||
<GridContainer> | ||
<Global styles={{ body: backGround(theme) }} /> | ||
<SideNav>{navigationSlot}</SideNav> | ||
<Header>{headerSlot}</Header> | ||
<Header> | ||
{loadingIndicator ? ( | ||
<LoadingBarWrapper> | ||
<Loader type={'indeterminate'} /> | ||
</LoadingBarWrapper> | ||
) : null} | ||
{headerSlot} | ||
</Header> | ||
<Contents>{children}</Contents> | ||
</GridContainer> | ||
); | ||
} | ||
|
||
export function Scaffold(props: ScaffoldProps) { | ||
const { children, ...rest } = props; | ||
|
||
return ( | ||
<ContentLoadingIndicator> | ||
<ScaffoldInternal {...rest}>{children}</ScaffoldInternal> | ||
</ContentLoadingIndicator> | ||
); | ||
} |