Skip to content

Commit

Permalink
feat(core-components-button): add loading state
Browse files Browse the repository at this point in the history
* feat(core-components-loader): add new component

* feat(core-components-button): add loading state

* feat(core-components-button): add delayed loading

* feat(core-components-button): add css delay, instead js

* test(core-components-button): add snapshot

* chore: update deps

* refactor(core-components-button): review fixes

* feat(core-components-button): remove loader showing delay
  • Loading branch information
dmitrsavk committed May 28, 2020
1 parent 24f0c35 commit 5c0a75a
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 2 deletions.
3 changes: 3 additions & 0 deletions packages/button/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"peerDependencies": {
"classnames": "^2.2.6",
"react": "^16.9.0"
},
"dependencies": {
"@alfalab/core-components-loader": "^1.0.0"
}
}
56 changes: 54 additions & 2 deletions packages/button/src/Component.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Icon from '@alfalab/icons-glyph/StarMIcon';
import { Button } from './Component';
import { name, version } from '../package.json';


export const VIEWS = ['primary', 'secondary', 'outlined', 'link', 'ghost'];
export const SIZES = ['xs', 's', 'm', 'l'];

Expand All @@ -27,7 +26,7 @@ import { Button } from '@alfalab/core-components-button';

<Story name='Песочница'>
<Button
view={select('view', VIEWS)}
view={select('view', VIEWS, 'primary')}
size={select('size', SIZES, 'm')}
type={select('type', ['button', 'reset', 'submit'])}
href={text('href', '')}
Expand All @@ -36,6 +35,7 @@ import { Button } from '@alfalab/core-components-button';
className={text('className', '')}
dataTestId={text('dataTestId', '')}
onClick={action('click')}
loading={boolean('loading')}
>
{text('label', 'Оплатить')}
</Button>
Expand Down Expand Up @@ -177,3 +177,55 @@ import { Button } from '@alfalab/core-components-button';
</Row>
</Container>
</Preview>

## Состояние загрузки
С помощью свойства `loading` можно отрисовать состояние загрузки.

<Preview>
{React.createElement(() => {
const [loading, setLoading] = React.useState({
primary: false,
secondary: false,
outlined: false,
link: false,
ghost: false
});
const handleClick = (buttonName) => {
setLoading({...loading, [buttonName]: true});
setTimeout(() => {
setLoading({...loading, [buttonName]: false});
}, 500)
}
return (
<Container>
<Row align="middle">
<Col>
<Button view="primary" loading={loading.primary} onClick={() => handleClick('primary')}>
Отправить запрос
</Button>
</Col>
<Col>
<Button view="secondary" loading={loading.secondary} onClick={() => handleClick('secondary')}>
Отправить запрос
</Button>
</Col>
<Col>
<Button view="outlined" loading={loading.outlined} onClick={() => handleClick('outlined')}>
Отправить запрос
</Button>
</Col>
<Col>
<Button view="link" loading={loading.link} onClick={() => handleClick('link')}>
Отправить запрос
</Button>
</Col>
<Col>
<Button view="ghost" loading={loading.ghost} onClick={() => handleClick('ghost')}>
Отправить запрос
</Button>
</Col>
</Row>
</Container>
);
})}
</Preview>
4 changes: 4 additions & 0 deletions packages/button/src/Component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ describe('Button', () => {
it('should render anchor if href pass', () => {
expect(render(<Button href='https://some-url' />)).toMatchSnapshot();
});

it('should render loader if loading pass', () => {
expect(render(<Button loading={true} />)).toMatchSnapshot();
});
});

describe('Attributes tests', () => {
Expand Down
12 changes: 12 additions & 0 deletions packages/button/src/Component.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react';
import cn from 'classnames';

import { Loader } from '@alfalab/core-components-loader';

import styles from './index.module.css';

type ComponentProps = {
Expand Down Expand Up @@ -43,6 +45,11 @@ type ComponentProps = {
* Идентификатор для систем автоматизированного тестирования
*/
dataTestId?: string;

/**
* Показать лоадер
*/
loading?: boolean;
};

type AnchorButtonProps = ComponentProps & AnchorHTMLAttributes<HTMLAnchorElement>;
Expand All @@ -61,6 +68,8 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu
className,
dataTestId,
href,
loading = false,
disabled = false,
...restProps
},
ref,
Expand All @@ -73,10 +82,12 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu
{
[styles.block]: block,
[styles.iconOnly]: !children,
[styles.loading]: loading,
},
className,
),
'data-test-id': dataTestId || null,
disabled: disabled || loading,
};

const buttonChildren = (
Expand All @@ -99,6 +110,7 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu
// eslint-disable-next-line react/button-has-type
<button {...componentProps} {...restProps} ref={ref}>
{buttonChildren}
{loading && <Loader className={cn(styles.loader)} />}
</button>
);
},
Expand Down
117 changes: 117 additions & 0 deletions packages/button/src/__snapshots__/Component.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,123 @@ Object {
}
`;

exports[`Button Snapshots tests should render loader if loading pass 1`] = `
Object {
"asFragment": [Function],
"baseElement": <body>
<div>
<button
class="component secondary m iconOnly loading"
disabled=""
>
<svg
class="component loader"
height="24"
viewBox="0 0 24 24"
width="24"
>
<circle
cx="4"
cy="12"
r="2"
/>
<circle
cx="12"
cy="12"
r="2"
/>
<circle
cx="20"
cy="12"
r="2"
/>
</svg>
</button>
</div>
</body>,
"container": <div>
<button
class="component secondary m iconOnly loading"
disabled=""
>
<svg
class="component loader"
height="24"
viewBox="0 0 24 24"
width="24"
>
<circle
cx="4"
cy="12"
r="2"
/>
<circle
cx="12"
cy="12"
r="2"
/>
<circle
cx="20"
cy="12"
r="2"
/>
</svg>
</button>
</div>,
"debug": [Function],
"findAllByAltText": [Function],
"findAllByDisplayValue": [Function],
"findAllByLabelText": [Function],
"findAllByPlaceholderText": [Function],
"findAllByRole": [Function],
"findAllByTestId": [Function],
"findAllByText": [Function],
"findAllByTitle": [Function],
"findByAltText": [Function],
"findByDisplayValue": [Function],
"findByLabelText": [Function],
"findByPlaceholderText": [Function],
"findByRole": [Function],
"findByTestId": [Function],
"findByText": [Function],
"findByTitle": [Function],
"getAllByAltText": [Function],
"getAllByDisplayValue": [Function],
"getAllByLabelText": [Function],
"getAllByPlaceholderText": [Function],
"getAllByRole": [Function],
"getAllByTestId": [Function],
"getAllByText": [Function],
"getAllByTitle": [Function],
"getByAltText": [Function],
"getByDisplayValue": [Function],
"getByLabelText": [Function],
"getByPlaceholderText": [Function],
"getByRole": [Function],
"getByTestId": [Function],
"getByText": [Function],
"getByTitle": [Function],
"queryAllByAltText": [Function],
"queryAllByDisplayValue": [Function],
"queryAllByLabelText": [Function],
"queryAllByPlaceholderText": [Function],
"queryAllByRole": [Function],
"queryAllByTestId": [Function],
"queryAllByText": [Function],
"queryAllByTitle": [Function],
"queryByAltText": [Function],
"queryByDisplayValue": [Function],
"queryByLabelText": [Function],
"queryByPlaceholderText": [Function],
"queryByRole": [Function],
"queryByTestId": [Function],
"queryByText": [Function],
"queryByTitle": [Function],
"rerender": [Function],
"unmount": [Function],
}
`;

exports[`Button Snapshots tests should render right addons 1`] = `
Object {
"asFragment": [Function],
Expand Down
31 changes: 31 additions & 0 deletions packages/button/src/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@
cursor: initial;
}

.loading .text,
.loading .addons {
opacity: 0;
}

.loader {
position: absolute;
}

/* Size */

.xs {
Expand Down Expand Up @@ -123,6 +132,10 @@
&:disabled {
background-color: var(--button-primary-disabled-bg-color);
}

&.loading {
background-color: var(--button-primary-base-bg-color);
}
}

.secondary {
Expand All @@ -141,6 +154,11 @@
color: var(--color-dark-indigo-30);
background-color: var(--button-secondary-disabled-bg-color);
}

&.loading {
color: var(--color-dark-indigo);
background-color: var(--button-secondary-base-bg-color);
}
}

.outlined {
Expand All @@ -161,6 +179,11 @@
background-color: transparent;
border-color: var(--color-dark-indigo-10);
}

&.loading {
color: var(--color-dark-indigo);
border-color: var(--color-dark-indigo-60);
}
}

.link {
Expand All @@ -180,6 +203,10 @@
color: var(--color-dark-indigo-30);
background-color: transparent;
}

&.loading {
color: var(--color-dark-indigo);
}
}

.ghost {
Expand All @@ -203,6 +230,10 @@
color: var(--button-ghost-disabled-color);
}

&.loading {
color: var(--button-ghost-base-color);
}

&.iconOnly {
min-width: 0;
}
Expand Down

0 comments on commit 5c0a75a

Please sign in to comment.