Skip to content

Commit fe4df8f

Browse files
committed
Add new Twist indicator
1 parent 63d6c76 commit fe4df8f

File tree

6 files changed

+237
-0
lines changed

6 files changed

+237
-0
lines changed

src/indicators/Twist/Twist.scss

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
@use "../../scss/variables" as defaults;
2+
3+
$twistAnimDuration: 4s;
4+
$twistBladeAnimDuration: 2s;
5+
$twistBladeWidth: 4em;
6+
7+
.twist-bounding-box {
8+
box-sizing: border-box;
9+
font-size: defaults.$fontSizer;
10+
position: relative;
11+
isolation: isolate;
12+
color: defaults.$defaultColor;
13+
14+
.twist-loader {
15+
width: $twistBladeWidth;
16+
perspective: 1000px;
17+
animation: twistRotate360 $twistAnimDuration linear infinite;
18+
19+
.blade {
20+
display: block;
21+
width: $twistBladeWidth;
22+
height: calc($twistBladeWidth / 8);
23+
background: currentColor;
24+
margin-bottom: 0.1em;
25+
animation: twistBlade 4s linear infinite, bgPlay $twistBladeAnimDuration linear infinite;
26+
opacity : 0;
27+
transition: opacity 400ms;
28+
29+
&:nth-child(1) {
30+
animation-delay: 0s;
31+
}
32+
&:nth-child(2) {
33+
animation-delay: 0.25s;
34+
}
35+
&:nth-child(3) {
36+
animation-delay: 0.5s;
37+
}
38+
&:nth-child(4) {
39+
animation-delay: 0.75s;
40+
}
41+
&:nth-child(5) {
42+
animation-delay: 1s;
43+
}
44+
&:nth-child(6) {
45+
animation-delay: 1.25s;
46+
}
47+
&:nth-child(7) {
48+
animation-delay: 1.5s;
49+
}
50+
&:nth-child(8) {
51+
animation-delay: 1.75s;
52+
}
53+
}
54+
}
55+
56+
.twist-text {
57+
color: currentColor;
58+
mix-blend-mode: difference;
59+
60+
position: absolute;
61+
top: 105%;
62+
left: 50%;
63+
transform: translateX(-50%);
64+
65+
z-index: -2;
66+
}
67+
}
68+
69+
@keyframes twistBlade {
70+
from {
71+
transform: rotateY(0deg) rotateX(-20deg);
72+
}
73+
to {
74+
transform: rotateY(360deg) rotateX(-20deg);
75+
}
76+
}
77+
78+
@keyframes bgPlay {
79+
0% {
80+
filter: brightness(1);
81+
opacity: 1;
82+
}
83+
50% {
84+
filter: brightness(0.59);
85+
opacity: 1;
86+
}
87+
51% {
88+
filter: opacity(0.5);
89+
opacity: 1;
90+
}
91+
70% {
92+
filter: opacity(0.7);
93+
opacity: 1;
94+
}
95+
100% {
96+
filter: brightness(1);
97+
opacity: 1;
98+
}
99+
}
100+
101+
@keyframes twistRotate360 {
102+
from {
103+
transform: rotate(0deg);
104+
}
105+
to {
106+
transform: rotate(360deg);
107+
}
108+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from "react";
2+
import { ComponentStory, ComponentMeta } from "@storybook/react";
3+
import { Twist } from "./Twist";
4+
5+
export default {
6+
title: "rli/Twist",
7+
component: Twist
8+
} as ComponentMeta<typeof Twist>;
9+
10+
const Template: ComponentStory<typeof Twist> = args => <Twist {...args} />;
11+
12+
export const Primary = Template.bind({});
13+
14+
export const Secondary = Template.bind({});
15+
Secondary.args = {
16+
color: "#b7ac9a",
17+
text: true
18+
};
19+
20+
export const Small = Template.bind({});
21+
Small.args = {
22+
size: "small"
23+
};
24+
25+
export const Medium = Template.bind({});
26+
Medium.args = {
27+
size: "medium"
28+
};
29+
30+
export const Large = Template.bind({});
31+
Large.args = {
32+
size: "large"
33+
};

src/indicators/Twist/Twist.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"use strict";
2+
3+
import React from "react";
4+
5+
import { TwistProps } from "./Twist.types";
6+
import "./Twist.scss";
7+
import useFontsizeMapper from "../../hooks/useFontsizeMapper";
8+
9+
const Twist = (props: TwistProps) => {
10+
// Styles
11+
let styles: React.CSSProperties = Object(props?.style);
12+
13+
/* Size SETTINGS */
14+
let fontSize: string | number = useFontsizeMapper(props?.size);
15+
16+
// Setting size by specifying font-size in style attr
17+
// and modifying styles to exclude fontSize
18+
if (props?.style?.fontSize) {
19+
const { fontSize: cssFontSize, ...css } = props?.style;
20+
21+
styles = css;
22+
fontSize = cssFontSize;
23+
}
24+
25+
/* Color SETTINGS */
26+
// If Color property is a string, that is the color of all rings
27+
// If color property is an array, that is color for each rings
28+
const twistColor: string | string[] = props?.color ?? "";
29+
const twistColorStyles: React.CSSProperties =
30+
twistColor instanceof Array
31+
? { ...genStyleFromColorArr(twistColor) }
32+
: { ...genStyleFromColorStr(twistColor) };
33+
34+
return (
35+
<span
36+
className="rli-d-i-b twist-bounding-box"
37+
style={{ ...(fontSize && { fontSize }), ...twistColorStyles }}
38+
>
39+
<span className="rli-d-i-b twist-loader" style={{ ...styles }}>
40+
<span className="blade"></span>
41+
<span className="blade"></span>
42+
<span className="blade"></span>
43+
<span className="blade"></span>
44+
<span className="blade"></span>
45+
<span className="blade"></span>
46+
<span className="blade"></span>
47+
<span className="blade"></span>
48+
</span>
49+
50+
<span
51+
className="rli-d-i-b rli-text-format twist-text"
52+
style={{
53+
...(props?.textColor && {
54+
color: props?.textColor,
55+
mixBlendMode: "unset"
56+
})
57+
}}
58+
>
59+
{props?.text
60+
? typeof props?.text === "string" && props?.text.length
61+
? props?.text
62+
: "loading"
63+
: null}
64+
</span>
65+
</span>
66+
);
67+
};
68+
69+
export { Twist };
70+
71+
function genStyleFromColorStr(
72+
colorStr: string | undefined
73+
): React.CSSProperties {
74+
colorStr = colorStr ?? "";
75+
76+
const stylesObject: any = {};
77+
78+
stylesObject["color"] = colorStr;
79+
80+
return stylesObject;
81+
}
82+
83+
function genStyleFromColorArr(colorArr: string[]): React.CSSProperties {
84+
const stylesObject: any = {};
85+
86+
// NOT supporting Individual bubble coloring
87+
const [color] = colorArr;
88+
89+
stylesObject["color"] = color;
90+
91+
return stylesObject;
92+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { CommonProps } from "../common.types";
2+
export interface TwistProps extends CommonProps {}

src/indicators/Twist/index.ts

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

src/indicators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ export * from "./Mosaic";
88
export * from "./Riple";
99
export * from "./Seek";
1010
export * from "./GlidingBlink";
11+
export * from "./Twist";
1112

1213
export { CircularProgress as default };

0 commit comments

Comments
 (0)