feat: design applications and first api calls
Co-authored-by: Walid <87608619+WalidKorchi@users.noreply.github.com>
This commit is contained in:
14
components/design/Loader/Loader.stories.tsx
Normal file
14
components/design/Loader/Loader.stories.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { Meta, Story } from '@storybook/react'
|
||||
|
||||
import { Loader as Component, LoaderProps } from './Loader'
|
||||
|
||||
const Stories: Meta = {
|
||||
title: 'Loader',
|
||||
component: Component
|
||||
}
|
||||
|
||||
export default Stories
|
||||
|
||||
export const Loader: Story<LoaderProps> = (arguments_) => (
|
||||
<Component {...arguments_} />
|
||||
)
|
20
components/design/Loader/Loader.test.tsx
Normal file
20
components/design/Loader/Loader.test.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
import { Loader } from './'
|
||||
|
||||
describe('<Loader />', () => {
|
||||
it('should render with correct width and height', async () => {
|
||||
const size = 20
|
||||
const { findByTestId } = render(<Loader width={size} height={size} />)
|
||||
const progressSpinner = await findByTestId('progress-spinner')
|
||||
expect(progressSpinner).toHaveStyle(`width: ${size}px`)
|
||||
expect(progressSpinner).toHaveStyle(`height: ${size}px`)
|
||||
})
|
||||
|
||||
it('should render with default width and height', async () => {
|
||||
const { findByTestId } = render(<Loader />)
|
||||
const progressSpinner = await findByTestId('progress-spinner')
|
||||
expect(progressSpinner).toHaveStyle('width: 50px')
|
||||
expect(progressSpinner).toHaveStyle('height: 50px')
|
||||
})
|
||||
})
|
81
components/design/Loader/Loader.tsx
Normal file
81
components/design/Loader/Loader.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
export interface LoaderProps {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
export const Loader: React.FC<LoaderProps> = (props) => {
|
||||
const { width = 50, height = 50 } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<div data-testid='progress-spinner' className='progress-spinner'>
|
||||
<svg className='progress-spinner-svg' viewBox='25 25 50 50'>
|
||||
<circle
|
||||
className='progress-spinner-circle'
|
||||
cx='50'
|
||||
cy='50'
|
||||
r='20'
|
||||
fill='none'
|
||||
strokeWidth='2'
|
||||
strokeMiterlimit='10'
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style jsx>
|
||||
{`
|
||||
.progress-spinner {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: ${width}px;
|
||||
height: ${height}px;
|
||||
display: inline-block;
|
||||
}
|
||||
.progress-spinner::before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
.progress-spinner-svg {
|
||||
animation: progress-spinner-rotate 2s linear infinite;
|
||||
height: 100%;
|
||||
transform-origin: center center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
.progress-spinner-circle {
|
||||
stroke-dasharray: 89, 200;
|
||||
stroke-dashoffset: 0;
|
||||
stroke: #27b05e;
|
||||
animation: progress-spinner-dash 1.5s ease-in-out infinite;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
@keyframes progress-spinner-rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes progress-spinner-dash {
|
||||
0% {
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
50% {
|
||||
stroke-dasharray: 89, 200;
|
||||
stroke-dashoffset: -35px;
|
||||
}
|
||||
100% {
|
||||
stroke-dasharray: 89, 200;
|
||||
stroke-dashoffset: -124px;
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</>
|
||||
)
|
||||
}
|
1
components/design/Loader/index.ts
Normal file
1
components/design/Loader/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './Loader'
|
Reference in New Issue
Block a user