diff --git a/.size-limit.js b/.size-limit.js
index f31cff6a63df7e..625821edfa1f5e 100644
--- a/.size-limit.js
+++ b/.size-limit.js
@@ -41,7 +41,7 @@ module.exports = [
name: 'The main docs bundle',
webpack: false,
path: main.path,
- limit: '176 KB',
+ limit: '176.1 KB',
},
{
name: 'The docs home page',
diff --git a/packages/material-ui-styles/package.json b/packages/material-ui-styles/package.json
index 0e13aefc7b7667..bbc3362c43b2bb 100644
--- a/packages/material-ui-styles/package.json
+++ b/packages/material-ui-styles/package.json
@@ -40,7 +40,6 @@
"@material-ui/utils": "^3.0.0-alpha.0",
"classnames": "^2.2.5",
"deepmerge": "^3.0.0",
- "hoist-non-react-statics": "^3.2.1",
"jss": "^9.3.3",
"jss-camel-case": "^6.0.0",
"jss-default-unit": "^8.0.2",
diff --git a/packages/material-ui-styles/src/hoistInternalStatics.js b/packages/material-ui-styles/src/hoistInternalStatics.js
new file mode 100644
index 00000000000000..9015336b5e8057
--- /dev/null
+++ b/packages/material-ui-styles/src/hoistInternalStatics.js
@@ -0,0 +1,18 @@
+/**
+ * Copies internal immediate statics from material-ui from source to target
+ */
+export default function hoistStatics(target, source) {
+ const internals = ['muiName'];
+
+ for (let i = 0; i < internals.length; i += 1) {
+ const key = internals[i];
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
+ try {
+ Object.defineProperty(target, key, descriptor);
+ } catch (e) {
+ // Avoid failures from read-only properties and undefined descriptors
+ }
+ }
+
+ return target;
+}
diff --git a/packages/material-ui-styles/src/withStyles.js b/packages/material-ui-styles/src/withStyles.js
index c9b7a51ed2dbd6..cff81d1d9be324 100644
--- a/packages/material-ui-styles/src/withStyles.js
+++ b/packages/material-ui-styles/src/withStyles.js
@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
import warning from 'warning';
import getDynamicStyles from 'jss/lib/utils/getDynamicStyles';
import { getDisplayName } from '@material-ui/utils';
-import hoistNonReactStatics from 'hoist-non-react-statics';
import { increment } from './indexCounter';
import mergeClasses from './mergeClasses';
import multiKeyStore from './multiKeyStore';
import getStylesCreator from './getStylesCreator';
import getThemeProps from './getThemeProps';
+import hoistStatics from './hoistInternalStatics';
import { StylesContext } from './StylesProvider';
import { ThemeContext } from './ThemeProvider';
@@ -333,7 +333,7 @@ const withStyles = (stylesOrCreator, options = {}) => Component => {
WithStyles.displayName = `WithStyles(${getDisplayName(Component)})`;
}
- hoistNonReactStatics(WithStyles, Component);
+ hoistStatics(WithStyles, Component);
if (process.env.NODE_ENV !== 'production') {
// Exposed for test purposes.
diff --git a/packages/material-ui-styles/src/withStyles.test.js b/packages/material-ui-styles/src/withStyles.test.js
new file mode 100644
index 00000000000000..73d4e7e1302672
--- /dev/null
+++ b/packages/material-ui-styles/src/withStyles.test.js
@@ -0,0 +1,23 @@
+import { assert } from 'chai';
+import React from 'react';
+import { Input } from '@material-ui/core';
+import { isMuiElement } from '@material-ui/core/utils/reactHelpers';
+import withStyles from './withStyles';
+
+describe('withStyles', () => {
+ it('does not hoist statics', () => {
+ const Test = () => null;
+ Test.someStatic = 'will not get hoisted';
+ const TestWithStyles = withStyles({})(Test);
+ assert.strictEqual(TestWithStyles.someStatic, undefined);
+ });
+
+ it('hoists mui internals', () => {
+ assert.strictEqual(isMuiElement(, ['Input']), true);
+
+ // the imported Input is decorated with @material-ui/core/styles
+ const StyledInput = withStyles({})(Input);
+
+ assert.strictEqual(isMuiElement(, ['Input']), true);
+ });
+});
diff --git a/packages/material-ui-styles/src/withTheme.js b/packages/material-ui-styles/src/withTheme.js
index da2fc0695006ac..820630f3e38113 100644
--- a/packages/material-ui-styles/src/withTheme.js
+++ b/packages/material-ui-styles/src/withTheme.js
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import hoistNonReactStatics from 'hoist-non-react-statics';
import { getDisplayName } from '@material-ui/utils';
+import hoistStatics from './hoistInternalStatics';
import { ThemeContext } from './ThemeProvider';
// Provide the theme object as a property to the input component.
@@ -26,7 +26,7 @@ const withTheme = () => Component => {
WithTheme.displayName = `WithTheme(${getDisplayName(Component)})`;
}
- hoistNonReactStatics(WithTheme, Component);
+ hoistStatics(WithTheme, Component);
return WithTheme;
};
diff --git a/packages/material-ui-styles/src/withTheme.test.js b/packages/material-ui-styles/src/withTheme.test.js
index 4eaf0f45366fe9..5da506e72829c9 100644
--- a/packages/material-ui-styles/src/withTheme.test.js
+++ b/packages/material-ui-styles/src/withTheme.test.js
@@ -1,6 +1,8 @@
import React from 'react';
import { assert } from 'chai';
import { createMount } from '@material-ui/core/test-utils';
+import { Input } from '@material-ui/core';
+import { isMuiElement } from '@material-ui/core/utils/reactHelpers';
import PropTypes from 'prop-types';
import withTheme from './withTheme';
import ThemeProvider from './ThemeProvider';
@@ -34,4 +36,19 @@ describe('withTheme', () => {
);
assert.strictEqual(wrapper.text(), 'foo');
});
+
+ it('does not hoist statics', () => {
+ const Test = () => null;
+ Test.someStatic = 'will not get hoisted';
+ const TestWithTheme = withTheme()(Test);
+ assert.strictEqual(TestWithTheme.someStatic, undefined);
+ });
+
+ it('hoists mui internals', () => {
+ assert.strictEqual(isMuiElement(, ['Input']), true);
+
+ const ThemedInput = withTheme()(Input);
+
+ assert.strictEqual(isMuiElement(, ['Input']), true);
+ });
});