UNPKG

@uifabric/utilities

Version:

Fluent UI React utilities for building components.

73 lines 4.6 kB
import { warn } from './warn'; import { isControlled as checkIsControlled } from '../controlled'; var warningsMap; if (process.env.NODE_ENV !== 'production') { warningsMap = { valueOnChange: {}, valueDefaultValue: {}, controlledToUncontrolled: {}, uncontrolledToControlled: {}, }; } /** Reset controlled usage warnings for testing purposes. */ export function resetControlledWarnings() { if (process.env.NODE_ENV !== 'production') { warningsMap.valueOnChange = {}; warningsMap.valueDefaultValue = {}; warningsMap.controlledToUncontrolled = {}; warningsMap.uncontrolledToControlled = {}; } } /** * Check for and warn on the following error conditions with a form component: * - A value prop is provided (indicated it's being used as controlled) without a change handler, * and the component is not read-only * - Both the value and defaultValue props are provided * - The component is attempting to switch between controlled and uncontrolled * * The messages mimic the warnings React gives for these error conditions on input elements. * The warning will only be displayed once per component ID. */ export function warnControlledUsage(params) { if (process.env.NODE_ENV !== 'production') { var componentId = params.componentId, componentName = params.componentName, defaultValueProp = params.defaultValueProp, props = params.props, oldProps = params.oldProps, onChangeProp = params.onChangeProp, readOnlyProp = params.readOnlyProp, valueProp = params.valueProp; // This warning logic closely follows what React does for native <input> elements. var oldIsControlled = oldProps ? checkIsControlled(oldProps, valueProp) : undefined; var newIsControlled = checkIsControlled(props, valueProp); if (newIsControlled) { // onChange (or readOnly) must be provided if value is provided var hasOnChange = !!props[onChangeProp]; var isReadOnly = !!(readOnlyProp && props[readOnlyProp]); if (!(hasOnChange || isReadOnly) && !warningsMap.valueOnChange[componentId]) { warningsMap.valueOnChange[componentId] = true; warn("Warning: You provided a '" + valueProp + "' prop to a " + componentName + " without an '" + onChangeProp + "' handler. " + ("This will render a read-only field. If the field should be mutable use '" + defaultValueProp + "'. ") + ("Otherwise, set '" + onChangeProp + "'" + (readOnlyProp ? " or '" + readOnlyProp + "'" : '') + ".")); } // value and defaultValue are mutually exclusive var defaultValue = props[defaultValueProp]; if (defaultValue !== undefined && defaultValue !== null && !warningsMap.valueDefaultValue[componentId]) { warningsMap.valueDefaultValue[componentId] = true; warn("Warning: You provided both '" + valueProp + "' and '" + defaultValueProp + "' to a " + componentName + ". " + ("Form fields must be either controlled or uncontrolled (specify either the '" + valueProp + "' prop, ") + ("or the '" + defaultValueProp + "' prop, but not both). Decide between using a controlled or uncontrolled ") + (componentName + " and remove one of these props. More info: https://fb.me/react-controlled-components")); } } // Warn if switching between uncontrolled and controlled. (One difference between this implementation // and React's <input> is that if oldIsControlled is indeterminate and newIsControlled true, we don't warn.) if (oldProps && newIsControlled !== oldIsControlled) { var oldType = oldIsControlled ? 'a controlled' : 'an uncontrolled'; var newType = oldIsControlled ? 'uncontrolled' : 'controlled'; var warnMap = oldIsControlled ? warningsMap.controlledToUncontrolled : warningsMap.uncontrolledToControlled; if (!warnMap[componentId]) { warnMap[componentId] = true; warn("Warning: A component is changing " + oldType + " " + componentName + " to be " + newType + ". " + (componentName + "s should not switch from controlled to uncontrolled (or vice versa). ") + "Decide between using controlled or uncontrolled for the lifetime of the component. " + "More info: https://fb.me/react-controlled-components"); } } } } //# sourceMappingURL=warnControlledUsage.js.map