Skip to content

Commit e263c76

Browse files
jphawkElena KazakovaRobert Grzonka
authored
Add Spinner (#91)
* Spinner WIP * Add Spinner * Fix setColor * Fix colors Co-authored-by: Elena Kazakova <[email protected]> Co-authored-by: Robert Grzonka <[email protected]>
1 parent b2a0cb8 commit e263c76

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export * from "./switch";
2525
export * from "./heading";
2626
export * from "./sidebar";
2727
export * from "./tabs";
28+
export * from "./spinner";

src/components/spinner/Spinner.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React, { FunctionComponent } from "react";
2+
import { color } from "styled-system";
3+
import styled, { css } from "styled-components";
4+
import theme from "../../theme";
5+
import { Text } from "../text";
6+
7+
export interface SpinnerProps {
8+
caption?: string;
9+
className?: string;
10+
size?: number;
11+
color?: string;
12+
onClick?: (e: any) => void;
13+
onChange?: (e: React.FormEvent<HTMLInputElement>) => void;
14+
}
15+
16+
const SpinnerContainer = styled.div<SpinnerProps>`
17+
display: flex;
18+
align-items: center;
19+
p {
20+
margin: 0 0 0 ${({ caption }) => (caption ? theme.spacing.spacing02 : "0")};
21+
}
22+
`;
23+
24+
const StyledRing = styled.div<SpinnerProps>`
25+
${color};
26+
display: inline-block;
27+
position: relative;
28+
width: 5rem;
29+
height: 5rem;
30+
zoom: ${({ size }) => (size ? `${size}` : `1`)};
31+
32+
div {
33+
box-sizing: border-box;
34+
display: block;
35+
position: absolute;
36+
width: 4rem;
37+
height: 4rem;
38+
margin: 0.5rem;
39+
border: 0.5rem solid ${theme.colors.primary};
40+
border-radius: 50%;
41+
animation: ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
42+
border-color: ${theme.colors.primary} transparent transparent transparent;
43+
&:nth-child(1) {
44+
animation-delay: -0.45s;
45+
}
46+
&:nth-child(2) {
47+
animation-delay: -0.3s;
48+
}
49+
&:nth-child(3) {
50+
animation-delay: -0.15s;
51+
}
52+
${({ color }) =>
53+
color &&
54+
css`
55+
border: 0.5rem solid
56+
${theme.colors[color] ? theme.colors[color] : color};
57+
border-color: ${theme.colors[color] ? theme.colors[color] : color}
58+
transparent transparent transparent;
59+
`}
60+
}
61+
62+
@keyframes ring {
63+
0% {
64+
transform: rotate(0deg);
65+
}
66+
100% {
67+
transform: rotate(360deg);
68+
}
69+
}
70+
`;
71+
72+
export const Spinner: FunctionComponent<SpinnerProps> = ({
73+
caption,
74+
color,
75+
size,
76+
}) => {
77+
return (
78+
<SpinnerContainer caption={caption}>
79+
<StyledRing color={color} size={size}>
80+
<div></div>
81+
<div></div>
82+
<div></div>
83+
<div></div>
84+
</StyledRing>
85+
{caption && <Text>{caption}</Text>}
86+
</SpinnerContainer>
87+
);
88+
};

src/components/spinner/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Spinner";

src/stories/Spinner.stories.mdx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import styled from "styled-components";
2+
import { Meta, Story, Preview } from "@storybook/addon-docs/blocks";
3+
import { Spinner } from "../components/spinner";
4+
import { Button } from "../components/button";
5+
import { Spacer } from "../components/spacer";
6+
import theme from "../theme";
7+
8+
<Meta title="Components/Spinner" component={Spinner} />
9+
10+
# Spinner
11+
12+
#### Props
13+
14+
```typescript
15+
export interface SpinnerProps {
16+
caption?: string;
17+
className?: string;
18+
size?: number;
19+
color?: string;
20+
onClick?: (e: any) => void;
21+
onChange?: (e: React.FormEvent<HTMLInputElement>) => void;
22+
}
23+
```
24+
25+
## Default
26+
27+
<Preview>
28+
<Story name="default">
29+
<Spinner />
30+
</Story>
31+
</Preview>
32+
33+
## Color
34+
35+
From `theme`:
36+
37+
<Preview>
38+
<Story name="color theme">
39+
<Spinner color="success" size="0.5" />
40+
</Story>
41+
</Preview>
42+
43+
Named:
44+
45+
<Preview>
46+
<Story name="named">
47+
<Spinner color="palevioletred" size="0.5" />
48+
</Story>
49+
</Preview>
50+
51+
## Size
52+
53+
> `size?: number;` - size is measured in percentage; 1 is original size of the spinner
54+
55+
<Preview>
56+
<Story name="size">
57+
<Spinner size="0.2" />
58+
</Story>
59+
</Preview>
60+
61+
## Label
62+
63+
> `caption?: string;` - caption for the spinner
64+
65+
<Preview>
66+
<Story name="label">
67+
<Spinner size="0.2" caption="Here is a spinner" />
68+
</Story>
69+
</Preview>
70+
71+
## Button
72+
73+
<Preview>
74+
<Story name="button">
75+
<Button>
76+
<Spinner size="0.2" color="white" caption="Spinner" />
77+
</Button>
78+
</Story>
79+
</Preview>

0 commit comments

Comments
 (0)