Skip to content

Commit

Permalink
feat(app-components): add loading spinner to button
Browse files Browse the repository at this point in the history
  • Loading branch information
rams23 committed Feb 3, 2021
1 parent 538445b commit cba2362
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ IconClear.args = {
label: 'Back to game',
leftIcon: <ArrowIcon />,
};

export const Loading = Template.bind({});

Loading.args = {
variant: 'default',
label: 'Button',
loading: true,
};
18 changes: 15 additions & 3 deletions packages/game-app/src/_shared/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { ButtonContent, NotHoverIconWrapper, StyledButton, Variants } from './Button.styled';
import Spinner from '../Spinner';

type Props = {
id?: string;
Expand All @@ -10,22 +11,33 @@ type Props = {
disabled?: boolean;
leftIcon?: React.ReactElement;
color?: React.ComponentProps<typeof StyledButton>['color'];
loading?: boolean;
};

const Button: React.FC<Props> = ({ variant = 'default', label, onClick, id, testId, disabled, leftIcon, color }) => {
const Button: React.FC<Props> = ({
variant = 'default',
label,
onClick,
id,
testId,
disabled,
leftIcon,
color,
loading,
}) => {
return (
<StyledButton
type="button"
id={id}
data-cy={testId || id}
disabled={disabled}
disabled={disabled || loading}
onClick={onClick}
variant={variant}
color={color}
>
<ButtonContent>
{leftIcon ? <NotHoverIconWrapper>{leftIcon}</NotHoverIconWrapper> : null}
{label}
{loading ? <Spinner /> : label}
</ButtonContent>
</StyledButton>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';

import Spinner from './Spinner';
import { Clear } from '../Input/Input.stories';

export default {
title: 'Components/Spinner',
component: Spinner,
argTypes: {},
} as Meta;

const Template: Story<React.ComponentProps<typeof Spinner>> = args => <Spinner {...args} />;

export const Default = Template.bind({});

Default.args = {};
Default.decorators = [
Story => (
<div style={{ padding: '50px', background: 'lightgray' }}>
<Story />
</div>
),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled, { keyframes } from 'styled-components';

const spinnerAnimation = keyframes`
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}`;

export const StyledSpinner = styled.div`
display: inline-block;
position: relative;
width: 30px;
height: 30px;
& > div.thumb {
box-sizing: border-box;
display: block;
position: absolute;
width: 30px;
height: 30px;
border: 4px solid #fff;
border-radius: 50%;
animation: ${spinnerAnimation} 1.2s linear infinite;
border-color: #fff transparent transparent transparent;
}
& > div.placeholder {
box-sizing: border-box;
display: block;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
border: 4px solid rgba(255, 255, 255, 0.5);
border-radius: 50%;
}
`;

StyledSpinner.displayName = 'StyledSpinner';
17 changes: 17 additions & 0 deletions packages/game-app/src/_shared/components/Spinner/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { StyledSpinner } from './Spinner.styled';

type Props = {};

const Spinner: React.FC<Props> = ({}) => {
return (
<StyledSpinner>
<div className="thumb"></div>
<div className="placeholder"></div>
</StyledSpinner>
);
};

Spinner.displayName = 'Spinner';

export default Spinner;
3 changes: 3 additions & 0 deletions packages/game-app/src/_shared/components/Spinner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Spinner from './Spinner';

export default Spinner;

0 comments on commit cba2362

Please sign in to comment.