mirror of
https://github.com/vercel/commerce.git
synced 2025-07-21 11:51:20 +00:00
✨ feat: Skeleton Common
This commit is contained in:
parent
1cc64c6fd0
commit
bfbdb23c70
@ -0,0 +1,32 @@
|
||||
@import '../../../styles/utilities';
|
||||
|
||||
$base-color: #ddd;
|
||||
$shine-color: #e8e8e8;
|
||||
$animation-duration: 1.6s;
|
||||
|
||||
@mixin background-gradient {
|
||||
background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
|
||||
background-size: 600px;
|
||||
}
|
||||
|
||||
.skeletonCommon:empty {
|
||||
margin: auto;
|
||||
height: 14rem;
|
||||
width: 14rem;
|
||||
animation: name duration timing-function delay iteration-count direction fill-mode;
|
||||
|
||||
@include background-gradient;
|
||||
animation: shine-lines $animation-duration infinite linear;
|
||||
}
|
||||
|
||||
@keyframes shine-lines {
|
||||
0% {
|
||||
background-position: -100px;
|
||||
}
|
||||
40% {
|
||||
background-position: 140px;
|
||||
}
|
||||
100% {
|
||||
background-position: 140px;
|
||||
}
|
||||
}
|
17
src/components/common/SkeletonCommon/SkeletonCommon.tsx
Normal file
17
src/components/common/SkeletonCommon/SkeletonCommon.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React from "react";
|
||||
import s from './SkeletonCommon.module.scss'
|
||||
|
||||
interface SkeletonCommonProps {
|
||||
children? : React.ReactNode;
|
||||
}
|
||||
|
||||
const SkeletonCommon = ({ children }: SkeletonCommonProps) => {
|
||||
|
||||
return (
|
||||
<div className={s.skeletonCommon}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SkeletonCommon
|
@ -0,0 +1,51 @@
|
||||
@import '../../../../../styles/utilities';
|
||||
|
||||
$base-color: #8F8F8F;
|
||||
$shine-color: #ebebeb;
|
||||
$animation-duration: 1.6s;
|
||||
$avatar-offset: 52 + 16;
|
||||
|
||||
@mixin background-gradient {
|
||||
background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
|
||||
background-size: 600px;
|
||||
}
|
||||
|
||||
.skeletonAvatar {
|
||||
|
||||
&.active {
|
||||
@include background-gradient;
|
||||
animation: shine-avatar $animation-duration infinite linear;
|
||||
}
|
||||
|
||||
&.circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.square {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&.small {
|
||||
width: 3.2rem;
|
||||
height: 3.2rem;
|
||||
}
|
||||
&.default {
|
||||
width: 4.8rem;
|
||||
height: 4.8rem;
|
||||
}
|
||||
&.large {
|
||||
width: 6.4rem;
|
||||
height: 6.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine-avatar {
|
||||
0% {
|
||||
background-position: -100px + $avatar-offset
|
||||
}
|
||||
|
||||
40%, 100% {
|
||||
background-position: 140px + $avatar-offset
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import s from './SkeletonAvatar.module.scss'
|
||||
|
||||
interface SkeletonAvatarProps {
|
||||
active?: boolean,
|
||||
shape?: "circle" | "square",
|
||||
size?: "small" | "default" | "large",
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const SkeletonAvatar = ({ active=true, shape="circle", size="default", children }: SkeletonAvatarProps) => {
|
||||
|
||||
return (
|
||||
<div className={classNames(s.skeletonAvatar, {
|
||||
[s.active] : active,
|
||||
[s[shape]] : shape,
|
||||
[s[size]] : size,
|
||||
})}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SkeletonAvatar
|
@ -0,0 +1,41 @@
|
||||
@import '../../../../../styles/utilities';
|
||||
|
||||
$base-color: #DDD;
|
||||
$shine-color: #ebebeb;
|
||||
$animation-duration: 2s;
|
||||
|
||||
@mixin background-gradient {
|
||||
background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.skeletonParagraph {
|
||||
@apply bg-white;
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
|
||||
.row {
|
||||
height: 2rem;
|
||||
margin: 1rem;
|
||||
animation: shine-lines $animation-duration infinite linear;
|
||||
@include background-gradient;
|
||||
}
|
||||
|
||||
.lastRow {
|
||||
height: 2rem;
|
||||
margin: 1rem;
|
||||
width: 85%;
|
||||
animation: shine-lines $animation-duration infinite linear;
|
||||
@include background-gradient;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine-lines {
|
||||
0% {
|
||||
background-position: -100px;
|
||||
}
|
||||
40%, 100% {
|
||||
background-position: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import s from './SkeletonParagraph.module.scss'
|
||||
|
||||
interface SkeletonParagraphProps {
|
||||
active?: boolean,
|
||||
rows?: number // number of rows in paragraph
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const SkeletonParagraph = ({ active=true, rows=2, children }: SkeletonParagraphProps) => {
|
||||
|
||||
return (
|
||||
<div className={classNames(s.skeletonParagraph, {
|
||||
[s.active] : active
|
||||
})}>
|
||||
{
|
||||
[...Array(rows)].map((e, i) => {
|
||||
if (i === rows-1) {
|
||||
return <p key={i} className={s.lastRow}></p>
|
||||
}
|
||||
return <p key={i} className={s.row}></p>
|
||||
})
|
||||
}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SkeletonParagraph
|
@ -0,0 +1,27 @@
|
||||
@import '../../../../../styles/utilities';
|
||||
|
||||
$base-color: #8F8F8F;
|
||||
$shine-color: #ebebeb;
|
||||
$animation-duration: 1.6s;
|
||||
|
||||
@mixin background-gradient {
|
||||
background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
|
||||
background-size: 600px;
|
||||
}
|
||||
|
||||
.skeletonTitle {
|
||||
&.active {
|
||||
@include background-gradient;
|
||||
animation: shine-lines $animation-duration infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine-lines {
|
||||
0% {
|
||||
background-position: -100px;
|
||||
}
|
||||
40%, 100% {
|
||||
background-position: 50rem;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import s from './SkeletonTitle.module.scss'
|
||||
|
||||
interface SkeletonTitleProps {
|
||||
active?: boolean,
|
||||
width: string | number, // number px
|
||||
height: string | number,
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const SkeletonTitle = ({ active=true, width, height, children }: SkeletonTitleProps) => {
|
||||
|
||||
const styles = {
|
||||
width: width,
|
||||
height: height
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={styles} className={classNames(s.skeletonTitle, {
|
||||
[s.active] : active
|
||||
})}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SkeletonTitle
|
Loading…
x
Reference in New Issue
Block a user