-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: copied over button files * chore: updated util funcs * chore: removed console.logs, fixed Button icon props, removed Color library references * chore: delete references to outline-shadow prop * fix: merge icon changes * feat: add withInfo to button * feat: Icons (#24) * feat: add icon directory * feat: add icon story * chore: added Icon to index.js * chore: update snaps * fix: support custom svgs * test: update snapshots * test: updated snaps test: update snaps * fix: update iconSize propTypes * fix: update default props * chore: remove console logs * fix: add PADDING_BASE to size variables
- Loading branch information
Kait Moreno
committed
Jan 12, 2018
1 parent
a9669d6
commit 1e39844
Showing
27 changed files
with
2,784 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,106 @@ | ||
import React from "react"; | ||
import styled from "styled-components"; | ||
import { PropTypes } from "prop-types"; | ||
import { getColor, getPadding } from "./helpers"; | ||
import { lighten } from "polished"; | ||
import { FONT_SIZE_BASE } from "../../style/fonts/fontVariables"; | ||
import React from "react"; | ||
|
||
const Button = styled.button.attrs({ | ||
type: "button" // defaults to button rather than submit | ||
})` | ||
box-sizing: border-box; | ||
user-select: none; | ||
overflow: hidden; | ||
color: ${props => (props.disabled ? "#bbb" : getColor(props).color)}; | ||
border: 1px solid #f0f0f0; | ||
border-radius: 3px; | ||
border-top-color: ${lighten("3%", "#ececec")}; | ||
border-bottom-color: #cdcdcd; | ||
box-shadow: inset 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(0, 0, 0, 0), | ||
0 0 0 rgba(0, 0, 0, 0); | ||
width: ${props => (props.size === "fit" ? "100%" : "fit-content")}; | ||
background: ${props => | ||
props.disabled ? "#eee" : getColor(props).background}; | ||
padding: ${props => getPadding(props)}; | ||
text-align: center; | ||
cursor: ${props => (props.disabled ? "default" : "pointer")}; | ||
font-size: ${FONT_SIZE_BASE}; | ||
&:hover { | ||
background: ${props => | ||
props.disabled ? "#fbfbfb" : getColor(props).hover}; | ||
} | ||
`; | ||
import Icon from "../Icon"; | ||
|
||
Button.defaultProps = { | ||
size: "md", | ||
appearance: "primary" | ||
}; | ||
import ButtonWrap from "./components/ButtonWrap"; | ||
import ButtonLabelPrefix from "./components/ButtonLabelPrefix"; | ||
import ButtonLabelSuffix from "./components/ButtonLabelSuffix"; | ||
|
||
Button.propTypes = { | ||
onClick: PropTypes.any.isRequired, // click handler | ||
size: PropTypes.oneOf(["xs", "sm", "md", "lg", "fit"]), // Relative size of the button | ||
appearance: PropTypes.oneOf(["danger", "info", "primary", "warning"]) | ||
active: PropTypes.bool, // If the button should be style as active or not | ||
children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), | ||
clickAction: PropTypes.any.isRequired, // click handler | ||
disabled: PropTypes.bool, // disables the button | ||
glyph: PropTypes.string, // Glyph to display in the button | ||
glyphColor: PropTypes.string, // Color for the glyph | ||
glyphRatio: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // Relative size for the glyph | ||
iconSize: PropTypes.oneOf(["normal", "xs", "sm", "lg", "xl"]), | ||
label: PropTypes.string.isRequired, // label for the button | ||
labelStyle: PropTypes.object, | ||
orientation: PropTypes.oneOf(["vertical", "horizontal"]), // Vertical: Icon top, label bottom; Horizontal: Icon left, label right; | ||
outline: PropTypes.oneOf([ | ||
"raised", // Add highlight effect to top edge and shadow effect to bottom edge | ||
"outline", // Add outline effect | ||
"shadow", // Add shadow effect to bottom edge | ||
"none", // No effects | ||
"raised-outline" | ||
]), | ||
prefix: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // Add prefix text to button label | ||
size: PropTypes.oneOf(["normal", "xs", "sm", "lg", "xl"]), // Relative size of the button | ||
style: PropTypes.object, // style prop | ||
suffix: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // Add suffix text to button label | ||
tabIndex: PropTypes.number, | ||
type: PropTypes.oneOf([ | ||
"danger", | ||
"info", | ||
"primary", | ||
"secondary", | ||
"warning", | ||
"polling" | ||
]) | ||
}; | ||
|
||
Button.defaultProps = { | ||
active: false, | ||
clickAction: () => {}, | ||
disabled: false, | ||
size: "normal", | ||
orientation: "horizontal" | ||
}; | ||
|
||
export default Button; | ||
/** | ||
* General purpose button | ||
* @param {Object} props - see propTypes | ||
* @returns JSX.Element | ||
*/ | ||
export default function Button({ | ||
active, | ||
children, | ||
clickAction, | ||
disabled, | ||
glyph, | ||
glyphRatio, | ||
glyphColor, | ||
iconSize, | ||
label, | ||
orientation, | ||
prefix, | ||
size, | ||
style, | ||
suffix, | ||
outline, | ||
tabIndex, | ||
type, | ||
labelStyle | ||
}) { | ||
return ( | ||
<ButtonWrap | ||
active={active} | ||
type={type} | ||
size={size} | ||
outline={outline} | ||
orientation={orientation} | ||
disabled={disabled} | ||
onClick={clickAction} | ||
tabIndex={tabIndex} | ||
title={label} | ||
style={style} | ||
iconSize={iconSize} | ||
> | ||
{glyph && ( | ||
<Icon | ||
glyphColor={glyphColor} | ||
glyph={glyph} | ||
glyphSizeRatio={glyphRatio} | ||
/> | ||
)} | ||
{children} | ||
<span style={labelStyle}> | ||
{prefix ? <ButtonLabelPrefix>{prefix}</ButtonLabelPrefix> : ""} | ||
{label} | ||
{suffix ? <ButtonLabelSuffix>{suffix}</ButtonLabelSuffix> : ""} | ||
</span> | ||
</ButtonWrap> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import React from "react"; | ||
import { mount, render } from "enzyme"; | ||
|
||
import Button from "./Button"; | ||
import ButtonWrap from "./components/ButtonWrap"; | ||
|
||
const types = ["danger", "info", "primary", "warning", "polling"]; | ||
const outlines = ["raised", "outline", "shadow", "none", "raised-outline"]; | ||
const sizes = ["normal", "xs", "sm", "lg", "xl"]; | ||
const orientations = ["vertical", "horizontal"]; | ||
|
||
const props = { | ||
active: false, | ||
clickAction: () => {}, | ||
disabled: false, | ||
glyph: "Bell", | ||
glyphColor: "#fff", | ||
glyphRatio: 1, | ||
iconSize: "sm", | ||
label: "Button", | ||
labelStyle: {}, | ||
orientation: "horizontal", | ||
outline: "outline", | ||
prefix: "pre", | ||
size: "normal", | ||
style: {}, | ||
suffix: "suff", | ||
tabIndex: 0, | ||
type: "primary" | ||
}; | ||
|
||
describe("Button", () => { | ||
describe("Snapshots", () => { | ||
test("matches type snapshots", () => { | ||
let tree; | ||
types.forEach(type => { | ||
tree = render( | ||
<Button type={type} label={type} key={type} clickAction={() => {}} /> | ||
); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
test("matches outline snapshots", () => { | ||
let tree; | ||
outlines.forEach(outline => { | ||
tree = render( | ||
<Button | ||
outline={outline} | ||
label={outline} | ||
key={outline} | ||
clickAction={() => {}} | ||
/> | ||
); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
test("matches size snapshots", () => { | ||
let tree; | ||
sizes.forEach(size => { | ||
tree = render( | ||
<Button size={size} label={size} key={size} clickAction={() => {}} /> | ||
); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
test("matches orientation snapshots", () => { | ||
let tree; | ||
orientations.forEach(orientation => { | ||
tree = render( | ||
<Button | ||
orientation={orientation} | ||
label={orientation} | ||
key={orientation} | ||
clickAction={() => {}} | ||
/> | ||
); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
test("matches prefix/suffix snapshot", () => { | ||
let tree = ( | ||
<Button | ||
prefix="Prefix" | ||
suffix="Suffix" | ||
label="Button" | ||
clickAction={() => {}} | ||
/> | ||
); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
|
||
test("matches active snapshot", () => { | ||
let tree = <Button active label="Button" clickAction={() => {}} />; | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
|
||
test("matches disabled snapshot", () => { | ||
let tree = <Button disabled label="Button" clickAction={() => {}} />; | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
describe("Props", () => { | ||
let wrapper; | ||
beforeEach(() => { | ||
wrapper = mount(<Button {...props}>{["Hello World"]}</Button>); | ||
}); | ||
|
||
test("passes correct props to ButtonWrap", () => { | ||
expect(wrapper.find(ButtonWrap).props()).toMatchObject({ | ||
active: false, | ||
disabled: false, | ||
iconSize: "sm", | ||
onClick: wrapper.props().clickAction, | ||
orientation: "horizontal", | ||
outline: "outline", | ||
size: "normal", | ||
style: {}, | ||
tabIndex: 0, | ||
title: "Button", | ||
type: "primary" | ||
}); | ||
}); | ||
|
||
test("passes correct props to Glyph", () => { | ||
expect(wrapper.find("Glyph").props()).toMatchObject({ | ||
glyphColor: "#fff", | ||
name: "Bell", | ||
ratio: 1 | ||
}); | ||
}); | ||
|
||
test("renders children", () => { | ||
expect(wrapper.html().includes("Hello World")).toBe(true); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.