@arnonsang/react-loading
Version:
A highly customizable React loading component library with 17 beautiful animations, and flexible children API
840 lines (771 loc) • 14 kB
CSS
/* Loading Component Styles */
.loading-container {
--color-primary: var(--loading-color, #667eea);
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 2rem;
}
.loading-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1.2rem;
padding: 0.5rem;
}
.loading-text {
font-size: 0.875rem;
color: #718096;
text-align: center;
}
.loading-fullpage {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
/* Size Classes */
.loading-xs {
width: 0.75rem;
height: 0.75rem;
}
.loading-sm {
width: 1.25rem;
height: 1.25rem;
}
.loading-md {
width: 2.25rem;
height: 2.25rem;
}
.loading-lg {
width: 3.5rem;
height: 3.5rem;
}
.loading-xl {
width: 5rem;
height: 5rem;
}
.loading-2xl {
width: 7rem;
height: 7rem;
}
/* Spinner Animation */
.loading-spinner {
border-radius: 50%;
border: 3px solid #e5e7eb;
border-top-color: var(--color-primary);
animation: spin 1s linear infinite;
}
/* Dots Animation */
.loading-dots {
display: flex;
align-items: center;
gap: 0.35em;
}
.loading-dot {
border-radius: 50%;
background: var(--color-primary);
animation: dotDance 1.6s ease-in-out infinite;
}
.loading-dots.loading-xs .loading-dot {
width: 0.25em;
height: 0.25em;
}
.loading-dots.loading-sm .loading-dot {
width: 0.4em;
height: 0.4em;
}
.loading-dots.loading-md .loading-dot {
width: 0.6em;
height: 0.6em;
}
.loading-dots.loading-lg .loading-dot {
width: 0.8em;
height: 0.8em;
}
.loading-dots.loading-xl .loading-dot {
width: 1em;
height: 1em;
}
.loading-dots.loading-2xl .loading-dot {
width: 1.2em;
height: 1.2em;
}
.loading-dot:nth-child(1) {
animation-delay: 0s;
}
.loading-dot:nth-child(2) {
animation-delay: 0.2s;
}
.loading-dot:nth-child(3) {
animation-delay: 0.4s;
}
/* Pulse Animation */
.loading-pulse {
border-radius: 50%;
background: var(--color-primary);
animation: pulseWave 2.5s infinite;
}
/* Bars Animation */
.loading-bars {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 0.15em;
height: 100%;
}
.loading-bars.loading-xs {
gap: 0.08em;
}
.loading-bars.loading-sm {
gap: 0.12em;
}
.loading-bars.loading-md {
gap: 0.15em;
}
.loading-bars.loading-lg {
gap: 0.2em;
}
.loading-bars.loading-xl {
gap: 0.25em;
}
.loading-bars.loading-2xl {
gap: 0.3em;
}
.loading-bars .bar {
width: 0.35em;
min-height: 0.4em;
border-radius: 0.2em 0.2em 0 0;
background: var(--color-primary);
animation: barRise 1.8s ease-in-out infinite;
transform-origin: bottom center;
}
.loading-bars.loading-xs .bar {
width: 0.2em;
min-height: 0.25em;
}
.loading-bars.loading-sm .bar {
width: 0.28em;
min-height: 0.32em;
}
.loading-bars.loading-md .bar {
width: 0.35em;
min-height: 0.4em;
}
.loading-bars.loading-lg .bar {
width: 0.45em;
min-height: 0.5em;
}
.loading-bars.loading-xl .bar {
width: 0.55em;
min-height: 0.6em;
}
.loading-bars.loading-2xl .bar {
width: 0.7em;
min-height: 0.8em;
}
.loading-bars .bar:nth-child(1) {
animation-delay: 0s;
}
.loading-bars .bar:nth-child(2) {
animation-delay: 0.2s;
}
.loading-bars .bar:nth-child(3) {
animation-delay: 0.4s;
}
.loading-bars .bar:nth-child(4) {
animation-delay: 0.6s;
}
.loading-bars .bar:nth-child(5) {
animation-delay: 0.8s;
}
/* Bubbles Animation */
.loading-bubbles {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-bubbles .bubble {
position: absolute;
width: 0.5em;
height: 0.5em;
border-radius: 50%;
background: var(--color-primary);
animation: bubbleFloat 2s ease-in-out infinite;
}
/* Cylon Animation */
.loading-cylon {
position: relative;
width: 100%;
height: 0.4em;
border-radius: 0.3em;
background: linear-gradient(
to right,
rgba(102, 126, 234, 0.1) 0%,
rgba(102, 126, 234, 0.3) 50%,
rgba(102, 126, 234, 0.1) 100%
);
overflow: hidden;
min-width: 3rem;
}
.loading-cylon.loading-xs {
height: 0.2em;
min-width: 2rem;
}
.loading-cylon.loading-sm {
height: 0.3em;
min-width: 2.5rem;
}
.loading-cylon.loading-md {
height: 0.4em;
min-width: 3rem;
}
.loading-cylon.loading-lg {
height: 0.6em;
min-width: 4rem;
}
.loading-cylon.loading-xl {
height: 0.8em;
min-width: 5rem;
}
.loading-cylon.loading-2xl {
height: 1em;
min-width: 6rem;
}
.loading-cylon .cylon-line {
position: absolute;
width: 25%;
height: 100%;
border-radius: 0.3em;
background: var(--color-primary);
animation: cylonScan 3s ease-in-out infinite;
}
/* Spinning Bubbles Animation */
.loading-spinning-bubbles {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spinning-bubbles .bubble {
position: absolute;
width: 0.4em;
height: 0.4em;
border-radius: 50%;
background: var(--color-primary);
animation: orbitSpin 2.8s linear infinite;
}
/* Ripple Animation */
.loading-ripple {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-ripple .ripple-circle {
position: absolute;
border: 2px solid var(--color-primary);
border-radius: 50%;
width: 100%;
height: 100%;
animation: rippleExpand 1.5s ease-out infinite;
}
/* Wave Animation */
.loading-wave {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 0.2em;
height: 100%;
}
.loading-wave.loading-xs {
gap: 0.1em;
}
.loading-wave.loading-sm {
gap: 0.15em;
}
.loading-wave.loading-md {
gap: 0.2em;
}
.loading-wave.loading-lg {
gap: 0.25em;
}
.loading-wave.loading-xl {
gap: 0.3em;
}
.loading-wave.loading-2xl {
gap: 0.4em;
}
.loading-wave .wave-dot {
width: 0.3em;
height: 0.3em;
border-radius: 50%;
background: var(--color-primary);
animation: waveMotion 1.2s ease-in-out infinite;
}
.loading-wave.loading-xs .wave-dot {
width: 0.15em;
height: 0.15em;
}
.loading-wave.loading-sm .wave-dot {
width: 0.22em;
height: 0.22em;
}
.loading-wave.loading-md .wave-dot {
width: 0.3em;
height: 0.3em;
}
.loading-wave.loading-lg .wave-dot {
width: 0.4em;
height: 0.4em;
}
.loading-wave.loading-xl .wave-dot {
width: 0.5em;
height: 0.5em;
}
.loading-wave.loading-2xl .wave-dot {
width: 0.6em;
height: 0.6em;
}
/* Orbit Animation */
.loading-orbit {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-orbit .orbit-center {
width: 0.5em;
height: 0.5em;
border-radius: 50%;
background: var(--color-primary);
position: absolute;
}
.loading-orbit .orbit-dot {
position: absolute;
width: 0.3em;
height: 0.3em;
border-radius: 50%;
background: var(--color-primary);
animation: orbitRotate 2s linear infinite;
}
/* Bounce Animation */
.loading-bounce {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: flex-end;
justify-content: center;
}
.loading-bounce .bounce-ball {
width: 0.8em;
height: 0.8em;
border-radius: 50%;
background: var(--color-primary);
animation: bounceBall 1.5s ease-in-out infinite;
}
.loading-bounce .bounce-shadow {
position: absolute;
bottom: 0;
width: 0.6em;
height: 0.15em;
border-radius: 50%;
background: rgba(0, 0, 0, 0.2);
animation: bounceShadow 1.5s ease-in-out infinite;
}
/* Snake Animation */
.loading-snake {
display: flex;
align-items: center;
justify-content: center;
gap: 0.1em;
width: 100%;
height: 100%;
}
.loading-snake.loading-xs {
gap: 0.05em;
}
.loading-snake.loading-sm {
gap: 0.08em;
}
.loading-snake.loading-md {
gap: 0.1em;
}
.loading-snake.loading-lg {
gap: 0.12em;
}
.loading-snake.loading-xl {
gap: 0.15em;
}
.loading-snake.loading-2xl {
gap: 0.2em;
}
.loading-snake .snake-segment {
width: 0.3em;
height: 0.3em;
border-radius: 50%;
background: var(--color-primary);
animation: snakeMove 1.6s ease-in-out infinite;
}
.loading-snake.loading-xs .snake-segment {
width: 0.15em;
height: 0.15em;
}
.loading-snake.loading-sm .snake-segment {
width: 0.22em;
height: 0.22em;
}
.loading-snake.loading-md .snake-segment {
width: 0.3em;
height: 0.3em;
}
.loading-snake.loading-lg .snake-segment {
width: 0.4em;
height: 0.4em;
}
.loading-snake.loading-xl .snake-segment {
width: 0.5em;
height: 0.5em;
}
.loading-snake.loading-2xl .snake-segment {
width: 0.6em;
height: 0.6em;
}
/* Grid Animation */
.loading-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 0.1em;
width: 100%;
height: 100%;
}
.loading-grid.loading-xs {
gap: 0.05em;
}
.loading-grid.loading-sm {
gap: 0.08em;
}
.loading-grid.loading-md {
gap: 0.1em;
}
.loading-grid.loading-lg {
gap: 0.12em;
}
.loading-grid.loading-xl {
gap: 0.15em;
}
.loading-grid.loading-2xl {
gap: 0.2em;
}
.loading-grid .grid-square {
background: var(--color-primary);
border-radius: 0.1em;
animation: gridPulse 1.8s ease-in-out infinite;
min-height: 0.2em;
min-width: 0.2em;
}
/* Heart Animation */
.loading-heart {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-heart .heart-shape {
position: relative;
width: 1em;
height: 0.8em;
animation: heartBeat 1.2s ease-in-out infinite;
}
.loading-heart .heart-shape::before,
.loading-heart .heart-shape::after {
content: "";
position: absolute;
width: 0.5em;
height: 0.8em;
background: var(--color-primary);
border-radius: 0.5em 0.5em 0 0;
transform-origin: 0 1em;
}
.loading-heart .heart-shape::before {
left: 0.5em;
transform: rotate(-45deg);
}
.loading-heart .heart-shape::after {
left: -0.1rem;
top: -0.35em;
transform: rotate(45deg);
}
/* Spiral Animation */
.loading-spiral {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spiral .spiral-dot {
position: absolute;
width: 0.25em;
height: 0.25em;
border-radius: 50%;
background: var(--color-primary);
animation: spiralRotate 2.4s linear infinite;
}
/* Skeleton Animation */
.loading-skeleton {
width: 80%;
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.loading-skeleton.loading-xs {
gap: 0.2rem;
}
.loading-skeleton.loading-sm {
gap: 0.3rem;
}
.loading-skeleton.loading-md {
gap: 0.4rem;
}
.loading-skeleton.loading-lg {
gap: 0.5rem;
}
.loading-skeleton.loading-xl {
gap: 0.6rem;
}
.loading-skeleton.loading-2xl {
gap: 0.8rem;
}
.skeleton-line {
height: 0.6rem;
border-radius: 0.5rem;
background: linear-gradient(
110deg,
#e2e8f0 8%,
#f1f5f9 18%,
#e2e8f0 33%
);
background-size: 200% 100%;
animation: skeletonShine 2s linear infinite;
}
.loading-skeleton.loading-xs .skeleton-line {
height: 0.3rem;
}
.loading-skeleton.loading-sm .skeleton-line {
height: 0.45rem;
}
.loading-skeleton.loading-md .skeleton-line {
height: 0.6rem;
}
.loading-skeleton.loading-lg .skeleton-line {
height: 0.8rem;
}
.loading-skeleton.loading-xl .skeleton-line {
height: 1rem;
}
.loading-skeleton.loading-2xl .skeleton-line {
height: 1.2rem;
}
/* Animations */
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes dotDance {
0%,
80%,
100% {
transform: scale(0.9) translateY(0);
}
40% {
transform: scale(1.3) translateY(-0.8em);
}
}
@keyframes pulseWave {
0%,
100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.2);
opacity: 0.6;
}
}
@keyframes barRise {
0%,
100% {
transform: scaleY(0.3);
}
50% {
transform: scaleY(1.2);
}
}
@keyframes bubbleFloat {
0%,
80%,
100% {
transform: scale(0);
opacity: 0;
}
40% {
transform: scale(1);
opacity: 1;
}
}
@keyframes cylonScan {
0% {
transform: translateX(-120%);
opacity: 0;
}
20%,
80% {
opacity: 1;
}
100% {
transform: translateX(420%);
opacity: 0;
}
}
@keyframes orbitSpin {
0% {
transform: rotate(0deg) translateX(1.5em) rotate(0deg);
}
100% {
transform: rotate(360deg) translateX(1.5em) rotate(-360deg);
}
}
@keyframes rippleExpand {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(2);
opacity: 0;
}
}
@keyframes waveMotion {
0%,
60%,
100% {
transform: scaleY(0.4);
}
30% {
transform: scaleY(1.6);
}
}
@keyframes orbitRotate {
0% {
transform: rotate(0deg) translateX(1.5em) rotate(0deg);
}
100% {
transform: rotate(360deg) translateX(1.5em) rotate(-360deg);
}
}
@keyframes bounceBall {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-2em);
}
}
@keyframes bounceShadow {
0%,
100% {
transform: scale(1);
opacity: 0.3;
}
50% {
transform: scale(0.5);
opacity: 0.1;
}
}
@keyframes snakeMove {
0%,
100% {
transform: scale(0.8);
opacity: 0.6;
}
50% {
transform: scale(1.2);
opacity: 1;
}
}
@keyframes gridPulse {
0%,
100% {
transform: scale(0.8);
opacity: 0.6;
}
50% {
transform: scale(1);
opacity: 1;
}
}
@keyframes heartBeat {
0%,
100% {
transform: scale(1);
}
25%,
75% {
transform: scale(1.1);
}
50% {
transform: scale(1.3);
}
}
@keyframes spiralRotate {
0% {
transform: rotate(0deg) translateX(1.2em) scale(0);
opacity: 0;
}
25% {
opacity: 1;
transform: rotate(90deg) translateX(1.2em) scale(1);
}
75% {
opacity: 1;
transform: rotate(270deg) translateX(1.2em) scale(1);
}
100% {
transform: rotate(360deg) translateX(1.2em) scale(0);
opacity: 0;
}
}
@keyframes skeletonShine {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}