UNPKG

5.12 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2013-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 */
8
9'use strict';
10
11var _prodInvariant = require('./reactProdInvariant');
12
13var ReactPropTypesSecret = require('./ReactPropTypesSecret');
14var propTypesFactory = require('prop-types/factory');
15
16var React = require('react/lib/React');
17var PropTypes = propTypesFactory(React.isValidElement);
18
19var invariant = require('fbjs/lib/invariant');
20var warning = require('fbjs/lib/warning');
21
22var hasReadOnlyValue = {
23 button: true,
24 checkbox: true,
25 image: true,
26 hidden: true,
27 radio: true,
28 reset: true,
29 submit: true
30};
31
32function _assertSingleLink(inputProps) {
33 !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : _prodInvariant('87') : void 0;
34}
35function _assertValueLink(inputProps) {
36 _assertSingleLink(inputProps);
37 !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '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.') : _prodInvariant('88') : void 0;
38}
39
40function _assertCheckedLink(inputProps) {
41 _assertSingleLink(inputProps);
42 !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don\'t want to use checkedLink') : _prodInvariant('89') : void 0;
43}
44
45var propTypes = {
46 value: function (props, propName, componentName) {
47 if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
48 return null;
49 }
50 return new Error('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`.');
51 },
52 checked: function (props, propName, componentName) {
53 if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
54 return null;
55 }
56 return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
57 },
58 onChange: PropTypes.func
59};
60
61var loggedTypeFailures = {};
62function getDeclarationErrorAddendum(owner) {
63 if (owner) {
64 var name = owner.getName();
65 if (name) {
66 return ' Check the render method of `' + name + '`.';
67 }
68 }
69 return '';
70}
71
72/**
73 * Provide a linked `value` attribute for controlled forms. You should not use
74 * this outside of the ReactDOM controlled form components.
75 */
76var LinkedValueUtils = {
77 checkPropTypes: function (tagName, props, owner) {
78 for (var propName in propTypes) {
79 if (propTypes.hasOwnProperty(propName)) {
80 var error = propTypes[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret);
81 }
82 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
83 // Only monitor this failure once because there tends to be a lot of the
84 // same error.
85 loggedTypeFailures[error.message] = true;
86
87 var addendum = getDeclarationErrorAddendum(owner);
88 process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : void 0;
89 }
90 }
91 },
92
93 /**
94 * @param {object} inputProps Props for form component
95 * @return {*} current value of the input either from value prop or link.
96 */
97 getValue: function (inputProps) {
98 if (inputProps.valueLink) {
99 _assertValueLink(inputProps);
100 return inputProps.valueLink.value;
101 }
102 return inputProps.value;
103 },
104
105 /**
106 * @param {object} inputProps Props for form component
107 * @return {*} current checked status of the input either from checked prop
108 * or link.
109 */
110 getChecked: function (inputProps) {
111 if (inputProps.checkedLink) {
112 _assertCheckedLink(inputProps);
113 return inputProps.checkedLink.value;
114 }
115 return inputProps.checked;
116 },
117
118 /**
119 * @param {object} inputProps Props for form component
120 * @param {SyntheticEvent} event change event to handle
121 */
122 executeOnChange: function (inputProps, event) {
123 if (inputProps.valueLink) {
124 _assertValueLink(inputProps);
125 return inputProps.valueLink.requestChange(event.target.value);
126 } else if (inputProps.checkedLink) {
127 _assertCheckedLink(inputProps);
128 return inputProps.checkedLink.requestChange(event.target.checked);
129 } else if (inputProps.onChange) {
130 return inputProps.onChange.call(undefined, event);
131 }
132 }
133};
134
135module.exports = LinkedValueUtils;
\No newline at end of file