Skip to content

Commit

Permalink
Merge pull request #92 from PocketDerm/toggle-component
Browse files Browse the repository at this point in the history
new Toggle component
  • Loading branch information
daigof committed Apr 25, 2019
2 parents 346bf2c + 2e02c71 commit c04f581
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 1 deletion.
24 changes: 24 additions & 0 deletions docs/toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Toggle
### Usage

```jsx
import { Toggle } from 'radiance-ui';

<Toggle
checked={checked}
label="Toggle Label"
onChange={this.onChange}
/>
```

<!-- STORY -->

### Proptypes
| prop | propType | required | default | description
|-----------------------|------------------|----------|-----------|------------------------------------------------------------------------------------------------------------------------------|
| checked | bool | yes | - | controls the toggle state |
| label | string | no | '' | the toggle label |
| onChange | function | yes | - | the toggle handler function, this usually toggle the checked prop value |

### Notes
The `<Toggle>` component is usually wrapped in a `container` element (with a fixed `width` style for example). The toggle and label are spread in the container (`space-between`) from edge to edge.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
"react": "^16.6.0",
"react-modal": "^3.8.1",
"react-slick": "^0.23.2",
"react-toggle-button": "^2.2.0",
"react-transition-group": "^2.9.0",
"tinycolor2": "^1.4.1"
},
Expand Down
1 change: 1 addition & 0 deletions src/shared-components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export { default as OptionButton } from './optionButton';
export { default as ProgressBar } from './progressBar';
export { default as RadioButton } from './radioButton';
export { default as Tabs } from './tabs';
export { default as Toggle } from './toggle';
export { default as Tooltip } from './tooltip';
export { default as Typography, style as TYPOGRAPHY_STYLE } from './typography';
export { FadeInContainer, opacityInAnimationStyle } from './transitions';
191 changes: 191 additions & 0 deletions src/shared-components/toggle/__snapshots__/test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Toggle /> UI snapshot renders the component 1`] = `
.emotion-2 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-flow: row nowrap;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
padding: 1rem 0;
}
.emotion-2 > input {
display: none;
}
.emotion-0 {
color: #524D6E;
margin: 0;
font-size: 1rem;
line-height: 1.5rem;
text-align: left;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin-right: 0.5rem;
}
<div
className="emotion-2 emotion-3"
>
<span
className="emotion-0 emotion-1"
>
Label Text
</span>
<div
onClick={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
style={
Object {
"KhtmlUserSelect": "none",
"MozUserSelect": "none",
"WebkitTapHighlightColor": "transparent",
"WebkitTouchCallout": "none",
"WebkitUserSelect": "none",
"alignItems": "center",
"backgroundColor": "transparent",
"border": 0,
"cursor": "pointer",
"display": "flex",
"justifyContent": "flex-start",
"msUserSelect": "none",
"padding": 0,
"position": "relative",
"userSelect": "none",
"width": 52,
}
}
>
<div
style={
Object {
"alignItems": "center",
"backgroundColor": "rgb(225,224,230)",
"borderRadius": 100,
"display": "flex",
"height": 24,
"justifyContent": "center",
"padding": 0,
"width": 40,
}
}
>
<div
style={
Object {
"alignItems": "center",
"color": "#FAFAFA",
"display": "flex",
"fontFamily": "'Helvetica Neue', Helvetica, sans-serif",
"fontSize": 11,
"height": 20,
"justifyContent": "center",
"left": 4,
"lineHeight": 0,
"marginBottom": "auto",
"marginTop": "auto",
"opacity": 0,
"position": "relative",
"width": 26,
}
}
>
</div>
<div
style={
Object {
"alignItems": "center",
"bottom": "0px",
"color": "rgba(255,255,255,0.6)",
"display": "flex",
"fontFamily": "'Helvetica Neue', Helvetica, sans-serif",
"fontSize": 11,
"height": 20,
"justifyContent": "center",
"lineHeight": 0,
"marginBottom": "auto",
"marginTop": "auto",
"opacity": 1,
"paddingRight": 5,
"position": "relative",
"width": 26,
}
}
>
</div>
</div>
<div
style={
Object {
"alignItems": "center",
"alignSelf": "stretch",
"display": "flex",
"flex": 1,
"height": "100%",
"justifyContent": "flex-start",
"left": 0,
"position": "absolute",
"top": 0,
}
}
>
<div
style={
Object {
"MozBoxSizing": "border-box",
"WebkitBoxSizing": "border-box",
"alignSelf": "center",
"background": "#ffffff",
"backgroundColor": "rgb(255,255,255)",
"border": "1px solid #ededf0",
"borderRadius": "50%",
"boxShadow": "none",
"boxSizing": "border-box",
"display": "flex",
"height": 22,
"left": 1,
"position": "relative",
"width": 22,
}
}
/>
</div>
<input
onClick={[Function]}
style={
Object {
"border": 0,
"clip": "rect(0 0 0 0)",
"height": 1,
"margin": -1,
"overflow": "hidden",
"padding": 0,
"position": "absolute",
"width": 1,
}
}
type="checkbox"
value={false}
/>
</div>
</div>
`;
51 changes: 51 additions & 0 deletions src/shared-components/toggle/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PropTypes from 'prop-types';
import React from 'react';
import ToggleButton from 'react-toggle-button';

import { COLORS } from '../../constants';
import { Container, Label, trackStyle, thumbStyle } from './style';

const propTypes = {
checked: PropTypes.bool,
label: PropTypes.string,
onChange: PropTypes.func,
};

const defaultProps = {
checked: false,
label: '',
};

const Toggle = ({ checked, label, onChange }) => (
<Container>
{label && <Label onClick={onChange}>{label}</Label>}
<ToggleButton
value={checked || false}
onToggle={onChange}
inactiveLabel=""
activeLabel=""
thumbStyle={thumbStyle}
trackStyle={trackStyle}
thumbAnimateRange={[1, 17]}
colors={{
active: {
base: COLORS.secondary,
},
inactive: {
base: COLORS.purple15,
},
activeThumb: {
base: COLORS.white,
},
inactiveThumb: {
base: COLORS.white,
},
}}
/>
</Container>
);

Toggle.propTypes = propTypes;
Toggle.defaultProps = defaultProps;

export default Toggle;
43 changes: 43 additions & 0 deletions src/shared-components/toggle/style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import styled from '@emotion/styled';

import { COLORS, SPACING } from '../../constants';

export const Container = styled.div`
position: relative;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
width: 100%;
padding: ${SPACING.small} 0;
& > input {
display: none;
}
`;

export const Label = styled.span`
color: ${COLORS.primaryTint1};
margin: 0;
font-size: ${SPACING.small};
line-height: ${SPACING.base};
text-align: left;
cursor: pointer;
user-select: none;
margin-right: ${SPACING.xsmall};
`;

export const trackStyle = {
borderRadius: 100,
height: 24,
width: 40,
};

export const thumbStyle = {
height: 22,
width: 22,
border: `1px solid ${COLORS.border}`,
boxShadow: `none`,
background: COLORS.white,
backgroundColor: COLORS.white,
};
45 changes: 45 additions & 0 deletions src/shared-components/toggle/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { shallow, mount } from 'enzyme';
import renderer from 'react-test-renderer';

import Toggle from './index';

describe('<Toggle />', () => {
const labelText = 'Label Text';

describe('UI snapshot', () => {
it('renders the component', () => {
const component = renderer.create(
<Toggle checked={false} label={labelText} />
);

const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

describe('when label is undefined', () => {
test('does not render a label component', () => {
const wrapper = shallow(<Toggle checked={false} />);
expect(wrapper.html().indexOf('label') === -1).toBe(true);
});
});

describe('when label is a string', () => {
test('renders a text component', () => {
const wrapper = shallow(<Toggle checked={false} label={labelText} />);

expect(wrapper.html().indexOf(labelText) > 0).toBe(true);
});
});

describe('when checkbox is clicked', () => {
test('fires onChange function with correct argument when function exists', () => {
const spy = jest.fn();
const wrapper = mount(<Toggle checked={false} onChange={spy} />);

wrapper.find('[type="checkbox"]').simulate('click');
expect(spy).toHaveBeenCalled();
});
});
});
Loading

0 comments on commit c04f581

Please sign in to comment.