Skip to content

Commit

Permalink
Change LinkedValueMixin to a util class
Browse files Browse the repository at this point in the history
This makes it clear that .getValue() is not a public API.
  • Loading branch information
sophiebits committed Jan 22, 2014
1 parent e3248ef commit 95a8059
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 114 deletions.
2 changes: 1 addition & 1 deletion src/addons/link/ReactLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* });
*
* We have provided some sugary mixins to make the creation and
* consumption of ReactLink easier; see LinkedValueMixin and LinkedStateMixin.
* consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin.
*/

/**
Expand Down
93 changes: 0 additions & 93 deletions src/dom/components/LinkedValueMixin.js

This file was deleted.

97 changes: 97 additions & 0 deletions src/dom/components/LinkedValueUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule LinkedValueUtils
* @typechecks static-only
*/

"use strict";

var invariant = require('invariant');

var hasReadOnlyValue = {
'checkbox': true,
'hidden': true,
'radio': true
};

function _assertLink(input) {
invariant(
input.props.value == null && input.props.onChange == null,
'Cannot provide a valueLink and a value or onChange event. If you want ' +
'to use value or onChange, you probably don\'t want to use valueLink.'
);
}

/**
* @param {SyntheticEvent} e change event to handle
*/
function _handleLinkedValueChange(e) {
/*jshint validthis:true */
this.props.valueLink.requestChange(e.target.value);
}

/**
* Provide a linked `value` attribute for controlled forms. You should not use
* this outside of the ReactDOM controlled form components.
*/
var LinkedValueUtils = {
Mixin: {
propTypes: {
value: function(props, propName, componentName) {
if (__DEV__) {
if (props[propName] &&
!hasReadOnlyValue[props.type] &&
!props.onChange &&
!props.readOnly &&
!props.disabled) {
console.warn(
'You provided a `value` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultValue`. Otherwise, ' +
'set either `onChange` or `readOnly`.'
);
}
}
}
}
},

/**
* @param {ReactComponent} input Form component
* @return {*} current value of the input either from value prop or link.
*/
getValue: function(input) {
if (input.props.valueLink) {
_assertLink(input);
return input.props.valueLink.value;
}
return input.props.value;
},

/**
* @param {ReactComponent} input Form component
* @return {function} change callback either from onChange prop or link.
*/
getOnChange: function(input) {
if (input.props.valueLink) {
_assertLink(input);
return _handleLinkedValueChange;
}
return input.props.onChange;
}
};

module.exports = LinkedValueUtils;
14 changes: 7 additions & 7 deletions src/dom/components/ReactDOMInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

"use strict";

var DOMPropertyOperations = require('DOMPropertyOperations');
var LinkedValueMixin = require('LinkedValueMixin');
var AutoFocusMixin = require('AutoFocusMixin');
var DOMPropertyOperations = require('DOMPropertyOperations');
var LinkedValueUtils = require('LinkedValueUtils');
var ReactCompositeComponent = require('ReactCompositeComponent');
var ReactDOM = require('ReactDOM');
var ReactMount = require('ReactMount');
Expand Down Expand Up @@ -52,7 +52,7 @@ var instancesByReactID = {};
var ReactDOMInput = ReactCompositeComponent.createClass({
displayName: 'ReactDOMInput',

mixins: [LinkedValueMixin, AutoFocusMixin],
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],

getInitialState: function() {
var defaultValue = this.props.defaultValue;
Expand All @@ -76,7 +76,7 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
props.checked =
this.props.checked != null ? this.props.checked : this.state.checked;

var value = this.getValue();
var value = LinkedValueUtils.getValue(this);
props.value = value != null ? value : this.state.value;

props.onChange = this._handleChange;
Expand Down Expand Up @@ -105,7 +105,7 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
);
}

var value = this.getValue();
var value = LinkedValueUtils.getValue(this);
if (value != null) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
Expand All @@ -115,10 +115,10 @@ var ReactDOMInput = ReactCompositeComponent.createClass({

_handleChange: function(event) {
var returnValue;
var onChange = this.getOnChange();
var onChange = LinkedValueUtils.getOnChange(this);
if (onChange) {
this._isChanging = true;
returnValue = onChange(event);
returnValue = onChange.call(this, event);
this._isChanging = false;
}
this.setState({
Expand Down
10 changes: 5 additions & 5 deletions src/dom/components/ReactDOMSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

"use strict";

var LinkedValueMixin = require('LinkedValueMixin');
var AutoFocusMixin = require('AutoFocusMixin');
var LinkedValueUtils = require('LinkedValueUtils');
var ReactCompositeComponent = require('ReactCompositeComponent');
var ReactDOM = require('ReactDOM');

Expand Down Expand Up @@ -61,7 +61,7 @@ function selectValueType(props, propName, componentName) {
function updateOptions() {
/*jshint validthis:true */
var multiple = this.props.multiple;
var propValue = this.getValue();
var propValue = LinkedValueUtils.getValue(this);
var value = propValue != null ? propValue : this.state.value;
var options = this.getDOMNode().options;
var selectedValue, i, l;
Expand Down Expand Up @@ -102,7 +102,7 @@ function updateOptions() {
var ReactDOMSelect = ReactCompositeComponent.createClass({
displayName: 'ReactDOMSelect',

mixins: [LinkedValueMixin, AutoFocusMixin],
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],

propTypes: {
defaultValue: selectValueType,
Expand Down Expand Up @@ -142,10 +142,10 @@ var ReactDOMSelect = ReactCompositeComponent.createClass({

_handleChange: function(event) {
var returnValue;
var onChange = this.getOnChange();
var onChange = LinkedValueUtils.getOnChange(this);
if (onChange) {
this._isChanging = true;
returnValue = onChange(event);
returnValue = onChange.call(this, event);
this._isChanging = false;
}

Expand Down
16 changes: 8 additions & 8 deletions src/dom/components/ReactDOMTextarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

"use strict";

var DOMPropertyOperations = require('DOMPropertyOperations');
var LinkedValueMixin = require('LinkedValueMixin');
var AutoFocusMixin = require('AutoFocusMixin');
var DOMPropertyOperations = require('DOMPropertyOperations');
var LinkedValueUtils = require('LinkedValueUtils');
var ReactCompositeComponent = require('ReactCompositeComponent');
var ReactDOM = require('ReactDOM');

Expand Down Expand Up @@ -48,7 +48,7 @@ var textarea = ReactDOM.textarea;
var ReactDOMTextarea = ReactCompositeComponent.createClass({
displayName: 'ReactDOMTextarea',

mixins: [LinkedValueMixin, AutoFocusMixin],
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],

getInitialState: function() {
var defaultValue = this.props.defaultValue;
Expand Down Expand Up @@ -78,7 +78,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
if (defaultValue == null) {
defaultValue = '';
}
var value = this.getValue();
var value = LinkedValueUtils.getValue(this);
return {
// We save the initial value so that `ReactDOMComponent` doesn't update
// `textContent` (unnecessary since we update value).
Expand All @@ -97,7 +97,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
render: function() {
// Clone `this.props` so we don't mutate the input.
var props = merge(this.props);
var value = this.getValue();
var value = LinkedValueUtils.getValue(this);

invariant(
props.dangerouslySetInnerHTML == null,
Expand All @@ -114,7 +114,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
},

componentDidUpdate: function(prevProps, prevState, prevContext) {
var value = this.getValue();
var value = LinkedValueUtils.getValue(this);
if (value != null) {
var rootNode = this.getDOMNode();
// Cast `value` to a string to ensure the value is set correctly. While
Expand All @@ -125,10 +125,10 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({

_handleChange: function(event) {
var returnValue;
var onChange = this.getOnChange();
var onChange = LinkedValueUtils.getOnChange(this);
if (onChange) {
this._isChanging = true;
returnValue = onChange(event);
returnValue = onChange.call(this, event);
this._isChanging = false;
}
this.setState({value: event.target.value});
Expand Down

0 comments on commit 95a8059

Please sign in to comment.