react-checkbox-group
Advanced tools
Comparing version 4.0.0-beta to 4.0.0
{ | ||
"name": "react-checkbox-group", | ||
"version": "4.0.0-beta", | ||
"version": "4.0.0", | ||
"description": "Sensible checkbox groups manipulation for DOM.", | ||
"main": "react-checkbox-group.js", | ||
"scripts": { | ||
"test": "mocha --compilers js:babel-core/register --require ./test/test_helper.js --recursive", | ||
"test": "mocha --require babel-core/register --require ./test/test_helper.js --recursive", | ||
"test:watch": "npm run test -- --watch", | ||
@@ -32,12 +32,12 @@ "prepublish": "babel ./react-checkbox-group.jsx --out-file ./react-checkbox-group.js" | ||
"babel-cli": "^6.6.5", | ||
"babel-plugin-transform-class-properties": "^6.24.1", | ||
"babel-plugin-transform-object-rest-spread": "^6.6.5", | ||
"babel-plugin-transform-class-properties": "^6.24.1", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babel-preset-react": "^6.1.18", | ||
"chai": "^3.5.0", | ||
"jsdom": "^8.1.0", | ||
"mocha": "^2.4.5", | ||
"react": "^15.0.1", | ||
"react-dom": "^15.0.1" | ||
"chai": "^4.1.2", | ||
"jsdom": "^11.3.0", | ||
"mocha": "^4.0.1", | ||
"react": "^16.0.0", | ||
"react-dom": "^16.0.0" | ||
} | ||
} |
@@ -71,2 +71,4 @@ 'use strict'; | ||
Checkbox.displayName = 'Checkbox'; | ||
var CheckboxGroup = exports.CheckboxGroup = function (_Component2) { | ||
@@ -80,5 +82,31 @@ _inherits(CheckboxGroup, _Component2); | ||
_this2._prepareBoxes = function (children) { | ||
var maxDepth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; | ||
var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; | ||
if (depth > maxDepth) { | ||
return children; | ||
} | ||
var checkboxGroup = { | ||
name: _this2.props.name, | ||
checkedValues: _this2.state.value, | ||
onChange: _this2._onCheckboxChange | ||
}; | ||
return _react2.default.Children.map(children, function (child) { | ||
if (!child.$$typeof) { | ||
return child; | ||
} else if (child.type === Checkbox) { | ||
return _react2.default.cloneElement(child, { checkboxGroup: checkboxGroup }); | ||
} else { | ||
return _react2.default.cloneElement(child, {}, child.props.children ? _react2.default.Children.map(child.props.children, function (c) { | ||
return _this2._prepareBoxes(c, maxDepth, depth + 1); | ||
}) : null); | ||
} | ||
}); | ||
}; | ||
_this2._isControlledComponent = _this2._isControlledComponent.bind(_this2); | ||
_this2._onCheckboxChange = _this2._onCheckboxChange.bind(_this2); | ||
_this2._prepareBoxes = _this2._prepareBoxes.bind(_this2); | ||
_this2.getValue = _this2.getValue.bind(_this2); | ||
@@ -101,23 +129,2 @@ _this2.state = { | ||
}, { | ||
key: '_prepareBoxes', | ||
value: function _prepareBoxes(children) { | ||
var _this3 = this; | ||
var checkboxGroup = { | ||
name: this.props.name, | ||
checkedValues: this.state.value, | ||
onChange: this._onCheckboxChange | ||
}; | ||
return _react2.default.Children.map(children, function (child) { | ||
if (!child.$$typeof) { | ||
return child; | ||
} else if (child.type === Checkbox) { | ||
return _react2.default.cloneElement(child, { checkboxGroup: checkboxGroup }); | ||
} else { | ||
return _react2.default.cloneElement(child, {}, child.props.children ? _react2.default.Children.map(child.props.children, _this3._prepareBoxes) : null); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -131,3 +138,5 @@ value: function render() { | ||
children = _props2.children, | ||
rest = _objectWithoutProperties(_props2, ['Component', 'name', 'value', 'onChange', 'children']); | ||
_props2$checkboxDepth = _props2.checkboxDepth, | ||
checkboxDepth = _props2$checkboxDepth === undefined ? 1 : _props2$checkboxDepth, | ||
rest = _objectWithoutProperties(_props2, ['Component', 'name', 'value', 'onChange', 'children', 'checkboxDepth']); | ||
@@ -137,3 +146,3 @@ return _react2.default.createElement( | ||
rest, | ||
this._prepareBoxes(children) | ||
this._prepareBoxes(children, checkboxDepth) | ||
); | ||
@@ -178,4 +187,5 @@ } | ||
CheckboxGroup.displayName = 'CheckboxGroup'; | ||
CheckboxGroup.defaultProps = { | ||
Component: "div" | ||
}; |
import React, {Component} from 'react'; | ||
export class Checkbox extends Component { | ||
displayName: 'Checkbox'; | ||
static displayName = 'Checkbox'; | ||
@@ -29,3 +29,3 @@ componentWillMount() { | ||
{...optional} | ||
/> | ||
/> | ||
); | ||
@@ -36,7 +36,7 @@ } | ||
export class CheckboxGroup extends Component { | ||
displayName: 'CheckboxGroup'; | ||
static displayName = 'CheckboxGroup'; | ||
static defaultProps = { | ||
Component: "div" | ||
} | ||
}; | ||
@@ -47,3 +47,2 @@ constructor(props) { | ||
this._onCheckboxChange = this._onCheckboxChange.bind(this); | ||
this._prepareBoxes = this._prepareBoxes.bind(this); | ||
this.getValue = this.getValue.bind(this); | ||
@@ -63,3 +62,7 @@ this.state = { | ||
_prepareBoxes(children) { | ||
_prepareBoxes = (children, maxDepth=1, depth=1) => { | ||
if (depth > maxDepth) { | ||
return children; | ||
} | ||
const checkboxGroup = { | ||
@@ -79,10 +82,10 @@ name: this.props.name, | ||
else { | ||
return React.cloneElement(child, {}, child.props.children ? React.Children.map(child.props.children, this._prepareBoxes) : null) | ||
return React.cloneElement(child, {}, child.props.children ? React.Children.map(child.props.children, c => this._prepareBoxes(c, maxDepth, depth + 1)) : null) | ||
} | ||
}) | ||
} | ||
}); | ||
}; | ||
render() { | ||
const {Component, name, value, onChange, children, ...rest} = this.props; | ||
return <Component {...rest}>{this._prepareBoxes(children)}</Component>; | ||
const {Component, name, value, onChange, children, checkboxDepth = 1, ...rest} = this.props; | ||
return <Component {...rest}>{this._prepareBoxes(children, checkboxDepth)}</Component>; | ||
} | ||
@@ -89,0 +92,0 @@ |
# [React](http://facebook.github.io/react/)-checkbox-group | ||
### Heavily inspired from https://github.com/chenglou/react-radio-group | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/ziad-saab/react-checkbox-group.svg)](https://greenkeeper.io/) | ||
[![Build Status](https://travis-ci.org/ziad-saab/react-checkbox-group.svg?branch=master)](https://travis-ci.org/ziad-saab/react-checkbox-group) | ||
@@ -70,2 +72,7 @@ | ||
## Nested `Checkbox` | ||
If you render `Checkbox`es deeply nested inside the `CheckboxGroup`, you need to pass a `checkboxDepth` prop to the `CheckboxGroup` so that it can manage the checkboxes without too much overhead. | ||
This is shown in the example below where the `<Checkbox>` elements are nested inside `<label>`s. | ||
## Example | ||
@@ -96,2 +103,3 @@ | ||
<CheckboxGroup | ||
checkboxDepth={2} // This is needed to optimize the checkbox group | ||
name="fruits" | ||
@@ -98,0 +106,0 @@ value={this.state.fruits} |
@@ -17,5 +17,16 @@ import React from 'react'; | ||
it('Renders correctly when `Checkbox` is not a direct child of `CheckboxGroup`', function() { | ||
var component = renderIntoDocument( | ||
<CheckboxGroup name="fruit"> | ||
it('Fails when `Checkbox` is not a direct child of `CheckboxGroup`', function() { | ||
expect(() => { | ||
renderIntoDocument( | ||
<CheckboxGroup name="fruit"> | ||
<label><Checkbox value="kiwi"/> Kiwi</label> | ||
<label><Checkbox value="watermelon"/> Watermelon</label> | ||
</CheckboxGroup> | ||
); | ||
}).to.throw(); | ||
}); | ||
it('Renders correctly when `Checkbox` is not a direct child of `CheckboxGroup` and `checkboxDepth` is passed', function() { | ||
const component = renderIntoDocument( | ||
<CheckboxGroup checkboxDepth={2} name="fruit"> | ||
<label><Checkbox value="kiwi"/> Kiwi</label> | ||
@@ -25,6 +36,8 @@ <label><Checkbox value="watermelon"/> Watermelon</label> | ||
); | ||
expect(component).to.be.ok; | ||
}); | ||
it('Passes the `name` prop down to the boxes', function() { | ||
var component = renderIntoDocument( | ||
const component = renderIntoDocument( | ||
<CheckboxGroup name="fruit"> | ||
@@ -35,3 +48,3 @@ <Checkbox value="kiwi"/> | ||
); | ||
var boxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"][name="fruit"]'); | ||
const boxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"][name="fruit"]'); | ||
@@ -42,4 +55,4 @@ expect(boxes.length).to.equal(2); | ||
it('Disables a box when `disabled` is used', function() { | ||
var disabled = true; | ||
var component = renderIntoDocument( | ||
const disabled = true; | ||
const component = renderIntoDocument( | ||
<CheckboxGroup name="fruit"> | ||
@@ -52,3 +65,3 @@ <Checkbox value="kiwi" disabled={disabled}/> | ||
var disabledBoxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"][name="fruit"][disabled]'); | ||
const disabledBoxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"][name="fruit"][disabled]'); | ||
@@ -59,4 +72,4 @@ expect(disabledBoxes.length).to.equal(2); | ||
it('Checks the correct boxes when `defaultValue` is used', function() { | ||
var fruits = ['watermelon', 'pineapple']; | ||
var component = renderIntoDocument( | ||
const fruits = ['watermelon', 'pineapple']; | ||
const component = renderIntoDocument( | ||
<CheckboxGroup name="fruit" defaultValue={fruits}> | ||
@@ -69,3 +82,3 @@ <Checkbox value="kiwi"/> | ||
var checkedBoxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"]:checked'); | ||
const checkedBoxes = ReactDOM.findDOMNode(component).querySelectorAll('input[type="checkbox"]:checked'); | ||
@@ -79,6 +92,6 @@ expect(checkedBoxes.length).to.equal(2); | ||
// Create an element to re-render to | ||
var div = document.createElement('div'); | ||
const div = document.createElement('div'); | ||
var fruits = ['watermelon', 'pineapple']; | ||
var component = ReactDOM.render( | ||
const fruits = ['watermelon', 'pineapple']; | ||
let component = ReactDOM.render( | ||
<CheckboxGroup name="fruit" defaultValue={fruits}> | ||
@@ -93,8 +106,8 @@ <Checkbox value="kiwi"/> | ||
// Check the box manually | ||
var wrapper = ReactDOM.findDOMNode(component); | ||
var box = _findInputWithValue(wrapper, 'kiwi'); | ||
const wrapper = ReactDOM.findDOMNode(component); | ||
const box = _findInputWithValue(wrapper, 'kiwi'); | ||
Simulate.change(box, {target: {checked: true}}); | ||
// Re-render with same props, defaultValue shouldn't affect it now | ||
var component = ReactDOM.render( | ||
component = ReactDOM.render( | ||
<CheckboxGroup name="fruit" defaultValue={fruits}> | ||
@@ -108,3 +121,3 @@ <Checkbox value="kiwi"/> | ||
var newValue = component.getValue(); | ||
const newValue = component.getValue(); | ||
expect(newValue.length).to.equal(3); | ||
@@ -118,6 +131,6 @@ expect(newValue).to.include('kiwi'); | ||
// Create an element to re-render to | ||
var div = document.createElement('div'); | ||
const div = document.createElement('div'); | ||
var fruits = ['watermelon', 'pineapple']; | ||
var component = ReactDOM.render( | ||
const fruits = ['watermelon', 'pineapple']; | ||
let component = ReactDOM.render( | ||
<CheckboxGroup name="fruit" value={fruits}> | ||
@@ -132,8 +145,8 @@ <Checkbox value="kiwi"/> | ||
// Check the box manually | ||
var wrapper = ReactDOM.findDOMNode(component); | ||
var box = _findInputWithValue(wrapper, 'kiwi') | ||
const wrapper = ReactDOM.findDOMNode(component); | ||
const box = _findInputWithValue(wrapper, 'kiwi'); | ||
Simulate.change(box, {target: {checked: true}}); | ||
// Re-render with same props, value should be kept | ||
var component = ReactDOM.render( | ||
component = ReactDOM.render( | ||
<CheckboxGroup name="fruit" value={fruits}> | ||
@@ -147,3 +160,3 @@ <Checkbox value="kiwi"/> | ||
var newValue = component.getValue(); | ||
const newValue = component.getValue(); | ||
expect(newValue.length).to.equal(2); | ||
@@ -157,6 +170,6 @@ expect(newValue).to.include('pineapple'); | ||
// Create an element to re-render to | ||
var div = document.createElement('div'); | ||
const div = document.createElement('div'); | ||
var fruits = ['watermelon', 'pineapple']; | ||
var component = ReactDOM.render( | ||
const fruits = ['watermelon', 'pineapple']; | ||
ReactDOM.render( | ||
<CheckboxGroup name="fruit" value={['watermelon']}> | ||
@@ -171,3 +184,3 @@ <Checkbox value="kiwi"/> | ||
// Re-render in same div with different prop value | ||
var component = ReactDOM.render( | ||
const component = ReactDOM.render( | ||
<CheckboxGroup name="fruit" value={['watermelon', 'kiwi']}> | ||
@@ -181,3 +194,3 @@ <Checkbox value="kiwi"/> | ||
var newValue = component.getValue(); | ||
const newValue = component.getValue(); | ||
expect(newValue.length).to.equal(2); | ||
@@ -190,5 +203,5 @@ expect(newValue).to.include('kiwi'); | ||
it('Calls `onChange` with the correct new value', function() { | ||
var fruits = ['kiwi', 'watermelon']; | ||
var onChangeCalled = false; | ||
var newFruits; | ||
const fruits = ['kiwi', 'watermelon']; | ||
let onChangeCalled = false; | ||
let newFruits; | ||
function onChange(newValue) { | ||
@@ -199,3 +212,3 @@ onChangeCalled = true; | ||
var component = renderIntoDocument( | ||
const component = renderIntoDocument( | ||
<CheckboxGroup name="fruit" value={fruits} onChange={onChange}> | ||
@@ -209,4 +222,4 @@ <Checkbox value="kiwi"/> | ||
// Check the box manually | ||
var wrapper = ReactDOM.findDOMNode(component); | ||
var box = _findInputWithValue(wrapper, 'pineapple'); | ||
const wrapper = ReactDOM.findDOMNode(component); | ||
const box = _findInputWithValue(wrapper, 'pineapple'); | ||
Simulate.change(box, {target: {checked: true}}); | ||
@@ -213,0 +226,0 @@ |
var jsdom = require('jsdom'); | ||
var doc = jsdom.jsdom('<!doctype html><html><body></body></html>'); | ||
var win = doc.defaultView; | ||
var { window: win } = new jsdom.JSDOM('<!doctype html><html><body></body></html>'); | ||
global.document = doc; | ||
global.window = win; | ||
global.document = win.document; | ||
Object.keys(window).forEach(function(key) { | ||
if (!(key in global)) { | ||
global[key] = window[key]; | ||
} | ||
(function() { | ||
if (!win.requestAnimationFrame) { | ||
var lastTime = 0; | ||
window.requestAnimationFrame = function(callback) { | ||
var currTime = new Date().getTime(); | ||
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); | ||
var id = window.setTimeout(function() { | ||
callback(currTime + timeToCall); | ||
}, timeToCall); | ||
lastTime = currTime + timeToCall; | ||
return id; | ||
}; | ||
win.cancelAnimationFrame = function (id) { | ||
clearTimeout(id); | ||
}; | ||
} | ||
})(); | ||
Object.keys(win).forEach(function(key) { | ||
if (!(key in global)) { | ||
global[key] = win[key]; | ||
} | ||
}); | ||
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
40123
14
461
0
128