Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/resources/scripts/components/elements/Spinner.tsx
7461 views
1
import React, { Suspense } from 'react';
2
import styled, { css, keyframes } from 'styled-components/macro';
3
import tw from 'twin.macro';
4
import ErrorBoundary from '@/components/elements/ErrorBoundary';
5
6
export type SpinnerSize = 'small' | 'base' | 'large';
7
8
interface Props {
9
size?: SpinnerSize;
10
centered?: boolean;
11
isBlue?: boolean;
12
}
13
14
interface Spinner extends React.FC<Props> {
15
Size: Record<'SMALL' | 'BASE' | 'LARGE', SpinnerSize>;
16
Suspense: React.FC<Props>;
17
}
18
19
const spin = keyframes`
20
to { transform: rotate(360deg); }
21
`;
22
23
// noinspection CssOverwrittenProperties
24
const SpinnerComponent = styled.div<Props>`
25
${tw`w-8 h-8`};
26
border-width: 3px;
27
border-radius: 50%;
28
animation: ${spin} 1s cubic-bezier(0.55, 0.25, 0.25, 0.7) infinite;
29
30
${(props) =>
31
props.size === 'small'
32
? tw`w-4 h-4 border-2`
33
: props.size === 'large'
34
? css`
35
${tw`w-16 h-16`};
36
border-width: 6px;
37
`
38
: null};
39
40
border-color: ${(props) => (!props.isBlue ? 'rgba(255, 255, 255, 0.2)' : 'hsla(212, 92%, 43%, 0.2)')};
41
border-top-color: ${(props) => (!props.isBlue ? 'rgb(255, 255, 255)' : 'hsl(212, 92%, 43%)')};
42
`;
43
44
const Spinner: Spinner = ({ centered, ...props }) =>
45
centered ? (
46
<div css={[tw`flex justify-center items-center`, props.size === 'large' ? tw`m-20` : tw`m-6`]}>
47
<SpinnerComponent {...props} />
48
</div>
49
) : (
50
<SpinnerComponent {...props} />
51
);
52
Spinner.displayName = 'Spinner';
53
54
Spinner.Size = {
55
SMALL: 'small',
56
BASE: 'base',
57
LARGE: 'large',
58
};
59
60
Spinner.Suspense = ({ children, centered = true, size = Spinner.Size.LARGE, ...props }) => (
61
<Suspense fallback={<Spinner centered={centered} size={size} {...props} />}>
62
<ErrorBoundary>{children}</ErrorBoundary>
63
</Suspense>
64
);
65
Spinner.Suspense.displayName = 'Spinner.Suspense';
66
67
export default Spinner;
68
69