Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Commit

Permalink
Merge pull request #159 from apollographql/justin/button-end-icon
Browse files Browse the repository at this point in the history
AP-1393 Add `endIcon` prop to `Button`
  • Loading branch information
Justin Anastos committed Mar 10, 2020
2 parents 4111805 + c95eaeb commit 7e71c70
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 14 deletions.
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@
"repository": "apollographql/space-kit",
"keywords": [],
"license": "MIT",
"eslintConfig": {
"extends": "@trevorblades"
},
"dependencies": {
"@emotion/cache": "^10.0.15",
"@emotion/core": "^10.0.15",
Expand Down
24 changes: 24 additions & 0 deletions src/Button/Button.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@ test("when passed an icon, text and icon are rendered", () => {
expect(getByTestId("icon")).toBeInTheDocument();
});

test("when passed an endIcon and text, both are rendered", () => {
const { getByText, getByTestId } = render(
<Button endIcon={<IconShip2 data-testid="icon" />}>submit</Button>
);

getByText("submit");
getByTestId("icon");
});

test("when passed an icon, endIcon, and text; all are rendered", () => {
const { getByText, getByTestId } = render(
<Button
endIcon={<IconShip2 data-testid="endIcon" />}
icon={<IconShip2 data-testid="icon" />}
>
submit
</Button>
);

getByText("submit");
getByTestId("icon");
getByTestId("endIcon");
});

test("wyhen passed an icon and no children, should render an icon and no text content", () => {
const { container, getByTestId } = render(
<Button icon={<IconShip2 data-testid="icon" />} />
Expand Down
24 changes: 24 additions & 0 deletions src/Button/Button.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import {
Props,
Preview,
} from "@storybook/addon-docs/blocks";
import { IconExpandList } from "../icons/IconExpandList";
import { IconShip2 } from "../icons/IconShip2";
import { ButtonLayout } from "./button.stories/ButtonLayout";
import { colors } from "../colors";

export const ExpandIcon = () => (
<IconExpandList style={{ height: 12, width: 12, color: colors.grey.light }} />
);

export const SampleIcon = () => (
<IconShip2 style={{ height: "100%", width: "100%" }} />
);
Expand Down Expand Up @@ -449,6 +454,25 @@ In space constrained places or for floating action buttons (FAB), we can show an
</Story>
</Preview>

### End Icons

You can specify that a button has an additional icon at the end of the row

<Preview>
<Story name="light end icon">
<ButtonLayout theme="light">
<Button endIcon={<ExpandIcon />}>Submit</Button>
</ButtonLayout>
</Story>
<Story name="dark end icon">
<ButtonLayout theme="dark">
<Button theme="dark" endIcon={<ExpandIcon />}>
Submit
</Button>
</ButtonLayout>
</Story>
</Preview>

### Loading

You can specify that a button is in a loading state with the `loading` prop
Expand Down
40 changes: 30 additions & 10 deletions src/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ interface Props
*/
disabled?: boolean;

/**
* Icon to use at the end of a button
*
* The size of icons will be automatically determined, but can be overriden
*/
endIcon?: React.ReactElement;

/**
* Which feel to display
*
Expand Down Expand Up @@ -264,6 +271,7 @@ export const Button = React.forwardRef<HTMLElement, Props>(
color = defaultColor,
disabled: disabledProps = false,
variant,
endIcon,
feel = "raised",
icon: iconProp,
loading,
Expand Down Expand Up @@ -362,6 +370,7 @@ export const Button = React.forwardRef<HTMLElement, Props>(

// Vertically center children
display: "inline-flex",
alignItems: "center",
justifyContent: "center",

height: getHeight({ size }),
Expand Down Expand Up @@ -494,15 +503,7 @@ export const Button = React.forwardRef<HTMLElement, Props>(
},

children: (
<div
className={cx(
css({
alignItems: "center",
display: "flex",
justifyContent: "center",
})
)}
>
<>
{icon && (
<span
className={cx(
Expand All @@ -523,7 +524,26 @@ export const Button = React.forwardRef<HTMLElement, Props>(
</span>
)}
{children}
</div>
{endIcon && !loading && (
<span
className={cx(
css({
alignItems: "center",
// This needs to be `inline-flex` and not the default of
// `inline-block` to vertically center the icon automatically
display: "inline-flex",
height: iconSize,
justifyContent: "center",
// The `4px` will be on the right to separate the icon from the text
margin: iconOnly ? 0 : "0 0 0 4px",
width: iconSize,
})
)}
>
{endIcon}
</span>
)}
</>
),
};

Expand Down
2 changes: 1 addition & 1 deletion src/Button/button.stories/ButtonLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const ButtonLayout: React.FC<Props> = ({ children, theme }) => (

"> *": {
margin: 8,
display: "block",
display: "flex",
},
})
)}
Expand Down

0 comments on commit 7e71c70

Please sign in to comment.