Skip to content

Commit

Permalink
feat(components): add icon prop to Button
Browse files Browse the repository at this point in the history
This allows us to style the icon appropriately and adjust its position in the future.

feature/button-enums

feature/button-enums

feature/button-enums
  • Loading branch information
connor-baer committed May 4, 2020
1 parent 77ba51f commit 38e6feb
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 14 deletions.
3 changes: 1 addition & 2 deletions src/__snapshots__/storyshots.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,9 @@ exports[`Storyshots Components/Button With Icon 1`] = `
class="circuit-0"
>
<svg
aria-hidden="true"
fill="none"
height="24"
role="img"
role="presentation"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
Expand Down
6 changes: 6 additions & 0 deletions src/components/Button/Button.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

import React from 'react';
import { ThumbUp } from '@sumup/icons';

import {
create,
Expand Down Expand Up @@ -80,6 +81,11 @@ describe('Button', () => {
const wrapper = renderButton(create, { ...baseProps, stretch: true });
expect(wrapper).toMatchSnapshot();
});

it('should render a button with icon', () => {
const wrapper = renderButton(create, { ...baseProps, icon: ThumbUp });
expect(wrapper).toMatchSnapshot();
});
});

describe('business logic', () => {
Expand Down
14 changes: 5 additions & 9 deletions src/components/Button/Button.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/

import React from 'react';
import { css } from '@emotion/core';
import { select, boolean, text } from '@storybook/addon-knobs';
import { ThumbUp } from '@sumup/icons';

Expand Down Expand Up @@ -62,14 +61,11 @@ export const Sizes = () => (
);

export const WithIcon = () => (
<Button>
<ThumbUp
role="img"
aria-hidden
css={theme => css`
margin-right: ${theme.spacings.bit};
`}
/>
<Button
icon={ThumbUp}
variant={select('Variant', ['primary', 'secondary', 'tertiary'], 'primary')}
size={select('Size', ['kilo', 'mega', 'giga'], 'mega')}
>
Like
</Button>
);
27 changes: 24 additions & 3 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
* limitations under the License.
*/

import React, { HTMLProps, ReactNode, ReactElement } from 'react';
import React, { HTMLProps, ReactNode, ReactElement, FC, SVGProps } from 'react';
import { css } from '@emotion/core';
import { Theme } from '@sumup/design-tokens';

import styled, { StyleProps } from '../../styles/styled';
import {
Expand Down Expand Up @@ -42,6 +43,10 @@ export interface BaseProps {
* Stretch the button across the full width of its parent.
*/
stretch?: boolean;
/**
* Display an icon in addition to the text to help to identify the action.
*/
icon?: FC<SVGProps<SVGSVGElement>>;
}

type LinkElProps = Omit<HTMLProps<HTMLAnchorElement>, 'size' | 'type'>;
Expand Down Expand Up @@ -163,6 +168,12 @@ const stretchStyles = ({ stretch }: ButtonProps) =>
width: 100%;
`;

const iconStyles = (theme: Theme) => css`
label: button__icon;
margin-right: ${theme.spacings.bit};
margin-left: -${theme.spacings.bit};
`;

const BaseButton = styled('button')<ButtonProps>(
baseStyles,
primaryStyles,
Expand All @@ -178,8 +189,18 @@ const BaseButton = styled('button')<ButtonProps>(
*/
export function Button(props: BaseProps & LinkElProps): ReturnType;
export function Button(props: BaseProps & ButtonElProps): ReturnType;
export function Button(props: ButtonProps): ReturnType {
export function Button({
children,
icon: Icon,
...props
}: ButtonProps): ReturnType {
const { Link } = useComponents();
const LinkButton = BaseButton.withComponent(Link);
return props.href ? <LinkButton {...props} /> : <BaseButton {...props} />;
const ButtonElement = props.href ? LinkButton : BaseButton;
return (
<ButtonElement {...props}>
{Icon && <Icon css={iconStyles} role="presentation" />}
{children}
</ButtonElement>
);
}
82 changes: 82 additions & 0 deletions src/components/Button/__snapshots__/Button.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,87 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Button styles should render a button with icon 1`] = `
.circuit-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
width: auto;
height: auto;
cursor: pointer;
font-size: 16px;
line-height: 24px;
text-align: center;
-webkit-text-decoration: none;
text-decoration: none;
font-weight: 700;
border-radius: 5px;
border-width: 1px;
border-style: solid;
background-color: #3388FF;
border-color: #3388FF;
color: #FFFFFF;
padding: 8px calc(24px - 1px);
}
.circuit-0:focus {
outline: 0;
box-shadow: 0 0 0 4px #AFD0FE;
}
.circuit-0:focus::-moz-focus-inner {
border: 0;
}
.circuit-0:disabled,
.circuit-0[disabled] {
opacity: 0.5;
pointer-events: none;
box-shadow: none;
}
.circuit-0:hover {
background-color: #1760CE;
border-color: #1760CE;
}
.circuit-0:active {
background-color: #003C8B;
border-color: #003C8B;
}
<button
class="circuit-0"
>
<svg
fill="none"
height="24"
role="presentation"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M13.316 9.2V6.8c0-.994-.819-1.8-1.829-1.8l-2.439 5.4V17h6.877a1.214 1.214 0 001.22-1.02l.841-5.4a1.187 1.187 0 00-.285-.968 1.228 1.228 0 00-.934-.412h-3.45zM9.048 17H7.22A1.21 1.21 0 016 15.8v-4.2c0-.663.546-1.2 1.22-1.2h1.828V17z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
/>
</svg>
Button
</button>
`;

exports[`Button styles should render a disabled button 1`] = `
.circuit-0 {
display: -webkit-box;
Expand Down

0 comments on commit 38e6feb

Please sign in to comment.