Skip to content

Commit

Permalink
feat: migrate AnimatedPlaceholder component
Browse files Browse the repository at this point in the history
Migrate AnimatedPlaceholder component from nodejs.dev
and create a new Story.

Fixes: nodejs#5193
  • Loading branch information
HinataKah0 committed Apr 7, 2023
1 parent e7071b1 commit 2b4f006
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import AnimatedPlaceholder from './index';

export default { component: AnimatedPlaceholder };

export const Default = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AnimatedPlaceholder component should render correctly with default skeleton 1`] = `
<div>
<div
class="placeholder"
style="width: 400px; height: 50px;"
>
<div
class="placeholderImage"
/>
<div
class="placeholderText"
>
<div
class="placeholderTextLine"
/>
<div
class="placeholderTextLine"
/>
</div>
</div>
</div>
`;

exports[`AnimatedPlaceholder component should support passing loader skeleton from outside 1`] = `
<div>
<div
class="placeholder"
style="width: 400px; height: 50px;"
>
<div
class="animated-placeholder__image"
/>
</div>
</div>
`;
20 changes: 20 additions & 0 deletions components/Common/AnimatedPlaceholder/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { render } from '@testing-library/react';
import AnimatedPlaceholder from './../index';

describe('AnimatedPlaceholder component', () => {
it('should render correctly with default skeleton', () => {
const { container } = render(<AnimatedPlaceholder />);

expect(container).toMatchSnapshot();
});

it('should support passing loader skeleton from outside', () => {
const { container } = render(
<AnimatedPlaceholder>
<div className="animated-placeholder__image" />
</AnimatedPlaceholder>
);

expect(container).toMatchSnapshot();
});
});
47 changes: 47 additions & 0 deletions components/Common/AnimatedPlaceholder/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.animatedBackground,
%animated-background {
animation-duration: 1.25s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f6f6;
background: linear-gradient(to right, #f6f6f6 8%, #f0f0f0 18%, #f6f6f6 33%);
background-size: 800px 104px;
height: 96px;
position: relative;
}

.placeholder {
display: flex;
width: 100%;

@keyframes placeHolderShimmer {
0% {
background-position: -468px 0;
}
100% {
background-position: 468px 0;
}
}

&Image {
@extend %animated-background;

height: 40px;
margin-right: 5px;
min-width: 40px;
}

&Text {
width: 100%;
}

&TextLine {
@extend %animated-background;

height: 10px;
margin: 4px 0;
width: 100%;
}
}
33 changes: 33 additions & 0 deletions components/Common/AnimatedPlaceholder/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import styles from './index.module.scss';

interface Props {
children?: React.ReactNode;
width?: number;
height?: number;
}

const AnimatedPlaceholder = ({
children,
width = 400,
height = 50,
}: Props) => (
<div
className={styles.placeholder}
style={{ width: `${width}px`, height: `${height}px` }}
>
{/* Prefer external skeleton structure or render default in case not passed */}
{children}
{!children && (
<>
<div className={styles.placeholderImage} />
<div className={styles.placeholderText}>
<div className={styles.placeholderTextLine} />
<div className={styles.placeholderTextLine} />
</div>
</>
)}
</div>
);

export default AnimatedPlaceholder;

0 comments on commit 2b4f006

Please sign in to comment.