Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-switch

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-switch - npm Package Compare versions

Comparing version 2.0.0-rc.1 to 2.0.0-rc.2

__tests__/getBackgroundColor.test.js

35

__tests__/Switch.test.jsx

@@ -10,3 +10,3 @@ import React from 'react';

it('matches snapshot with default props', () => {
const wrapper = render(<Switch onChange={noop} checked={false} />);
const wrapper = render(<Switch checked={false} onChange={noop} />);
expect(toJson(wrapper)).toMatchSnapshot();

@@ -18,13 +18,20 @@ });

<Switch
checked
onChange={noop}
checked
disabled
onColor="#abc"
handleColor="#def"
offHandleColor="#def"
handleDiameter={9}
checkedIcon={(
<div style={{ color: 'pink', paddingTop: 2, paddingLeft: 6, fontSize: 20 }}>
</div>
)}
boxShadow="0px 1px 5px rgba(0, 0, 0, 0.6)"
height={13}
width={37}
className="qux"
id="foo"
aria-labelledby="baz"
aria-label="bar"
aria-labelledby="baz"
className="qux"
/>

@@ -37,6 +44,6 @@ );

describe('onClick', () => {
it('calls onChange when fg is clicked with !checked as argument', () => {
it('calls onChange when bg is clicked with !checked as argument', () => {
const mockOnChange = jest.fn();
const wrapper = shallow(<Switch onChange={mockOnChange} checked={false} />);
wrapper.find('.react-switch-fg').simulate('click');
wrapper.find('.react-switch-bg').simulate('click');
expect(mockOnChange).toBeCalledWith(true);

@@ -48,3 +55,3 @@ });

const wrapper = shallow(<Switch onChange={mockOnChange} checked={false} disabled />);
wrapper.find('.react-switch-fg').simulate('click');
wrapper.find('.react-switch-bg').simulate('click');
expect(mockOnChange).not.toBeCalled();

@@ -58,3 +65,3 @@ });

wrapper.find('.react-switch-handle').simulate('focus');
expect(wrapper.find('.react-switch-handle').get(0).props.style.boxShadow).toBe('0px 0px 1px 2px #4D90FE');
expect(wrapper.find('.react-switch-handle').get(0).props.style.boxShadow).toBe('0px 0px 2px 3px #33bbff');
wrapper.find('.react-switch-handle').simulate('blur');

@@ -92,8 +99,10 @@ expect(wrapper.find('.react-switch-handle').get(0).props.style.boxShadow).toBeNull();

it('affects fg-opacity when it changes', () => {
const wrapper = shallow(<Switch onChange={noop} checked={false} />);
it('affects background when it changes', () => {
const wrapper = shallow(
<Switch onChange={noop} checked={false} offColor="#aabbcc" onColor="#ddeeff" />
);
wrapper.setProps({ checked: true });
expect(wrapper.find('.react-switch-fg').get(0).props.style.opacity).toBe(1);
expect(wrapper.find('.react-switch-bg').get(0).props.style.background).toBe('#ddeeff');
wrapper.setProps({ checked: false });
expect(wrapper.find('.react-switch-fg').get(0).props.style.opacity).toBe(0);
expect(wrapper.find('.react-switch-bg').get(0).props.style.background).toBe('#aabbcc');
});

@@ -100,0 +109,0 @@ });

@@ -7,3 +7,18 @@ # Changelog

## [Unfinished]
## [2.0.0-rc.2] - 2017-10-13
### Refactor
- The switch no longer uses the opacity hack to transition between color. This involved stacking two divs on top of each other and varying the opacity of the top div. This caused some weird visual artifacts.
### Changed
- onColor and offColor props can now only take colors in the form of '#xxxxxx'. Gradients and rgb(xxx, xxx, xxx) are no longer supported.
- handleColor prop is replaced by onHandleColor and offHandleColor.
- The boxShadow the handle gets when selected is now available in the activeBoxShadow prop. The boxShadow prop is now the boxShadow the handle has when it is not selected, and is null by default.
### Fixed
- The switch no longer has a pixel wide gloria of the offColor when checked.
### Removed
- activeHandleColor prop is removed because of lack of usefulness.
## [2.0.0-rc.1] - 2017-10-08
### Added

@@ -10,0 +25,0 @@ - New prop boxShadow. It acts just like outline, but I called it boxShadow since that is the actual css attribute that is being controlled.

@@ -16,3 +16,3 @@ "use strict";

"svg",
{ viewBox: "-2 -5 14 20", height: "100%", width: "100%" },
{ viewBox: "-2 -5 14 20", height: "100%", width: "100%", style: { position: 'absolute', top: 0 } },
_react2.default.createElement("path", {

@@ -51,3 +51,3 @@ /* eslint-disable max-len */

"svg",
{ height: "100%", width: "100%", viewBox: "-2 -5 17 21" },
{ height: "100%", width: "100%", viewBox: "-2 -5 17 21", style: { position: 'absolute', top: 0 } },
_react2.default.createElement("path", {

@@ -54,0 +54,0 @@ d: "M11.264 0L5.26 6.004 2.103 2.847 0 4.95l5.26 5.26 8.108-8.107L11.264 0",

@@ -19,2 +19,6 @@ 'use strict';

var _getBackgroundColor = require('./getBackgroundColor');
var _getBackgroundColor2 = _interopRequireDefault(_getBackgroundColor);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -48,4 +52,13 @@

_this.handleKeyDown = _this.handleKeyDown.bind(_this);
var height = props.height,
width = props.width,
handleDiameter = props.handleDiameter,
checked = props.checked;
_this.handleDiameter = handleDiameter || height - 2;
_this.checkedPos = Math.max(width - height, width - (height + _this.handleDiameter) / 2);
_this.uncheckedPos = Math.max(0, (height - _this.handleDiameter) / 2);
_this.state = {
left: props.checked ? props.width - props.height + 1 : 1,
pos: checked ? _this.checkedPos : _this.uncheckedPos,
startX: null,

@@ -62,9 +75,5 @@ isDragging: false,

var checked = _ref.checked;
var _props = this.props,
width = _props.width,
height = _props.height;
var checkedLeft = width - height + 1;
var left = checked ? checkedLeft : 1;
this.setState({ left: left });
var pos = checked ? this.checkedPos : this.uncheckedPos;
this.setState({ pos: pos });
}

@@ -80,13 +89,9 @@ }, {

var startX = this.state.startX;
var _props2 = this.props,
checked = _props2.checked,
width = _props2.width,
height = _props2.height;
var checked = this.props.checked;
var checkedLeft = width - height + 1;
var startLeft = checked ? checkedLeft : 1;
var newLeft = startLeft + clientX - startX;
var left = Math.min(checkedLeft, Math.max(1, newLeft));
this.setState({ left: left, isDragging: true });
var startPos = checked ? this.checkedPos : this.uncheckedPos;
var newPos = startPos + clientX - startX;
var pos = Math.min(this.checkedPos, Math.max(this.uncheckedPos, newPos));
this.setState({ pos: pos, isDragging: true });
}

@@ -97,9 +102,7 @@ }, {

var _state = this.state,
left = _state.left,
pos = _state.pos,
isDragging = _state.isDragging;
var _props3 = this.props,
checked = _props3.checked,
onChange = _props3.onChange,
width = _props3.width,
height = _props3.height;
var _props = this.props,
checked = _props.checked,
onChange = _props.onChange;

@@ -113,7 +116,5 @@ // Simulate clicking the handle

}
var checkedLeft = width - height + 1;
if (checked) {
if (left > (checkedLeft + 1) / 2) {
this.setState({ left: checkedLeft, startX: null, isDragging: false, hasOutline: false });
if (pos > (this.checkedPos + this.uncheckedPos) / 2) {
this.setState({ pos: this.checkedPos, startX: null, isDragging: false, hasOutline: false });
return;

@@ -125,4 +126,4 @@ }

}
if (left < (checkedLeft + 1) / 2) {
this.setState({ left: 1, startX: null, isDragging: false, hasOutline: false });
if (pos < (this.checkedPos + this.uncheckedPos) / 2) {
this.setState({ pos: this.uncheckedPos, startX: null, isDragging: false, hasOutline: false });
return;

@@ -144,3 +145,2 @@ }

document.addEventListener('mouseup', this.handleMouseUp);
console.log('mousedown');
}

@@ -152,3 +152,2 @@ }, {

this.handleDrag(event.clientX);
console.log('mousemove');
}

@@ -161,3 +160,2 @@ }, {

document.removeEventListener('mouseup', this.handleMouseUp);
console.log('mouseup');
}

@@ -170,3 +168,2 @@

value: function handleTouchStart(event) {
console.log('touchstart');
this.handleDragStart(event.touches[0].clientX);

@@ -177,3 +174,2 @@ }

value: function handleTouchMove(event) {
console.log('touchmove');
this.handleDrag(event.touches[0].clientX);

@@ -184,3 +180,2 @@ }

value: function handleTouchEnd(event) {
console.log('touchend');
event.preventDefault();

@@ -192,3 +187,2 @@ this.handleDragStop();

value: function handleTouchCancel() {
console.log('touchcancel');
this.setState({ startX: null, hasOutline: false });

@@ -199,5 +193,5 @@ }

value: function handleClick() {
var _props4 = this.props,
checked = _props4.checked,
onChange = _props4.onChange;
var _props2 = this.props,
checked = _props2.checked,
onChange = _props2.onChange;

@@ -209,5 +203,5 @@ onChange(!checked);

value: function handleKeyDown(event) {
var _props5 = this.props,
checked = _props5.checked,
onChange = _props5.onChange;
var _props3 = this.props,
checked = _props3.checked,
onChange = _props3.onChange;
var isDragging = this.state.isDragging;

@@ -226,99 +220,100 @@ // Trigger change on spacebar and enter keys (in violation of wai-aria spec).

var _props6 = this.props,
checked = _props6.checked,
disabled = _props6.disabled,
className = _props6.className,
offColor = _props6.offColor,
onColor = _props6.onColor,
handleColor = _props6.handleColor,
activeHandleColor = _props6.activeHandleColor,
checkedIcon = _props6.checkedIcon,
uncheckedIcon = _props6.uncheckedIcon,
boxShadow = _props6.boxShadow,
height = _props6.height,
width = _props6.width,
id = _props6.id,
ariaLabelledby = _props6['aria-labelledby'],
ariaLabel = _props6['aria-label'];
var _props4 = this.props,
checked = _props4.checked,
disabled = _props4.disabled,
className = _props4.className,
offColor = _props4.offColor,
onColor = _props4.onColor,
offHandleColor = _props4.offHandleColor,
onHandleColor = _props4.onHandleColor,
checkedIcon = _props4.checkedIcon,
uncheckedIcon = _props4.uncheckedIcon,
boxShadow = _props4.boxShadow,
activeBoxShadow = _props4.activeBoxShadow,
height = _props4.height,
width = _props4.width,
id = _props4.id,
ariaLabelledby = _props4['aria-labelledby'],
ariaLabel = _props4['aria-label'];
var _state2 = this.state,
left = _state2.left,
pos = _state2.pos,
isDragging = _state2.isDragging,
startX = _state2.startX,
hasOutline = _state2.hasOutline;
var checkedLeft = width - height + 1;
var rootStyle = {
position: 'relative',
display: 'inline-block',
opacity: disabled ? 0.5 : 1,
borderRadius: height / 2,
WebkitTransition: 'opacity 0.25s',
MozTransition: 'opacity 0.25s',
transition: 'opacity 0.25s'
// width
};
var backgroundStyle = {
height: height,
width: width,
background: offColor,
margin: Math.max(0, (this.handleDiameter - height) / 2),
position: 'relative',
cursor: disabled ? 'default' : 'pointer',
background: (0, _getBackgroundColor2.default)(pos, this.checkedPos, this.uncheckedPos, offColor, onColor),
borderRadius: height / 2,
display: 'inline-block',
WebkitTransition: isDragging ? null : 'background 0.25s',
MozTransition: isDragging ? null : 'background 0.25s',
transition: isDragging ? null : 'background 0.25s'
};
var checkedStyle = {
position: 'relative',
opacity: disabled ? 0.5 : 1,
WebkitTransition: 'all 0.2s',
MozTransition: 'all 0.2s',
transition: 'all 0.2s',
cursor: disabled ? 'default' : 'pointer'
opacity: (pos - this.uncheckedPos) / (this.checkedPos - this.uncheckedPos),
width: Math.min(height * 1.5, width - (this.handleDiameter + height) / 2 + 1),
height: height,
pointerEvents: 'none',
WebkitTransition: isDragging ? null : 'opacity 0.25s',
MozTransition: isDragging ? null : 'opacity 0.25s',
transition: isDragging ? null : 'opacity 0.25s'
};
var foregroundStyle = {
var uncheckedStyle = {
opacity: 1 - (pos - this.uncheckedPos) / (this.checkedPos - this.uncheckedPos),
width: Math.min(height * 1.5, width - (this.handleDiameter + height) / 2 + 1),
height: height,
width: width,
opacity: (left - 1) / (checkedLeft - 1),
background: onColor,
WebkitTransition: isDragging ? null : 'opacity 0.2s ease-out',
MozTransition: isDragging ? null : 'opacity 0.2s ease-out',
transition: isDragging ? null : 'opacity 0.2s ease-out',
borderRadius: height / 2
position: 'absolute',
right: 0,
top: 0,
pointerEvents: 'none',
WebkitTransition: isDragging ? null : 'opacity 0.25s',
MozTransition: isDragging ? null : 'opacity 0.25s',
transition: isDragging ? null : 'opacity 0.25s'
};
var handleStyle = {
height: height - 2,
width: height - 2,
background: startX ? activeHandleColor : handleColor,
height: this.handleDiameter,
width: this.handleDiameter,
background: (0, _getBackgroundColor2.default)(pos, this.checkedPos, this.uncheckedPos, offHandleColor, onHandleColor),
touchAction: 'none',
WebkitTransition: isDragging ? null : 'left 0.2s ease-out',
MozTransition: isDragging ? null : 'left 0.2s ease-out',
transition: isDragging ? null : 'left 0.2s ease-out',
cursor: disabled ? 'default' : 'pointer',
WebkitTransition: isDragging ? null : 'background-color 0.25s, left 0.25s, box-shadow 0.1s',
MozTransition: isDragging ? null : 'background-color 0.25s, left 0.25s, box-shadow 0.1s',
transition: isDragging ? null : 'background-color 0.25s, left 0.25s, box-shadow 0.1s',
display: 'inline-block',
borderRadius: '50%',
position: 'absolute',
left: left,
top: 1,
left: pos,
top: Math.max(0, (height - this.handleDiameter) / 2),
border: 0,
outline: 0,
boxShadow: hasOutline ? boxShadow : null
boxShadow: hasOutline ? activeBoxShadow : boxShadow
};
var uncheckedStyle = {
position: 'absolute',
right: 0,
opacity: 1 - (left - 1) / (checkedLeft - 1),
width: Math.min(height, width - height + 2),
height: height,
pointerEvents: 'none'
};
var checkedStyle = {
width: Math.min(height, width - height + 2),
height: height,
pointerEvents: 'none'
};
return _react2.default.createElement(
'div',
{
className: className,
style: backgroundStyle
},
uncheckedIcon ? _react2.default.createElement(
'div',
{ style: uncheckedStyle },
uncheckedIcon
) : null,
{ className: className, style: rootStyle },
_react2.default.createElement(
'div',
{
className: 'react-switch-fg',
style: foregroundStyle,
className: 'react-switch-bg',
style: backgroundStyle,
onClick: disabled ? null : this.handleClick

@@ -330,5 +325,11 @@ },

checkedIcon
) : null,
uncheckedIcon ? _react2.default.createElement(
'div',
{ style: uncheckedStyle },
uncheckedIcon
) : null
),
_react2.default.createElement('div', {
className: 'react-switch-handle',
role: 'checkbox',

@@ -349,3 +350,2 @@ tabIndex: disabled ? null : 0,

onTransitionEnd: this.handleTransitionEnd,
className: 'react-switch-handle',
style: handleStyle,

@@ -369,12 +369,14 @@ id: id,

disabled: _propTypes2.default.bool,
className: _propTypes2.default.string,
offColor: _propTypes2.default.string,
onColor: _propTypes2.default.string,
handleColor: _propTypes2.default.string,
activeHandleColor: _propTypes2.default.string,
offHandleColor: _propTypes2.default.string,
onHandleColor: _propTypes2.default.string,
handleDiameter: _propTypes2.default.number,
uncheckedIcon: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.element]),
checkedIcon: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.element]),
uncheckedIcon: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.element]),
boxShadow: _propTypes2.default.string,
activeBoxShadow: _propTypes2.default.string,
height: _propTypes2.default.number,
width: _propTypes2.default.number,
className: _propTypes2.default.string,
id: _propTypes2.default.string,

@@ -387,9 +389,11 @@ 'aria-labelledby': _propTypes2.default.string,

disabled: false,
offColor: 'grey',
onColor: 'green',
handleColor: 'white',
activeHandleColor: '#ddd',
offColor: '#888',
onColor: '#080',
offHandleColor: '#fff',
onHandleColor: '#fff',
handleDiameter: null,
uncheckedIcon: _icons.uncheckedIcon,
checkedIcon: _icons.checkedIcon,
uncheckedIcon: _icons.uncheckedIcon,
boxShadow: '0px 0px 1px 2px #4D90FE',
boxShadow: null,
activeBoxShadow: '0px 0px 2px 3px #33bbff',
height: 28,

@@ -396,0 +400,0 @@ width: 56,

{
"name": "react-switch",
"version": "2.0.0-rc.1",
"version": "2.0.0-rc.2",
"description": "Draggable toggle-switch component for react",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -8,3 +8,4 @@ # react-switch

<img src="https://media.giphy.com/media/l1J9OD7acbBrtYrWU/giphy.gif" />
<img src="https://media.giphy.com/media/l0IsI0EHlJx2kyCrK/giphy.gif" />
<img src="https://media.giphy.com/media/3ov9k7TupiaveDlQ5O/giphy.gif" />

@@ -14,3 +15,3 @@

[Take a look at the demo.](https://yogaboll.github.io/react-switch/)
[Take a look at the demo](https://yogaboll.github.io/react-switch/)

@@ -60,11 +61,16 @@ ## Installation

| disabled | bool | false | When disabled, the switch will no longer be interactive and its colors will be greyed out. |
| offColor | string | 'grey' | The switch will take on this color when it is *not* checked |
| onColor | string | 'green' | The switch will take on this color when it is checked. |
| handleColor | string | 'white' | The handle of the switch will take on this color when it is *not* active. If you use this prop, make sure to also change *activeHandleColor* to something appropriate. |
| activeHandleColor | string | '#ddd' | The handle of the switch will take on this color when it is active, meaning when it is dragged or clicked. |
| height | number | 28 | The height of the component, measured in pixels. |
| width | number | 56 | The width of the component, measured in pixels. |
| className | string | null | Set as the className of the outer shell of the switch. |
| offColor | string | '#888' | The switch will take on this color when it is *not* checked |
| onColor | string | '#080' | The switch will take on this color when it is checked. |
| offHandleColor | string | '#fff' | The handle of the switch will take on this color when it is *not* checked. |
| onHandleColor | string | '#fff' | The handle of the switch will take on this color when it is checked. |
| handleDiameter | number | null | The diameter of the handle, measured in pixels. By default it will be slightly smaller than the height of the switch. |
| uncheckedIcon | element *or* bool | [Default value](https://github.com/yogaboll/react-switch/blob/master/src/icons.jsx) | An icon that will be shown on the switch when it is **not** checked. Pass in *false* if you don't want any icon. |
| checkedIcon | element *or* bool | [Default value](https://github.com/yogaboll/react-switch/blob/master/src/icons.jsx) | An icon that will be shown on the switch when it is checked. Pass in *false* if you don't want any icon. |
| boxShadow | string | null | The default box-shadow of the handle. You can read up on the box-shadow syntax [on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow?v=b). |
| activeBoxShadow | string | '0px 0px 2px 3px #33bbff' | The box-shadow of the handle when it is active or focused. Do not set this to null, since it is important for accessibility.
| height | number | 28 | The height of the background of the switch, measured in pixels. |
| width | number | 56 | The width of the background of the switch, measured in pixels. |
| className | string | null | Set as the className of the outer shell of the switch. Useful for positioning the switch. |
| id | string | null | Set as an attribute to the embedded checkbox. This is useful for the associated label, which can point to the id in its htmlFor attribute. |
| aria-labelledby | string | null | Set as an attribute of the embedded checkbox. This should be the same as the id of a label. |
| aria-labelledby | string | null | Set as an attribute of the embedded checkbox. This should be the same as the id of a label. You should use this if you don't want your label to be a \<label> element|
| aria-label | string | null | Set as an attribute of the embedded checkbox. Its value will only be seen by screen readers. |

@@ -71,0 +77,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc