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 1.2.0 to 2.0.0-rc.1

__tests__/__snapshots__/Switch.test.jsx.snap

18

CHANGELOG.md

@@ -7,2 +7,20 @@ # Changelog

## [Unfinished]
### Added
- New prop boxShadow. It acts just like outline, but I called it boxShadow since that is the actual css attribute that is being controlled.
- New props checkedIcon and uncheckedIcon. They have a checkmark and an x as default. Custom elements can be given as icons or the boolean value 'false', which will remove icons.
### Refactor
- Dependency on 'react-draggable' is removed and replaced with new drag logic.
### Fixed
- Glitch related to faulty 'inTransition' state fixed due to inTransition no longer existing.
## Changed
- Outline disappears when the users stops holding down the mouse. This is the same behaviour as google's switch-button implementation.
- onChange callback function is now also triggered when enter key is pressed in violation of wai-aria checkbox spec. This is reasonably since it's in the toggle-button spec.
## Removed
- The deprecated 'name' and 'value' properties are removed.
## [1.2.0 - 2017-09-29]

@@ -9,0 +27,0 @@ ### Fixed

287

dist/index.js

@@ -17,3 +17,3 @@ 'use strict';

var _reactDraggable = require('react-draggable');
var _icons = require('./icons');

@@ -36,14 +36,19 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_this.handleClick = _this.handleClick.bind(_this);
_this.handleDragStart = _this.handleDragStart.bind(_this);
_this.handleDrag = _this.handleDrag.bind(_this);
_this.handleDragStop = _this.handleDragStop.bind(_this);
_this.handleTransitionEnd = _this.handleTransitionEnd.bind(_this);
_this.handleMouseDown = _this.handleMouseDown.bind(_this);
_this.handleMouseMove = _this.handleMouseMove.bind(_this);
_this.handleMouseUp = _this.handleMouseUp.bind(_this);
_this.handleTouchStart = _this.handleTouchStart.bind(_this);
_this.handleTouchMove = _this.handleTouchMove.bind(_this);
_this.handleTouchEnd = _this.handleTouchEnd.bind(_this);
_this.handleTouchCancel = _this.handleTouchCancel.bind(_this);
_this.handleClick = _this.handleClick.bind(_this);
_this.handleKeyDown = _this.handleKeyDown.bind(_this);
_this.state = {
left: props.checked ? props.width - props.height + 1 : 1,
inTransition: false,
startX: null,
isDragging: false,
focused: false
hasOutline: false
};

@@ -55,4 +60,4 @@ return _this;

key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var left = this.state.left;
value: function componentWillReceiveProps(_ref) {
var checked = _ref.checked;
var _props = this.props,

@@ -63,55 +68,18 @@ width = _props.width,

var checkedLeft = width - height + 1;
var newLeft = nextProps.checked ? checkedLeft : 1;
/* !IMPORTANT: Don't set inTransition to true if the new and old left-position
is the same since this will not trigger the transition */
if (left !== newLeft) {
this.setState({
left: newLeft,
inTransition: true
});
}
var left = checked ? checkedLeft : 1;
this.setState({ left: left });
}
}, {
key: 'handleClick',
value: function handleClick() {
var _props2 = this.props,
checked = _props2.checked,
onChange = _props2.onChange;
onChange(!checked);
}
}, {
key: 'handleKeyDown',
value: function handleKeyDown(event) {
var _props3 = this.props,
checked = _props3.checked,
onChange = _props3.onChange;
var isDragging = this.state.isDragging;
// Trigger change only on spacebar key in accordance with wai-aria spec
if (event.keyCode === 32 && !isDragging) {
event.preventDefault();
onChange(!checked);
}
}
}, {
key: 'handleDragStart',
value: function handleDragStart(event) {
var inTransition = this.state.inTransition;
if (inTransition) {
return;
}
var clientX = event.clientX || event.touches[0].clientX;
this.setState({ startX: clientX });
value: function handleDragStart(clientX) {
this.setState({ startX: clientX, hasOutline: true });
}
}, {
key: 'handleDrag',
value: function handleDrag(event) {
var clientX = event.clientX || event.touches[0].clientX;
var _props4 = this.props,
checked = _props4.checked,
width = _props4.width,
height = _props4.height;
value: function handleDrag(clientX) {
var startX = this.state.startX;
var _props2 = this.props,
checked = _props2.checked,
width = _props2.width,
height = _props2.height;

@@ -130,18 +98,13 @@ var checkedLeft = width - height + 1;

left = _state.left,
isDragging = _state.isDragging,
inTransition = _state.inTransition;
isDragging = _state.isDragging;
var _props3 = this.props,
checked = _props3.checked,
onChange = _props3.onChange,
width = _props3.width,
height = _props3.height;
if (inTransition) {
return;
}
var _props5 = this.props,
checked = _props5.checked,
onChange = _props5.onChange,
width = _props5.width,
height = _props5.height;
// Simulate clicking the handle
if (!isDragging) {
this.setState({ startX: null });
this.setState({ startX: null, hasOutline: false });
onChange(!checked);

@@ -154,6 +117,6 @@ return;

if (left > (checkedLeft + 1) / 2) {
this.setState({ left: checkedLeft, startX: null, isDragging: false });
this.setState({ left: checkedLeft, startX: null, isDragging: false, hasOutline: false });
return;
}
this.setState({ startX: null, isDragging: false });
this.setState({ startX: null, isDragging: false, hasOutline: false });
onChange(false);

@@ -163,14 +126,88 @@ return;

if (left < (checkedLeft + 1) / 2) {
this.setState({ left: 1, startX: null, isDragging: false });
this.setState({ left: 1, startX: null, isDragging: false, hasOutline: false });
return;
}
this.setState({ startX: null, isDragging: false });
this.setState({ startX: null, isDragging: false, hasOutline: false });
onChange(true);
}
}, {
key: 'handleTransitionEnd',
value: function handleTransitionEnd() {
this.setState({ inTransition: false });
key: 'handleMouseDown',
value: function handleMouseDown(event) {
// Ignore right click and scroll
if (typeof event.button === 'number' && event.button !== 0) {
return;
}
this.handleDragStart(event.clientX);
document.addEventListener('mousemove', this.handleMouseMove);
document.addEventListener('mouseup', this.handleMouseUp);
console.log('mousedown');
}
}, {
key: 'handleMouseMove',
value: function handleMouseMove(event) {
event.preventDefault();
this.handleDrag(event.clientX);
console.log('mousemove');
}
}, {
key: 'handleMouseUp',
value: function handleMouseUp() {
this.handleDragStop();
document.removeEventListener('mousemove', this.handleMouseMove);
document.removeEventListener('mouseup', this.handleMouseUp);
console.log('mouseup');
}
// TODO: Prevent mouse events from triggering on touch events.
}, {
key: 'handleTouchStart',
value: function handleTouchStart(event) {
console.log('touchstart');
this.handleDragStart(event.touches[0].clientX);
}
}, {
key: 'handleTouchMove',
value: function handleTouchMove(event) {
console.log('touchmove');
this.handleDrag(event.touches[0].clientX);
}
}, {
key: 'handleTouchEnd',
value: function handleTouchEnd(event) {
console.log('touchend');
event.preventDefault();
this.handleDragStop();
}
}, {
key: 'handleTouchCancel',
value: function handleTouchCancel() {
console.log('touchcancel');
this.setState({ startX: null, hasOutline: false });
}
}, {
key: 'handleClick',
value: function handleClick() {
var _props4 = this.props,
checked = _props4.checked,
onChange = _props4.onChange;
onChange(!checked);
}
}, {
key: 'handleKeyDown',
value: function handleKeyDown(event) {
var _props5 = this.props,
checked = _props5.checked,
onChange = _props5.onChange;
var isDragging = this.state.isDragging;
// Trigger change on spacebar and enter keys (in violation of wai-aria spec).
if ((event.keyCode === 32 || event.keyCode === 13) && !isDragging) {
event.preventDefault();
onChange(!checked);
}
}
}, {
key: 'render',

@@ -188,7 +225,8 @@ value: function render() {

activeHandleColor = _props6.activeHandleColor,
checkedIcon = _props6.checkedIcon,
uncheckedIcon = _props6.uncheckedIcon,
boxShadow = _props6.boxShadow,
height = _props6.height,
width = _props6.width,
id = _props6.id,
name = _props6.name,
value = _props6.value,
ariaLabelledby = _props6['aria-labelledby'],

@@ -200,3 +238,3 @@ ariaLabel = _props6['aria-label'];

startX = _state2.startX,
focused = _state2.focused;
hasOutline = _state2.hasOutline;

@@ -234,2 +272,3 @@ var checkedLeft = width - height + 1;

background: startX ? activeHandleColor : handleColor,
touchAction: 'none',
WebkitTransition: isDragging ? null : 'left 0.2s ease-out',

@@ -245,5 +284,19 @@ MozTransition: isDragging ? null : 'left 0.2s ease-out',

outline: 0,
boxShadow: focused ? '0px 0px 1px 2px #4D90FE' : null
boxShadow: hasOutline ? boxShadow : null
};
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(

@@ -255,37 +308,44 @@ 'div',

},
_react2.default.createElement('div', {
className: 'react-switch-fg',
style: foregroundStyle,
onClick: disabled ? null : this.handleClick
}),
uncheckedIcon ? _react2.default.createElement(
'div',
{ style: uncheckedStyle },
uncheckedIcon
) : null,
_react2.default.createElement(
_reactDraggable.DraggableCore,
'div',
{
onStart: this.handleDragStart,
onDrag: this.handleDrag,
onStop: this.handleDragStop,
disabled: disabled
className: 'react-switch-fg',
style: foregroundStyle,
onClick: disabled ? null : this.handleClick
},
_react2.default.createElement('div', {
role: 'checkbox',
tabIndex: disabled ? null : 0,
'aria-checked': checked,
'aria-disabled': disabled,
onTransitionEnd: this.handleTransitionEnd,
onKeyDown: this.handleKeyDown,
onFocus: function onFocus() {
return _this2.setState({ focused: true });
},
onBlur: function onBlur() {
return _this2.setState({ focused: false });
},
className: 'react-switch-handle',
style: handleStyle,
id: id,
name: name,
value: value,
'aria-labelledby': ariaLabelledby,
'aria-label': ariaLabel
})
)
checkedIcon ? _react2.default.createElement(
'div',
{ style: checkedStyle },
checkedIcon
) : null
),
_react2.default.createElement('div', {
role: 'checkbox',
tabIndex: disabled ? null : 0,
onMouseDown: disabled ? null : this.handleMouseDown,
onTouchStart: disabled ? null : this.handleTouchStart,
onTouchMove: disabled ? null : this.handleTouchMove,
onTouchEnd: disabled ? null : this.handleTouchEnd,
onTouchCancel: disabled ? null : this.handleTouchCancel,
onKeyDown: this.handleKeyDown,
onFocus: function onFocus() {
return _this2.setState({ hasOutline: true });
},
onBlur: function onBlur() {
return _this2.setState({ hasOutline: false });
},
onTransitionEnd: this.handleTransitionEnd,
className: 'react-switch-handle',
style: handleStyle,
id: id,
'aria-checked': checked,
'aria-disabled': disabled,
'aria-labelledby': ariaLabelledby,
'aria-label': ariaLabel
})
);

@@ -307,10 +367,10 @@ }

activeHandleColor: _propTypes2.default.string,
checkedIcon: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.element]),
uncheckedIcon: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.element]),
boxShadow: _propTypes2.default.string,
height: _propTypes2.default.number,
width: _propTypes2.default.number,
id: _propTypes2.default.string,
name: _propTypes2.default.string,
value: _propTypes2.default.string,
'aria-labelledby': _propTypes2.default.string,
'aria-label': _propTypes2.default.string
};

@@ -324,2 +384,5 @@

activeHandleColor: '#ddd',
checkedIcon: _icons.checkedIcon,
uncheckedIcon: _icons.uncheckedIcon,
boxShadow: '0px 0px 1px 2px #4D90FE',
height: 28,

@@ -329,4 +392,2 @@ width: 56,

id: null,
name: null,
value: null,
'aria-labelledby': null,

@@ -333,0 +394,0 @@ 'aria-label': null

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

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

"prepublishOnly": "npm run build",
"test": "jest --verbose",
"test": "jest",
"test:watch": "jest --watch",
"start": "webpack-dev-server",
"stats": "webpack --profile --json > stats.json"
"stats": "webpack -p --profile --json > stats.json && webpack-bundle-analyzer stats.json examples/dist -s gzip"
},

@@ -40,3 +41,5 @@ "repository": {

"css-loader": "^0.28.7",
"enzyme": "^2.9.1",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.0.0",
"enzyme-to-json": "^3.0.1",
"eslint": "^4.6.1",

@@ -50,12 +53,11 @@ "eslint-config-airbnb": "^15.1.0",

"prop-types": "^15.6.0",
"raf": "^3.3.2",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-test-renderer": "^15.6.1",
"react-test-renderer": "^16.0.0",
"style-loader": "^0.18.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.8.2"
},
"dependencies": {
"react-draggable": "^3.0.3"
},
"keywords": [

@@ -62,0 +64,0 @@ "switch",

# react-switch
[![npm](https://img.shields.io/npm/v/react-switch.svg)]()
[![npm](https://img.shields.io/npm/dm/react-switch.svg)]()
[![npm](https://img.shields.io/npm/v/react-switch.svg)](https://www.npmjs.com/package/react-switch)
[![npm](https://img.shields.io/npm/dm/react-switch.svg)](https://www.npmjs.com/package/react-switch)
[![GitHub stars](https://img.shields.io/github/stars/yogaboll/react-switch.svg?style=social&label=Stars)](https://github.com/yogaboll/react-switch)

@@ -5,0 +6,0 @@ A draggable, customizable and accessible toggle-switch component for React.

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