Skip to content

Commit

Permalink
[Chore] Update button loading prop usage (#125)
Browse files Browse the repository at this point in the history
* Rename loading to isLoading in RoundButton component

* Rename loading to isLoading in RoundButtonBase styled component

* Rename loading to isLoading in Button Loader component

* Rename loading to isLoading in ButtonLoader styled component

* Rename loading to isLoading in Button component

* Update isLoading throughout Button styled components

* Update snapshots and stories to use isLoading instead of loading

* Update markdown files with new isLoading prop, prettify

* Add deprecation warnings to use of 'loading' in Button and RoundButton
  • Loading branch information
michaeljaltamirano committed Jun 28, 2019
1 parent c2f9631 commit a6a5b35
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 113 deletions.
39 changes: 21 additions & 18 deletions docs/button/button.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Button

## Usage

```jsx
Expand All @@ -13,14 +14,14 @@ import { CheckmarkIcon } from 'radiance-ui/lib/icons';
<Button buttonType="quaternary">Quaternary Button</Button>
<Button disabled>Disabled Button</Button>

<Button loading>Primary Loading</Button>
<Button loading buttonType="secondary">
<Button isLoading>Primary Loading</Button>
<Button isLoading buttonType="secondary">
Secondary Loading
</Button>
<Button buttonType="tertiary" loading>
<Button buttonType="tertiary" isLoading>
Tertiary Loading
</Button>
<Button buttonType="quaternary" loading>
<Button buttonType="quaternary" isLoading>
Quaternary Loading
</Button>
</Button.Container>
Expand All @@ -40,36 +41,38 @@ import { CheckmarkIcon } from 'radiance-ui/lib/icons';
<Button disabled icon={<CheckmarkIcon />}>
Disabled Button
</Button>
<Button loading icon={<CheckmarkIcon />}>
<Button isLoading icon={<CheckmarkIcon />}>
Primary Loading
</Button>
<Button loading buttonType="secondary" icon={<CheckmarkIcon />}>
<Button isLoading buttonType="secondary" icon={<CheckmarkIcon />}>
Secondary Loading
</Button>
<Button loading buttonType="tertiary" icon={<CheckmarkIcon />}>
<Button isLoading buttonType="tertiary" icon={<CheckmarkIcon />}>
Tertiary Loading
</Button>
<Button loading buttonType="quaternary" icon={<CheckmarkIcon />}>
<Button isLoading buttonType="quaternary" icon={<CheckmarkIcon />}>
Quaternary Loading
</Button>
</Button.Container>
</React.Fragment>
</React.Fragment>;
```

<!-- STORY -->

### Proptypes
| prop | propType | required | default | description |
|----------|--------------------|----------|---------|------------------------------------------------------------------------------------------------------------------------------|
| buttonType | string | no | primary | Determines the button's main style theme. Must be one of `primary`, `secondary`, `tertiary`, `quaternary`. |
| children | node | yes | - | node to be rendered inside the button. Recommended to be the button text |
| disabled | bool | no | false | when disabled, click listener will not be called and the UI will look disabled |
| icon | node | no | null | icon to render in the button. Recommended to use one of Radiance's icons |
| loading | bool | no | false | renders loading state and prevents click listener from being called |
| onClick | func | no | () => {} | callback function called on click of the button |
| textColor | string | no | '' | color (as a string) that will override existing text, icon, and loading colors for the button (except when disabled is true) |

| prop | propType | required | default | description |
| ---------- | -------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| buttonType | string | no | primary | Determines the button's main style theme. Must be one of `primary`, `secondary`, `tertiary`, `quaternary`. |
| children | node | yes | - | node to be rendered inside the button. Recommended to be the button text |
| disabled | bool | no | false | when disabled, click listener will not be called and the UI will look disabled |
| icon | node | no | null | icon to render in the button. Recommended to use one of Radiance's icons |
| isLoading | bool | no | false | renders loading state and prevents click listener from being called |
| onClick | func | no | () => {} | callback function called on click of the button |
| textColor | string | no | '' | color (as a string) that will override existing text, icon, and loading colors for the button (except when disabled is true) |

### Notes

Buttons can be used as a main call-to-action (CTA). Try to avoid using
buttons of the same `buttonType` next to each other since we want to
guide the user towards one option.
Expand Down
31 changes: 17 additions & 14 deletions docs/button/roundButton.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Round Button

## Usage

```jsx
Expand All @@ -20,11 +21,11 @@ import { CheckmarkIcon, ArrowRightIcon, ArrowLeftIcon, CloseIcon } from 'radianc
<RoundButton buttonType="action" icon={<CloseIcon />} disabled>Action</RoundButton>

// Loading
<RoundButton icon={<ArrowLeftIcon />} loading>Primary</RoundButton>
<RoundButton buttonType="secondary" icon={<ArrowRightIcon />} loading>Secondary</RoundButton>
<RoundButton buttonType="tertiary" icon={<ArrowLeftIcon />} loading>Tertiary</RoundButton>
<RoundButton buttonType="quaternary" icon={<ArrowRightIcon />} loading>Quaternary</RoundButton>
<RoundButton buttonType="action" icon={<CloseIcon />} loading>Action</RoundButton>
<RoundButton icon={<ArrowLeftIcon />} isLoading>Primary</RoundButton>
<RoundButton buttonType="secondary" icon={<ArrowRightIcon />} isLoading>Secondary</RoundButton>
<RoundButton buttonType="tertiary" icon={<ArrowLeftIcon />} isLoading>Tertiary</RoundButton>
<RoundButton buttonType="quaternary" icon={<ArrowRightIcon />} isLoading>Quaternary</RoundButton>
<RoundButton buttonType="action" icon={<CloseIcon />} isLoading>Action</RoundButton>

// Within RoundButton.Container (with multi prop)
<RoundButton.Container multi>
Expand All @@ -36,17 +37,19 @@ import { CheckmarkIcon, ArrowRightIcon, ArrowLeftIcon, CloseIcon } from 'radianc
<!-- STORY -->

### Proptypes
| prop | propType | required | default | description |
|----------|--------------------|----------|---------|------------------------------------------------------------------------------------------------------------------------------|
| buttonType | string | no | primary | Determines the button's main style theme. Must be one of `primary`, `secondary`, `tertiary`, `quaternary`, `action`. |
| children | node | yes | - | node to be rendered inside the button. Recommended to be the button text |
| disabled | bool | no | false | when disabled, click listener will not be called and the UI will look disabled |
| icon | node | yes | null | icon to render in the button. Recommended to use one of Radiance's icons |
| loading | bool | no | false | renders loading state and prevents click listener from being called |
| onClick | func | no | () => {} | callback function called on click of the button |
| textColor | string | no | '' | color (as a string) that will override existing text, icon, and loading colors for the button (except when disabled is true) |

| prop | propType | required | default | description |
| ---------- | -------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| buttonType | string | no | primary | Determines the button's main style theme. Must be one of `primary`, `secondary`, `tertiary`, `quaternary`, `action`. |
| children | node | yes | - | node to be rendered inside the button. Recommended to be the button text |
| disabled | bool | no | false | when disabled, click listener will not be called and the UI will look disabled |
| icon | node | yes | null | icon to render in the button. Recommended to use one of Radiance's icons |
| isLoading | bool | no | false | renders loading state and prevents click listener from being called |
| onClick | func | no | () => {} | callback function called on click of the button |
| textColor | string | no | '' | color (as a string) that will override existing text, icon, and loading colors for the button (except when disabled is true) |

### Notes

`<RoundButton />` behaves mostly the same as `<Button />` except that it
requires an `icon` prop since that is the main content placed with in
the round button. Any children of the component will be rendered
Expand Down
4 changes: 0 additions & 4 deletions src/shared-components/button/__snapshots__/test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -233,26 +233,22 @@ exports[`<Button /> UI snapshots renders with props 1`] = `
<button
className="emotion-6 emotion-7"
disabled={true}
loading={false}
onClick={[Function]}
type="button"
>
<div
className="emotion-2 emotion-3"
loading={false}
>
<svg />
<span
className="emotion-0 emotion-1"
loading={false}
>
Button Text
</span>
</div>
<div
className="emotion-4 emotion-5"
disabled={true}
loading={false}
>
<div>
<span />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,13 @@ exports[`<RoundButton /> UI snapshots renders with props 1`] = `
<button
className="emotion-2 emotion-3"
disabled={true}
loading={false}
onClick={[Function]}
type="button"
>
<svg />
<div
className="emotion-0 emotion-1"
disabled={true}
loading={false}
>
<div>
<span />
Expand Down
65 changes: 42 additions & 23 deletions src/shared-components/button/components/roundButton/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ import {
RoundButtonText,
RoundButtonContainer,
} from './style';
import withDeprecationWarning from '../../../../utils/withDeprecationWarning';

const deprecatedProperties = {
loading: "The 'loading' prop is deprecated. Use 'isLoading' instead.",
};

const isLoadingPropFunction = (props, propName, componentName) => {
if (props[propName] !== undefined) {
return new Error(
`'loading' prop will be deprecated in the next major release. Please rename 'loading' to 'isLoading' in ${componentName}`
);
}
};

const propTypes = {
onClick: PropTypes.func,
Expand All @@ -21,15 +34,16 @@ const propTypes = {
'quaternary',
'action',
]),
loading: PropTypes.bool,
loading: isLoadingPropFunction,
isLoading: PropTypes.bool,
icon: PropTypes.node.isRequired,
textColor: PropTypes.string,
};

const defaultProps = {
disabled: false,
buttonType: 'primary',
loading: false,
isLoading: false,
onClick() {},
children: '',
textColor: '',
Expand All @@ -41,35 +55,40 @@ const RoundButton = ({
children,
buttonType,
loading,
isLoading,
icon,
textColor,
...rest
}) => (
<RoundButtonWrapper>
<RoundButtonBase
onClick={!disabled && !loading ? onClick : () => false}
disabled={disabled}
buttonType={buttonType}
loading={loading}
type="button"
textColor={textColor}
{...rest}
>
{icon}
<Loader
loading={loading}
}) => {
const loadingVal = loading === undefined ? isLoading : loading;

return (
<RoundButtonWrapper>
<RoundButtonBase
onClick={!disabled && !isLoading ? onClick : () => false}
disabled={disabled}
buttonType={buttonType}
css={roundButtonLoader(disabled)}
isLoading={loadingVal}
type="button"
textColor={textColor}
/>
</RoundButtonBase>
{children && <RoundButtonText>{children}</RoundButtonText>}
</RoundButtonWrapper>
);
{...rest}
>
{icon}
<Loader
isLoading={loadingVal}
disabled={disabled}
buttonType={buttonType}
css={roundButtonLoader(disabled)}
textColor={textColor}
/>
</RoundButtonBase>
{children && <RoundButtonText>{children}</RoundButtonText>}
</RoundButtonWrapper>
);
};

RoundButton.propTypes = propTypes;
RoundButton.defaultProps = defaultProps;
RoundButton.Container = RoundButtonContainer;

export default RoundButton;
export default withDeprecationWarning(RoundButton, deprecatedProperties);
6 changes: 3 additions & 3 deletions src/shared-components/button/components/roundButton/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export const RoundButtonBase = styled(ButtonBase)`
width: 48px;
padding: 0;
${({ loading, disabled }) =>
!loading &&
${({ isLoading, disabled }) =>
!isLoading &&
!disabled &&
css`
&:hover {
Expand All @@ -45,7 +45,7 @@ export const RoundButtonBase = styled(ButtonBase)`
`};
& > svg {
opacity: ${({ loading }) => (loading ? 0 : 1)};
opacity: ${({ isLoading }) => (isLoading ? 0 : 1)};
transition: opacity ${ANIMATION.defaultTiming};
margin: 0 auto;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('<RoundButton />', () => {
it('should not be invoked if loading', () => {
const spy = jest.fn();
const wrapper = mount(
<RoundButton loading onClick={spy} icon={<CameraIcon />}>
<RoundButton isLoading onClick={spy} icon={<CameraIcon />}>
Button Text
</RoundButton>
);
Expand Down
39 changes: 30 additions & 9 deletions src/shared-components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import { css } from '@emotion/core';
import Loader from './shared-components/loader';
import Container from './shared-components/container';
import { ButtonBase, ButtonText, ButtonContents } from './style';
import withDeprecationWarning from '../../utils/withDeprecationWarning';

const deprecatedProperties = {
loading: "The 'loading' prop is deprecated. Use 'isLoading' instead.",
};

const isLoadingPropFunction = (props, propName, componentName) => {
if (props[propName] !== undefined) {
return new Error(
`'loading' prop will be deprecated in the next major release. Please rename 'loading' to 'isLoading' in ${componentName}`
);
}
};

class Button extends React.Component {
static Container = Container;
Expand All @@ -19,15 +32,16 @@ class Button extends React.Component {
'tertiary',
'quaternary',
]),
loading: PropTypes.bool,
loading: isLoadingPropFunction,
isLoading: PropTypes.bool,
icon: PropTypes.node,
textColor: PropTypes.string,
};

static defaultProps = {
disabled: false,
buttonType: 'primary',
loading: false,
isLoading: false,
onClick() {},
textColor: '',
};
Expand All @@ -39,33 +53,40 @@ class Button extends React.Component {
children,
buttonType,
loading,
isLoading,
icon,
textColor,
...rest
} = this.props;

const loadingVal = loading === undefined ? isLoading : loading;

return (
<ButtonBase
disabled={disabled}
onClick={!disabled && !loading ? onClick : event => event.preventDefault()}
onClick={
!disabled && !loadingVal ? onClick : event => event.preventDefault()
}
buttonType={buttonType}
loading={loading}
isLoading={loadingVal}
type="button"
textColor={textColor}
{...rest}
>
<ButtonContents loading={loading} hasIcon={!!icon}>
<ButtonContents isLoading={loadingVal} hasIcon={!!icon}>
{icon}
<ButtonText
loading={loading}
isLoading={loadingVal}
hasIcon={!!icon}
css={css`padding-top: 2px;`}
css={css`
padding-top: 2px;
`}
>
{children}
</ButtonText>
</ButtonContents>
<Loader
loading={loading}
isLoading={loadingVal}
disabled={disabled}
buttonType={buttonType}
textColor={textColor}
Expand All @@ -78,4 +99,4 @@ class Button extends React.Component {
export LinkButton from './components/linkButton';
export RoundButton from './components/roundButton';
export TextButton from './components/textButton';
export default Button;
export default withDeprecationWarning(Button, deprecatedProperties);
Loading

0 comments on commit a6a5b35

Please sign in to comment.