UNPKG

react-addons

Version:

Simple packaging of react addons to avoid fiddly 'react/addons' npm module.

148 lines (130 loc) 4.15 kB
/** * Copyright 2013-2014 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 ReactPropTransferer */ "use strict"; var emptyFunction = require("./emptyFunction"); var invariant = require("./invariant"); var joinClasses = require("./joinClasses"); var merge = require("./merge"); /** * Creates a transfer strategy that will merge prop values using the supplied * `mergeStrategy`. If a prop was previously unset, this just sets it. * * @param {function} mergeStrategy * @return {function} */ function createTransferStrategy(mergeStrategy) { return function(props, key, value) { if (!props.hasOwnProperty(key)) { props[key] = value; } else { props[key] = mergeStrategy(props[key], value); } }; } /** * Transfer strategies dictate how props are transferred by `transferPropsTo`. * NOTE: if you add any more exceptions to this list you should be sure to * update `cloneWithProps()` accordingly. */ var TransferStrategies = { /** * Never transfer `children`. */ children: emptyFunction, /** * Transfer the `className` prop by merging them. */ className: createTransferStrategy(joinClasses), /** * Never transfer the `key` prop. */ key: emptyFunction, /** * Never transfer the `ref` prop. */ ref: emptyFunction, /** * Transfer the `style` prop (which is an object) by merging them. */ style: createTransferStrategy(merge) }; /** * ReactPropTransferer are capable of transferring props to another component * using a `transferPropsTo` method. * * @class ReactPropTransferer */ var ReactPropTransferer = { TransferStrategies: TransferStrategies, /** * Merge two props objects using TransferStrategies. * * @param {object} oldProps original props (they take precedence) * @param {object} newProps new props to merge in * @return {object} a new object containing both sets of props merged. */ mergeProps: function(oldProps, newProps) { var props = merge(oldProps); for (var thisKey in newProps) { if (!newProps.hasOwnProperty(thisKey)) { continue; } var transferStrategy = TransferStrategies[thisKey]; if (transferStrategy) { transferStrategy(props, thisKey, newProps[thisKey]); } else if (!props.hasOwnProperty(thisKey)) { props[thisKey] = newProps[thisKey]; } } return props; }, /** * @lends {ReactPropTransferer.prototype} */ Mixin: { /** * Transfer props from this component to a target component. * * Props that do not have an explicit transfer strategy will be transferred * only if the target component does not already have the prop set. * * This is usually used to pass down props to a returned root component. * * @param {ReactComponent} component Component receiving the properties. * @return {ReactComponent} The supplied `component`. * @final * @protected */ transferPropsTo: function(component) { ("production" !== process.env.NODE_ENV ? invariant( component._owner === this, '%s: You can\'t call transferPropsTo() on a component that you ' + 'don\'t own, %s. This usually means you are calling ' + 'transferPropsTo() on a component passed in as props or children.', this.constructor.displayName, component.constructor.displayName ) : invariant(component._owner === this)); component.props = ReactPropTransferer.mergeProps( component.props, this.props ); return component; } } }; module.exports = ReactPropTransferer;