Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

[FRNT-517] implement loader component #130

Merged
merged 5 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ui/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { ListItem, ListContainer } from './list';
export { Notification } from './notification';
export { Separator } from './separator';
export { Surface } from './surface';
export { Loader } from './loader';
export { Table, Thead, Tbody, Tr, Td, Th } from './table';
export { Text } from './text';
export { TextArea } from './text-area';
Expand Down
113 changes: 113 additions & 0 deletions src/ui/atoms/loader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import * as React from 'react';
import styled, { StyledComponent, keyframes } from 'styled-components';
import { Variant } from 'lib/types';
import { box } from 'ui/elements';

interface LoaderProps {
description?: string;
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
className?: string;
}

const LoaderBase = ({
description = 'Loading...',
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
variant = 'primary',
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
className,
}: LoaderProps & Variant) => {
return (
<div className={className} data-variant={variant}>
<div data-loader>
<svg viewBox="0 0 100 100" data-track>
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
<circle data-spinner cx={50} cy={50} r={45} strokeWidth={10} />
</svg>
<div data-text>{description}</div>
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
);
};

const trackAnimation = keyframes`
0% {
transform: rotateZ(0deg);
}

100% {
transform: rotateZ(360deg)
}
`;

const spinnerAnimation = keyframes`
0%,
25% {
stroke-dashoffset: 280;

transform: rotate(0);
}

50%,
75% {
stroke-dashoffset: 75;

transform: rotate(45deg);
}

100% {
stroke-dashoffset: 280;

transform: rotate(360deg);
}
`;

export const Loader = styled(LoaderBase)`
${box}
--local-size: calc(
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
1px * var(--woly-component-level) * var(--woly-main-level) * 4
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
);
--local-track-color: var(--woly-canvas-default);
--local-spinner-color: var(--woly-shape-default);

display: flex;
align-items: center;
justify-content: center;

box-sizing: border-box;
width: 100%;
height: 100%;

[data-loader] {
display: flex;
flex-direction: column;
align-items: center;
}

[data-track] {
width: var(--local-size);
height: var(--local-size);
margin-bottom: calc(var(--local-gap) * 2);
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved

transform-origin: 50% 50%;

animation: 2s linear infinite ${trackAnimation};

fill: transparent;
}

[data-track] circle {
transform-origin: 50% 50%;

animation: 1.4s ease-in-out infinite both ${spinnerAnimation};

stroke: var(--local-spinner-color);
stroke-linecap: round;
stroke-dashoffset: 280;
stroke-dasharray: 283;
}

[data-text] {
color: var(--woly-canvas-text-default);
font-weight: 400;
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
font-size: var(--woly-font-size);
line-height: var(--woly-line-height);
line-height: 21px;
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
text-align: center;
}
` as StyledComponent<'div', Record<string, unknown>, LoaderProps & Variant>;
36 changes: 36 additions & 0 deletions src/ui/atoms/loader/usage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: loader
category: atoms
package: 'woly'
---

import {Loader} from 'ui';
import {block, Playground} from 'lib/playground'

`Loader` component is used when retrieving data or performing slow computations, and help to notify users that loading is underway..
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
Description text below animated spinner provides more details on the current operation.

Use a `Loader` component whenever the wait time is anticipated to be longer than three seconds.

### Example

<Playground>
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
<block.H>
<div style={{ height: 300 }}>
<Loader description="Loading, please wait until all data is loaded" />
</div>
</block.H>
<block.S>
<div style={{ height: 100 }}>
<Loader variant="secondary" />
</div>
</block.S>
</Playground>

### Props

| Name | Type | Default | Description |
| ------------- | ---------------- | ------------ | ----------------------------------------------- |
| `description` | `string` | 'Loading...' | Description text below the animated spinner |
| `variant` | `string` | `'primary'` | Variant prop to style Input component |
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
| `...` | `HTMLDivElement` | `{}` | Other props are inherited from `HTMLDivElement` |