-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoadingContainer.tsx
57 lines (52 loc) · 2.21 KB
/
LoadingContainer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import React from 'react'
import { useEffect, useRef, useState } from "react";
import { Empty, Spin, theme } from 'antd';
import { PiEmptyFill } from "react-icons/pi";
interface LoadingContainerProps {
isFetching: boolean;
noData?:boolean;
children: React.ReactNode;
blurRadius?: string;
delay?: number;
}
/**
* Composant qui ajoute un effet de flou pendant le chargement (si temps de chargement > delay) et affiche un spinner au centre du contenu.
* @param isLoading Indique si le chargement est en cours ou non
* @param children Les éléments enfants à afficher dans le composant
* @param blurRadius Rayon du floutage (par défaut : 10px)
* @param delay Délai en millisecondes avant d'appliquer le flou lors du chargement (par défaut : 500ms)
*/
const LoadingContainer:React.FC<LoadingContainerProps> = ({isFetching, children, blurRadius='10px', delay=500, noData}) =>
{
const { token } = theme.useToken();
const [blur, setBlur] = useState(false);
const timeoutRef = useRef<number | null>(null); //Le timeout permet que le blur ne s'affiche pas si le chargement est plus court que delay (éviter effet clignotement)
useEffect(() => {
if(isFetching){
timeoutRef.current = window.setTimeout(() => {
setBlur(true);
}, delay);
}
else{
timeoutRef.current && clearTimeout(timeoutRef.current );
setBlur(false);
}
return () => { timeoutRef.current && clearTimeout(timeoutRef.current ) }
},[isFetching])
return(
<>
<div style={ {
filter: blur ? `blur(${blurRadius})` : undefined,
display : noData ? "none" : undefined} }>
{ children }
</div>
{noData && <Empty
style={{position:"absolute", top:"50%", right:"50%", transform: "translate(50%, -50%)"}}
description="Pas de données disponibles"
image={<PiEmptyFill size={80} color={token.colorPrimary}/>} />
}
{ blur ? <Spin size="large" style={{position:'absolute', left:'50%', top:'50%' }}/> : <></>}
</>
)
}
export default LoadingContainer;