uncontrollable
Advanced tools
Comparing version 1.3.2 to 1.4.0
"use strict"; | ||
var babelHelpers = require("./util/babelHelpers.js"); | ||
var React = require("react"); | ||
//var ReactUpdates = require('react/lib/ReactUpdates') | ||
var invariant = require("react/lib/invariant"); | ||
@@ -31,9 +30,2 @@ | ||
function forceUpdateIfMounted(ctx) { | ||
if (ctx.isMounted() && ctx._needsUpdate) { | ||
ctx._needsUpdate = false; | ||
ctx.forceUpdate(); | ||
} | ||
} | ||
module.exports = function (Component, controlledValues, taps) { | ||
@@ -66,7 +58,3 @@ var name = Component.displayName || Component.name || "Component", | ||
componentWillMount: function () { | ||
var _this = this; | ||
this.values = Object.create(null); | ||
getInitialState: function () { | ||
var props = this.props, | ||
@@ -76,8 +64,9 @@ keys = Object.keys(controlledValues); | ||
return transform(keys, function (state, key) { | ||
_this.values[key] = props[defaultKey(key)]; | ||
state[key] = props[defaultKey(key)]; | ||
}, {}); | ||
}, | ||
componentWillReceiveProps: function (nextProps) { | ||
this._needsUpdate = false; | ||
shouldComponentUpdate: function () { | ||
//let the setState trigger the update | ||
return !this._notifying; | ||
}, | ||
@@ -102,3 +91,3 @@ | ||
newProps[propName] = prop !== undefined ? prop : _this.values[propName]; | ||
newProps[propName] = prop !== undefined ? prop : _this.state[propName]; | ||
@@ -110,2 +99,3 @@ newProps[handle] = setAndNotify.bind(_this, propName); | ||
//console.log('props: ', newProps) | ||
each(taps, function (val, key) { | ||
@@ -120,4 +110,2 @@ return newProps[key] = chain(_this, val, newProps[key]); | ||
function setAndNotify(propName, value) { | ||
var _this = this; | ||
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
@@ -129,20 +117,21 @@ args[_key - 2] = arguments[_key]; | ||
handler = this.props[controlledValues[propName]]; | ||
//, controlled = handler && isProp(this.props, propName); | ||
if (linkName && isProp(this.props, linkName) && !handler) { | ||
handler = this.props[linkName].requestChange; | ||
handler = this.props[linkName].requestChange | ||
//propName = propName === 'valueLink' ? 'value' : 'checked' | ||
; | ||
} | ||
this._needsUpdate = true; | ||
this.values[propName] = value; | ||
if (handler) { | ||
this._notifying = true; | ||
handler.call.apply(handler, [this, value].concat(args)); | ||
this._notifying = false; | ||
} | ||
if (handler) handler.call.apply(handler, [this, value].concat(args)); | ||
// try { | ||
// ReactUpdates.batchedUpdates(()=> { | ||
// ReactUpdates.asap(forceUpdateIfMounted, this); | ||
// }) | ||
// } | ||
setTimeout(function () { | ||
return forceUpdateIfMounted(_this); | ||
}); | ||
this.setState((function () { | ||
var _setState = {}; | ||
_setState[propName] = value; | ||
return _setState; | ||
})()); | ||
} | ||
@@ -184,2 +173,2 @@ | ||
} | ||
// | ||
//return !controlled |
{ | ||
"name": "uncontrollable", | ||
"version": "1.3.2", | ||
"version": "1.4.0", | ||
"description": "Wrap a controlled react component, to allow spcific prop/handler pairs to be uncontrolled", | ||
@@ -5,0 +5,0 @@ "author": { |
'use strict'; | ||
var React = require('react/addons') | ||
var uncontrol = require('../src/uncontrollable') | ||
var Layer = require('react-layer') | ||
@@ -29,27 +28,13 @@ var TestUtils = React.addons.TestUtils | ||
onToggle: React.PropTypes.func, | ||
onRender: React.PropTypes.func, | ||
}, | ||
nonBatchingChange(val){ | ||
var target = this.refs.input.getDOMNode() | ||
if (val) target.value = val | ||
this.props.onChange(val) | ||
}, | ||
render() { | ||
if ( this.props.onRender ) | ||
this.props.onRender(this.props) | ||
return ( | ||
<div> | ||
<button onClick={this.props.onToggle}>toggle</button> | ||
{ this.props.open && | ||
{ this.props.open && | ||
<span className='open'>open!</span> | ||
} | ||
<input className='valueInput' | ||
ref='input' | ||
value={this.props.value} | ||
value={this.props.value} | ||
onChange={ e => this.props.onChange(e.value)}/> | ||
@@ -69,3 +54,3 @@ <input type='checkbox' | ||
, instance = render(<Control value={3}/>) | ||
warn.should.have.been.CalledOnce; | ||
@@ -85,3 +70,3 @@ | ||
, input = findAllTag(instance, 'input')[0] | ||
input.getDOMNode().value.should.equal('10') | ||
@@ -99,3 +84,3 @@ | ||
, input = findAllTag(instance, 'input')[1] | ||
input.getDOMNode().checked.should.equal(false) | ||
@@ -122,10 +107,10 @@ | ||
it('should track internally if not specified', () => { | ||
it('should track state if no specified', () => { | ||
var Control = uncontrol(Base, { value: 'onChange' }) | ||
, instance = render(<Control />) | ||
, input = findAllTag(instance, 'input')[0] | ||
trigger.change(input.getDOMNode(), { value: 42}) | ||
expect(instance.values).to.have.property('value') | ||
instance.state.should.have.property('value') | ||
.that.equals(42) | ||
@@ -139,3 +124,3 @@ }) | ||
, span = findClass(instance, 'open') | ||
input.getDOMNode().value.should.equal('10') | ||
@@ -145,145 +130,5 @@ | ||
expect(instance.values.value).to.equal(42) | ||
instance.state.value.should.equal(42) | ||
}) | ||
it('should not throw when not batching', () => { | ||
var spy = sinon.spy(); | ||
var Control = uncontrol(Base, { value: 'onChange', open: 'onToggle' }) | ||
, instance = render(<Control defaultValue={10} defaultOpen onChange={spy} />) | ||
, base = findType(instance, Base) | ||
, span = findClass(instance, 'open') | ||
expect(()=> | ||
base.nonBatchingChange(42)).not.to.throw() | ||
spy.should.have.been.calledOnce | ||
expect(instance.values.value).to.equal(42) | ||
}) | ||
// it('should update in the right order when controlled', () => { | ||
// var Control = uncontrol(Base, { value: 'onChange' }) | ||
// , spy = sinon.spy(); | ||
// var Parent = React.createClass({ | ||
// getInitialState(){ return { value: 5 } }, | ||
// render(){ | ||
// return ( | ||
// <Control | ||
// onRender={spy} | ||
// value={this.state.value} | ||
// onChange={value => this.setState({ value })} | ||
// /> | ||
// ) | ||
// } | ||
// }) | ||
// var instance = render(<Parent/>) | ||
// , input = findAllTag(instance, 'input')[0] | ||
// trigger.change(input.getDOMNode(), { value: 42 }) | ||
// spy.callCount.should.equal(2) | ||
// spy.firstCall.args[0].value.should.equal(5) | ||
// spy.secondCall.args[0].value.should.equal(42) | ||
// }) | ||
it('should update in the right order when uncontrolled', done => { | ||
var Control = uncontrol(Base, { value: 'onChange' }) | ||
, spy = sinon.spy(); | ||
var Parent = React.createClass({ | ||
getInitialState(){ return { value: 5 } }, | ||
render(){ | ||
return ( | ||
<Control | ||
ref='ctrl' | ||
onRender={spy} | ||
defaultValue={this.state.value} | ||
/> | ||
) | ||
} | ||
}) | ||
var instance = render(<Parent/>) | ||
, input = findAllTag(instance, 'input')[0] | ||
trigger.change(input.getDOMNode(), { value: 42 }) | ||
setTimeout(()=>{ | ||
spy.callCount.should.equal(2) | ||
spy.firstCall.args[0].value.should.equal(5) | ||
spy.secondCall.args[0].value.should.equal(42) | ||
spy.reset(); | ||
findType(instance.refs.ctrl, Base).nonBatchingChange(84); | ||
setTimeout(()=>{ | ||
spy.callCount.should.equal(1) | ||
spy.firstCall.args[0].value.should.equal(84) | ||
done() | ||
}) | ||
}) | ||
}) | ||
it('should update correctly in a Layer', done => { | ||
var Control = uncontrol(Base, { value: 'onChange' }) | ||
, spy = sinon.spy(); | ||
var Parent = React.createClass({ | ||
getInitialState(){ return { value: 5 } }, | ||
componentWillUnmount () { | ||
this._layer.destroy() | ||
this._layer = null | ||
}, | ||
componentDidUpdate(){this._renderOverlay()}, | ||
componentDidMount() {this._renderOverlay()}, | ||
_renderOverlay() { | ||
if (!this._layer) | ||
this._layer = new Layer(document.body, ()=> this._child) | ||
this.layerInstance = this._layer.render() | ||
}, | ||
render(){ | ||
this._child = ( | ||
<Control ref='ctrl' | ||
onRender={spy} | ||
value={this.state.value} | ||
onChange={value => this.setState({ value, called: true })} | ||
/> | ||
) | ||
return ( | ||
<div/> | ||
) | ||
} | ||
}) | ||
var instance = render(<Parent/>) | ||
, input = findAllTag(instance.layerInstance, 'input')[0] | ||
trigger.change(input.getDOMNode(), { value: 42 }) | ||
setTimeout(()=>{ | ||
spy.callCount.should.equal(2) | ||
spy.firstCall.args[0].value.should.equal(5) | ||
spy.secondCall.args[0].value.should.equal(42) | ||
spy.reset(); | ||
findType(instance.refs.ctrl, Base).nonBatchingChange(84); | ||
spy.callCount.should.equal(1) | ||
spy.firstCall.args[0].value.should.equal(84) | ||
done() | ||
}) | ||
}) | ||
describe('taps', () => { | ||
@@ -317,1 +162,2 @@ | ||
}) | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
191416
4648