/
GridLoader.tsx
68 lines (56 loc) · 2.08 KB
/
GridLoader.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
58
59
60
61
62
63
64
65
66
67
68
/** @jsxImportSource @emotion/react */
import * as React from "react";
import { keyframes, css, SerializedStyles } from "@emotion/react";
import { sizeMarginDefaults, cssValue, parseLengthAndUnit } from "./helpers";
import { LoaderSizeMarginProps } from "./interfaces";
const grid = keyframes`
0% {transform: scale(1)}
50% {transform: scale(0.5); opacity: 0.7}
100% {transform: scale(1);opacity: 1}
`;
const random = (top: number): number => Math.random() * top;
class Loader extends React.PureComponent<Required<LoaderSizeMarginProps>> {
public static defaultProps = sizeMarginDefaults(15);
public style = (rand: number): SerializedStyles => {
const { color, size, margin, speedMultiplier } = this.props;
return css`
display: inline-block;
background-color: ${color};
width: ${cssValue(size)};
height: ${cssValue(size)};
margin: ${cssValue(margin)};
border-radius: 100%;
animation-fill-mode: "both";
animation: ${grid} ${(rand / 100 + 0.6) / speedMultiplier}s ${rand / 100 - 0.2}s infinite ease;
`;
};
public wrapper = (): SerializedStyles => {
const { size, margin } = this.props;
const sizeWithUnit = parseLengthAndUnit(size);
const marginWithUnit = parseLengthAndUnit(margin);
const width = `${parseFloat(sizeWithUnit.value.toString()) * 3 + parseFloat(marginWithUnit.value.toString()) * 6}${
sizeWithUnit.unit
}`;
return css`
width: ${width};
font-size: 0;
`;
};
public render(): JSX.Element | null {
const { loading, css } = this.props;
return loading ? (
<span css={[this.wrapper(), css]}>
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
<span css={this.style(random(100))} />
</span>
) : null;
}
}
export default Loader;