UNPKG

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