pax_global_header00006660000000000000000000000064136121540630014513gustar00rootroot0000000000000052 comment=1b5fb0b06856f196544ff2dda54c9a15e451522e hoist-non-react-statics-3.3.2/000077500000000000000000000000001361215406300162025ustar00rootroot00000000000000hoist-non-react-statics-3.3.2/.babelrc000066400000000000000000000000401361215406300175670ustar00rootroot00000000000000{ "presets": ["@babel/env"] } hoist-non-react-statics-3.3.2/.coveralls.yml000066400000000000000000000000301361215406300207660ustar00rootroot00000000000000service_name: travis-ci hoist-non-react-statics-3.3.2/.eslintrc000066400000000000000000000004621361215406300200300ustar00rootroot00000000000000--- parserOptions: sourceType: 'module' env: node: true rules: strict: 0 indent: [2, 4] quotes: [2, 'single'] no-unused-vars: 0 // see https://github.com/babel/babel-eslint/issues/21 no-underscore-dangle: 0 yoda: 0 no-alert: 0 new-cap: 0 no-empty-class: 0 hoist-non-react-statics-3.3.2/.gitignore000066400000000000000000000000541361215406300201710ustar00rootroot00000000000000dist .nyc_output node_modules npm-debug.log hoist-non-react-statics-3.3.2/.travis.yml000066400000000000000000000001541361215406300203130ustar00rootroot00000000000000sudo: false language: node_js node_js: - "12" - "10" - "8" - "6" after_success: - "yarn coverage" hoist-non-react-statics-3.3.2/CHANGELOG.md000066400000000000000000000027441361215406300200220ustar00rootroot00000000000000# 3.3.2 (January 22, 2020) - Fix `React.memo` for v16.12+ (#93) # 3.3.1 (November 14, 2019) - Fix for UMD bundle (#85) - Tooling changes (#83, #84, #87) # 3.3.0 (January 23, 2019) - Prevent hoisting of React.memo statics (#73) # 3.2.1 (December 3, 2018) - Fixed `defaultProps`, `displayName` and `propTypes` being hoisted from `React.forwardRef` to `React.forwardRef`. ([#71]) # 3.2.0 (November 26, 2018) - Added support for `getDerivedStateFromError`. ([#68]) - Added support for React versions less than 0.14. ([#69]) # 3.1.0 (October 30, 2018) - Added support for `contextType`. ([#62]) - Reduced bundle size. ([e89c7a6]) - Removed TypeScript definitions. ([#61]) # 3.0.1 (July 28, 2018) - Fixed prop-types warnings. ([e0846fe]) # 3.0.0 (July 27, 2018) - Dropped support for React versions less than 0.14. ([#55]) - Added support for `React.forwardRef` components. ([#55]) [#55]: https://github.com/mridgway/hoist-non-react-statics/pull/55 [#61]: https://github.com/mridgway/hoist-non-react-statics/pull/61 [#62]: https://github.com/mridgway/hoist-non-react-statics/pull/62 [#68]: https://github.com/mridgway/hoist-non-react-statics/pull/68 [#69]: https://github.com/mridgway/hoist-non-react-statics/pull/69 [#71]: https://github.com/mridgway/hoist-non-react-statics/pull/71 [e0846fe]: https://github.com/mridgway/hoist-non-react-statics/commit/e0846feefbad8b34d300de9966ffd607aacb81a3 [e89c7a6]: https://github.com/mridgway/hoist-non-react-statics/commit/e89c7a6168edc19eeadb2d149e600b888e8b0446 hoist-non-react-statics-3.3.2/LICENSE.md000066400000000000000000000031761361215406300176150ustar00rootroot00000000000000Software License Agreement (BSD License) ======================================== Copyright (c) 2015, Yahoo! Inc. All rights reserved. ---------------------------------------------------- Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Yahoo! Inc. nor the names of YUI's contributors may be used to endorse or promote products derived from this software without specific prior written permission of Yahoo! Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hoist-non-react-statics-3.3.2/README.md000066400000000000000000000046441361215406300174710ustar00rootroot00000000000000# hoist-non-react-statics [![NPM version](https://badge.fury.io/js/hoist-non-react-statics.svg)](http://badge.fury.io/js/hoist-non-react-statics) [![Build Status](https://img.shields.io/travis/mridgway/hoist-non-react-statics.svg)](https://travis-ci.org/mridgway/hoist-non-react-statics) [![Coverage Status](https://img.shields.io/coveralls/mridgway/hoist-non-react-statics.svg)](https://coveralls.io/r/mridgway/hoist-non-react-statics?branch=master) [![Dependency Status](https://img.shields.io/david/mridgway/hoist-non-react-statics.svg)](https://david-dm.org/mridgway/hoist-non-react-statics) [![devDependency Status](https://img.shields.io/david/dev/mridgway/hoist-non-react-statics.svg)](https://david-dm.org/mridgway/hoist-non-react-statics#info=devDependencies) Copies non-react specific statics from a child component to a parent component. Similar to `Object.assign`, but with React static keywords blacklisted from being overridden. ```bash $ npm install --save hoist-non-react-statics ``` ## Usage ```js import hoistNonReactStatics from 'hoist-non-react-statics'; hoistNonReactStatics(targetComponent, sourceComponent); ``` If you have specific statics that you don't want to be hoisted, you can also pass a third parameter to exclude them: ```js hoistNonReactStatics(targetComponent, sourceComponent, { myStatic: true, myOtherStatic: true }); ``` ## What does this module do? See this [explanation](https://facebook.github.io/react/docs/higher-order-components.html#static-methods-must-be-copied-over) from the React docs. ## Compatible React Versions Please use latest 3.x. Versions prior to 3.x will not support ForwardRefs. | hoist-non-react-statics Version | Compatible React Version | |--------------------------|-------------------------------| | 3.x | 0.13-16.x With ForwardRef Support | | 2.x | 0.13-16.x Without ForwardRef Support | | 1.x | 0.13-16.2 | ## Browser Support This package uses `Object.defineProperty` which has a broken implementation in IE8. In order to use this package in IE8, you will need a polyfill that fixes this method. ## License This software is free to use under the Yahoo Inc. BSD license. See the [LICENSE file][] for license text and copyright information. [LICENSE file]: https://github.com/mridgway/hoist-non-react-statics/blob/master/LICENSE.md Third-party open source code used are listed in our [package.json file]( https://github.com/mridgway/hoist-non-react-statics/blob/master/package.json). hoist-non-react-statics-3.3.2/package.json000066400000000000000000000030161361215406300204700ustar00rootroot00000000000000{ "name": "hoist-non-react-statics", "version": "3.3.2", "description": "Copies non-react specific statics from a child component to a parent component", "main": "dist/hoist-non-react-statics.cjs.js", "repository": { "type": "git", "url": "git://github.com/mridgway/hoist-non-react-statics.git" }, "files": [ "src", "dist", "index.d.ts" ], "scripts": { "lint": "eslint src", "build": "rimraf dist && rollup -c", "test": "nyc mocha tests/unit/ --recursive --reporter spec --require=@babel/register", "coverage": "nyc report --reporter=text-lcov | coveralls", "prepublish": "npm test" }, "author": "Michael Ridgway ", "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" }, "devDependencies": { "@babel/core": "^7.5.0", "@babel/plugin-proposal-class-properties": "^7.5.0", "@babel/preset-env": "^7.5.0", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.4.4", "chai": "^4.2.0", "coveralls": "^2.11.1", "create-react-class": "^15.5.3", "eslint": "^4.13.1", "mocha": "^6.1.4", "nyc": "^14.1.1", "pre-commit": "^1.0.7", "prop-types": "^15.6.2", "react": "^16.7.0", "rimraf": "^2.6.2", "rollup": "^1.16.6", "rollup-plugin-babel": "^4.3.3", "rollup-plugin-commonjs": "^10.0.1", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-terser": "^5.1.1" }, "publishConfig": { "registry": "https://registry.npmjs.org/" }, "keywords": [ "react" ] } hoist-non-react-statics-3.3.2/rollup.config.js000066400000000000000000000025721361215406300213270ustar00rootroot00000000000000import path from 'path'; import nodeResolve from 'rollup-plugin-node-resolve'; import babel from 'rollup-plugin-babel' import commonjs from 'rollup-plugin-commonjs'; import { terser } from 'rollup-plugin-terser' import pkg from './package.json' import * as ReactIs from 'react-is'; const camelCase = string => { const [first, ...rest] = string.split('-').map(str => str.toLowerCase()); return first + rest.map(str => str[0].toUpperCase() + str.slice(1)).join('') }; const input = 'src/index.js'; const name = camelCase(pkg.name); const external = id => !id.startsWith('.') && !path.isAbsolute(id); const commonjsOptions = { namedExports: { 'react-is': Object.keys(ReactIs) } } export default [ { input, output: { file: pkg.main, format: 'cjs' }, external, plugins: [ babel({ exclude: /node_modules/ }), ] }, { input, output: { file: `dist/${pkg.name}.js`, format: 'umd', name }, plugins: [ nodeResolve(), babel({ exclude: /node_modules/ }), commonjs(commonjsOptions) ] }, { input, output: { file: `dist/${pkg.name}.min.js`, format: 'umd', name }, plugins: [ nodeResolve(), babel({ exclude: /node_modules/ }), commonjs(commonjsOptions), terser({ compress: { pure_getters: true, unsafe: true, unsafe_comps: true, }, }) ] } ] hoist-non-react-statics-3.3.2/src/000077500000000000000000000000001361215406300167715ustar00rootroot00000000000000hoist-non-react-statics-3.3.2/src/index.js000066400000000000000000000056431361215406300204460ustar00rootroot00000000000000/** * Copyright 2015, Yahoo! Inc. * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ import { ForwardRef, Memo, isMemo } from 'react-is'; const REACT_STATICS = { childContextTypes: true, contextType: true, contextTypes: true, defaultProps: true, displayName: true, getDefaultProps: true, getDerivedStateFromError: true, getDerivedStateFromProps: true, mixins: true, propTypes: true, type: true }; const KNOWN_STATICS = { name: true, length: true, prototype: true, caller: true, callee: true, arguments: true, arity: true }; const FORWARD_REF_STATICS = { '$$typeof': true, render: true, defaultProps: true, displayName: true, propTypes: true }; const MEMO_STATICS = { '$$typeof': true, compare: true, defaultProps: true, displayName: true, propTypes: true, type: true, } const TYPE_STATICS = {}; TYPE_STATICS[ForwardRef] = FORWARD_REF_STATICS; TYPE_STATICS[Memo] = MEMO_STATICS; function getStatics(component) { // React v16.11 and below if (isMemo(component)) { return MEMO_STATICS; } // React v16.12 and above return TYPE_STATICS[component['$$typeof']] || REACT_STATICS; } const defineProperty = Object.defineProperty; const getOwnPropertyNames = Object.getOwnPropertyNames; const getOwnPropertySymbols = Object.getOwnPropertySymbols; const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; const getPrototypeOf = Object.getPrototypeOf; const objectPrototype = Object.prototype; export default function hoistNonReactStatics(targetComponent, sourceComponent, blacklist) { if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components if (objectPrototype) { const inheritedComponent = getPrototypeOf(sourceComponent); if (inheritedComponent && inheritedComponent !== objectPrototype) { hoistNonReactStatics(targetComponent, inheritedComponent, blacklist); } } let keys = getOwnPropertyNames(sourceComponent); if (getOwnPropertySymbols) { keys = keys.concat(getOwnPropertySymbols(sourceComponent)); } const targetStatics = getStatics(targetComponent); const sourceStatics = getStatics(sourceComponent); for (let i = 0; i < keys.length; ++i) { const key = keys[i]; if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key]) ) { const descriptor = getOwnPropertyDescriptor(sourceComponent, key); try { // Avoid failures from read-only properties defineProperty(targetComponent, key, descriptor); } catch (e) {} } } } return targetComponent; }; hoist-non-react-statics-3.3.2/tests/000077500000000000000000000000001361215406300173445ustar00rootroot00000000000000hoist-non-react-statics-3.3.2/tests/.babelrc000066400000000000000000000001541361215406300207370ustar00rootroot00000000000000{ "presets": ["@babel/env", "@babel/react"], "plugins": [ "@babel/proposal-class-properties", ] } hoist-non-react-statics-3.3.2/tests/unit/000077500000000000000000000000001361215406300203235ustar00rootroot00000000000000hoist-non-react-statics-3.3.2/tests/unit/index.js000066400000000000000000000212201361215406300217650ustar00rootroot00000000000000/*globals describe,it,beforeEach */ import { expect } from 'chai'; import React from 'react'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; import hoistNonReactStatics from '../../src'; describe('hoist-non-react-statics', function () { it('should hoist non react statics', function () { var Component = createReactClass({ displayName: 'Foo', statics: { foo: 'bar' }, propTypes: { on: PropTypes.bool.isRequired }, render: function () { return null; } }); var Wrapper = createReactClass({ displayName: 'Bar', render: function () { return ; } }); hoistNonReactStatics(Wrapper, Component); expect(Wrapper.displayName).to.equal('Bar'); expect(Wrapper.foo).to.equal('bar'); }); it('should not hoist custom statics', function () { var Component = createReactClass({ displayName: 'Foo', statics: { foo: 'bar' }, render: function () { return null; } }); var Wrapper = createReactClass({ displayName: 'Bar', render: function () { return ; } }); hoistNonReactStatics(Wrapper, Component, {foo: true}); expect(Wrapper.foo).to.be.undefined; }); it('should not hoist statics from strings', function() { var Component = 'input'; var Wrapper = createReactClass({ render: function() { return ; } }); hoistNonReactStatics(Wrapper, Component); expect(Wrapper[0]).to.equal(undefined); // if hoisting it would equal 'i' }); it('should hoist symbols', function() { var foo = Symbol('foo'); var Component = createReactClass({ render: function() { return null; } }); // Manually set static property using Symbol // since createReactClass doesn't handle symbols passed to static Component[foo] = 'bar'; var Wrapper = createReactClass({ render: function() { return ; } }); hoistNonReactStatics(Wrapper, Component); expect(Wrapper[foo]).to.equal('bar'); }); it('should hoist class statics', function() { class Component extends React.Component { static foo = 'bar'; static test() { } } var Wrapper = createReactClass({ render: function() { return ; } }); hoistNonReactStatics(Wrapper, Component); expect(Wrapper.foo).to.equal(Component.foo); expect(Wrapper.test).to.equal(Component.test); }); it('should hoist properties with accessor methods', function() { var Component = createReactClass({ render: function() { return null; } }); // Manually set static complex property // since createReactClass doesn't handle properties passed to static var counter = 0; Object.defineProperty(Component, 'foo', { enumerable: true, configurable: true, get: function() { return counter++; } }); var Wrapper = createReactClass({ render: function() { return ; } }); hoistNonReactStatics(Wrapper, Component); // Each access of Wrapper.foo should increment counter. expect(Wrapper.foo).to.equal(0); expect(Wrapper.foo).to.equal(1); expect(Wrapper.foo).to.equal(2); }); it('should inherit static class properties', () => { class A extends React.Component { static test3 = 'A'; static test4 = 'D'; test5 = 'foo'; } class B extends A { static test2 = 'B'; static test4 = 'DD'; } class C { static test1 = 'C'; } const D = hoistNonReactStatics(C, B); expect(D.test1).to.equal('C'); expect(D.test2).to.equal('B'); expect(D.test3).to.equal('A'); expect(D.test4).to.equal('DD'); expect(D.test5).to.equal(undefined); }); it('should inherit static class methods', () => { class A extends React.Component { static test3 = 'A'; static test4 = 'D'; static getMeta() { return {}; }; test5 = 'foo'; } class B extends A { static test2 = 'B'; static test4 = 'DD'; static getMeta2() { return {}; }; } class C { static test1 = 'C'; } const D = hoistNonReactStatics(C, B); expect(D.test1).to.equal('C'); expect(D.test2).to.equal('B'); expect(D.test3).to.equal('A'); expect(D.test4).to.equal('DD'); expect(D.test5).to.equal(undefined); expect(D.getMeta).to.be.a('function'); expect(D.getMeta2).to.be.a('function'); expect(D.getMeta()).to.deep.equal({}); }); it('should not inherit ForwardRef render', () => { class FancyButton extends React.Component { } function logProps(Component) { class LogProps extends React.Component { static foo = 'foo'; static render = 'bar'; render() { const {forwardedRef, ...rest} = this.props; return ; } } const ForwardedComponent = React.forwardRef((props, ref) => { return ; }); hoistNonReactStatics(ForwardedComponent, LogProps); return ForwardedComponent; } const WrappedFancyButton = logProps(FancyButton); expect(WrappedFancyButton.foo).to.equal('foo'); expect(WrappedFancyButton.render).to.not.equal('bar'); }); it('should not mix defaultProps, displayName and propTypes in forwardRef', () => { const Component = React.forwardRef((props, ref) => null); Component.defaultProps = { message: 'forwarded' } Component.displayName = 'BaseComponent'; Component.propTypes = { id: () => new Error() } Component.foo = 'foo'; const EnhancedComponent = React.forwardRef(({id, ...props}, ref) => ); EnhancedComponent.defaultProps = { id: 'stop-me' } EnhancedComponent.displayName = `Enhanced(${Component.displayName})`; EnhancedComponent.propTypes = { innerRef: () => 'deprecated' } hoistNonReactStatics(EnhancedComponent, Component); expect(EnhancedComponent.foo).to.equal('foo'); expect(EnhancedComponent.displayName).to.equal('Enhanced(BaseComponent)'); expect(EnhancedComponent.defaultProps.id).to.equal('stop-me'); expect(EnhancedComponent.propTypes.innerRef()).to.equal('deprecated'); }) it('should not inherit Memo', () => { const FancyButton = React.memo(props =>