// 희미해졌다 선명해졌다 하는 애니메이션
const pulseAni = keyframes`
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
`;
// skeleton 최상위 div 요소
const SkeletonBox = styled.div`
width: 300px;
height: fit-content;
padding: 1rem;
background-color: #1f1f1f;
border-radius: 5px;
animation: ${pulseAni} 3s ease infinite; // 애니메이션 적용
position: relative;
`;
// skeleton Title 요소
const SkeletonTitle = styled.div`
width: 100px;
height: 50px;
background-color: silver;
margin-bottom: 1rem;
animation: ${pulseAni} 2s ease infinite; // 애니메이션 적용
`;
// skeleton의 No Data가 쓰여지는 요소
const SkeletonText = styled.h2`
position: absolute;
top: 15%;
right: 15%;
color: white;
z-index: 1;
`;
// skeleton의 여러 줄을 묶어주는 div 요소
const PragraphContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.6rem;
`;
// skeleton의 여러 줄을 표현한 div 요소
const SkeletonParagraph = styled.div`
width: 100%;
height: 15px;
background-color: silver;
animation: ${pulseAni} 2s ease infinite; // 애니메이션 적용
`;
export default function Skeleton() {
const lineArr = Array(3); // 반복적으로 UI를 생성하기 위한 Array
return (
<SkeletonBox>
<SkeletonTitle />
<PragraphContainer>
{[...lineArr].map((el, i) => { // 여러 줄을 표현하는 요소를 반복 생성
return <SkeletonParagraph key={i} />;
})}
</PragraphContainer>
<SkeletonText>No Data</SkeletonText>
</SkeletonBox>
);
}
만약 데이터가 없다면 그곳은 skeleton 컴포넌트가 반짝거리고 있다..⭐
// Skeleton 컴포넌트 import
import Skeleton from "../Skeleton/Skeleton";
// MAIN COMPONENT
export default function List() {
// ReduxState
const reduxMessages = useSelector((state) => state.messages);
// 만약 데이터가 없다면 그곳은 skeleton 컴포넌트가 반짝거리고 있다..⭐
if (reduxMessages?.length === 0) {
return (
<MessageContainer>
<Skeleton />
</MessageContainer>
);
}