From e154724fefdea917d8e3f6a49cc374dcbd02a609 Mon Sep 17 00:00:00 2001 From: sonnguyenkieio Date: Mon, 13 Sep 2021 15:46:08 +0700 Subject: [PATCH] :sparkles: feat: Skeleton Common --- .../SkeletonCommon/SkeletonCommon.module.scss | 32 ---------- .../common/SkeletonCommon/SkeletonCommon.tsx | 17 ----- .../SkeletonImage/SkeletonImage.module.scss | 53 ++++++++++++++++ .../SkeletonImage/SkeletonImage.tsx | 22 +++++++ .../SkeletonParagraph.module.scss | 63 +++++++++++++++++++ .../SkeletonParagraph/SkeletonParagraph.tsx | 31 +++++++++ .../SkeletonAvatar/SkeletonAvatar.module.scss | 51 --------------- .../SkeletonAvatar/SkeletonAvatar.tsx | 25 -------- .../SkeletonParagraph.module.scss | 41 ------------ .../SkeletonParagraph/SkeletonParagraph.tsx | 30 --------- .../SkeletonTitle/SkeletonTitle.module.scss | 27 -------- .../SkeletonTitle/SkeletonTitle.tsx | 28 --------- 12 files changed, 169 insertions(+), 251 deletions(-) delete mode 100644 src/components/common/SkeletonCommon/SkeletonCommon.module.scss delete mode 100644 src/components/common/SkeletonCommon/SkeletonCommon.tsx create mode 100644 src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss create mode 100644 src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx create mode 100644 src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss create mode 100644 src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss delete mode 100644 src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx diff --git a/src/components/common/SkeletonCommon/SkeletonCommon.module.scss b/src/components/common/SkeletonCommon/SkeletonCommon.module.scss deleted file mode 100644 index e388525e5..000000000 --- a/src/components/common/SkeletonCommon/SkeletonCommon.module.scss +++ /dev/null @@ -1,32 +0,0 @@ -@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; - } -} \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/SkeletonCommon.tsx b/src/components/common/SkeletonCommon/SkeletonCommon.tsx deleted file mode 100644 index 6b0631aef..000000000 --- a/src/components/common/SkeletonCommon/SkeletonCommon.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import s from './SkeletonCommon.module.scss' - -interface SkeletonCommonProps { - children? : React.ReactNode; -} - -const SkeletonCommon = ({ children }: SkeletonCommonProps) => { - - return ( -
- {children} -
- ) -} - -export default SkeletonCommon \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss new file mode 100644 index 000000000..57fdf3ebc --- /dev/null +++ b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss @@ -0,0 +1,53 @@ +@import '../../../../styles/utilities'; + +.skeletonImage:empty { + @apply relative; + background: #DDDBDD; + + &.small { + width: 10rem; + height: 10rem; + } + + &.default { + width: 15rem; + height: 15rem; + } + + &.large { + width: 20rem; + height: 20rem; + } + + &.left { + margin-left: 0; + } + + &.center { + margin: auto; + } + + &::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + transform: translateX(-100%); + background-image: linear-gradient( + 90deg, + rgba(#fff, 0) 0, + rgba(#fff, 0.2) 20%, + rgba(#fff, 0.5) 60%, + rgba(#fff, 0) + ); + animation: shimmer 2s infinite; + content: ''; + } +} + +@keyframes shimmer { + 100% { + transform: translateX(100%); + } +} diff --git a/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx new file mode 100644 index 000000000..7ab20b037 --- /dev/null +++ b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx @@ -0,0 +1,22 @@ +import classNames from "classnames"; +import React from "react"; +import s from './SkeletonImage.module.scss' + +interface SkeletonImageProps { + align?: "left" | "center" + size?: "small" | "default" | "large" + children?: React.ReactNode +} + +const SkeletonImage = ({ align="center", size="default", children }: SkeletonImageProps) => { + return ( +
+ {children} +
+ ) +} + +export default SkeletonImage \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss new file mode 100644 index 000000000..2c98d00e5 --- /dev/null +++ b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss @@ -0,0 +1,63 @@ +@import '../../../../styles/utilities'; + +.skeletonParagraph { + .row { + display: inline-block; + height: 2rem; + width: 100%; + position: relative; + overflow: hidden; + background-color: #DDDBDD; + + &::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + transform: translateX(-100%); + background-image: linear-gradient( + 90deg, + rgba(#fff, 0) 0, + rgba(#fff, 0.2) 20%, + rgba(#fff, 0.5) 60%, + rgba(#fff, 0) + ); + animation: shimmer 2s infinite; + content: ''; + } + } + + .lastRow { + display: inline-block; + height: 2rem; + width: 80%; + position: relative; + overflow: hidden; + background-color: #DDDBDD; + + &::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + transform: translateX(-100%); + background-image: linear-gradient( + 90deg, + rgba(#fff, 0) 0, + rgba(#fff, 0.2) 20%, + rgba(#fff, 0.5) 60%, + rgba(#fff, 0) + ); + animation: shimmer 2s infinite; + content: ''; + } + } +} + +@keyframes shimmer { + 100% { + transform: translateX(100%); + } +} diff --git a/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx new file mode 100644 index 000000000..4baa35a52 --- /dev/null +++ b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx @@ -0,0 +1,31 @@ +import React, { useEffect, useState } from "react"; +import s from './SkeletonParagraph.module.scss' + +interface SkeletonParagraphProps { + rows?: number // number of rows in paragraph + children?: React.ReactNode +} + +const SkeletonParagraph = ({ rows=2, children }: SkeletonParagraphProps) => { + + const [isChildLoaded, setIsChildLoaded] = useState(false) + + useEffect(() => { + setIsChildLoaded(true); + }, []) + + return ( +
+ { + isChildLoaded ? children : [...Array(rows)].map((e, i) => { + if (i === rows-1) { + return
+ } + return
+ }) + } +
+ ) +} + +export default SkeletonParagraph \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss b/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss deleted file mode 100644 index 82286d7a0..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss +++ /dev/null @@ -1,51 +0,0 @@ -@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 - } - -} diff --git a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx b/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx deleted file mode 100644 index d5d20165b..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx +++ /dev/null @@ -1,25 +0,0 @@ -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 ( -
- {children} -
- ) -} - -export default SkeletonAvatar \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss b/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss deleted file mode 100644 index 259c1574c..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss +++ /dev/null @@ -1,41 +0,0 @@ -@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%; - } -} - diff --git a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx b/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx deleted file mode 100644 index 5c3620f0a..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx +++ /dev/null @@ -1,30 +0,0 @@ -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 ( -
- { - [...Array(rows)].map((e, i) => { - if (i === rows-1) { - return

- } - return

- }) - } - {children} -
- ) -} - -export default SkeletonParagraph \ No newline at end of file diff --git a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss b/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss deleted file mode 100644 index 0dbb139d3..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss +++ /dev/null @@ -1,27 +0,0 @@ -@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; - } -} - diff --git a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx b/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx deleted file mode 100644 index 40d747d8f..000000000 --- a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx +++ /dev/null @@ -1,28 +0,0 @@ -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 ( -
- {children} -
- ) -} - -export default SkeletonTitle \ No newline at end of file