From 15dfe1cc99091af7c237a8b1f6c7aeec5467ecd9 Mon Sep 17 00:00:00 2001 From: Neil Gabbadon Date: Mon, 15 Feb 2016 02:19:38 -0500 Subject: [PATCH] Remove context-pure mixin --- src/SelectField/SelectField.jsx | 14 -- src/TextField/TextField.jsx | 41 +--- src/buttons/flat-button-label.jsx | 13 -- src/card/card-expandable.jsx | 13 -- src/date-picker/date-picker-dialog.jsx | 21 +- src/flat-button.jsx | 69 ++---- src/icon-button.jsx | 27 --- src/mixins/context-pure.js | 55 ----- src/snackbar.jsx | 22 -- test/mixin-context-pure-spec.js | 278 ------------------------- 10 files changed, 31 insertions(+), 522 deletions(-) delete mode 100644 src/mixins/context-pure.js delete mode 100644 test/mixin-context-pure-spec.js diff --git a/src/SelectField/SelectField.jsx b/src/SelectField/SelectField.jsx index a4efa188660837..7933ca82581ed7 100644 --- a/src/SelectField/SelectField.jsx +++ b/src/SelectField/SelectField.jsx @@ -2,7 +2,6 @@ import React from 'react'; import TextField from '../text-field'; import DropDownMenu from '../DropDownMenu'; import getMuiTheme from '../styles/getMuiTheme'; -import ContextPure from '../mixins/context-pure'; function getStyles(props) { return { @@ -142,19 +141,6 @@ const SelectField = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getChildrenClasses() { - return [ - TextField, - DropDownMenu, - ]; - }, - }, - getDefaultProps() { return { autoWidth: false, diff --git a/src/TextField/TextField.jsx b/src/TextField/TextField.jsx index 80784f32f48ac3..7d461b895c8843 100644 --- a/src/TextField/TextField.jsx +++ b/src/TextField/TextField.jsx @@ -6,7 +6,6 @@ import Transitions from '../styles/transitions'; import UniqueId from '../utils/unique-id'; import EnhancedTextarea from '../enhanced-textarea'; import getMuiTheme from '../styles/getMuiTheme'; -import ContextPure from '../mixins/context-pure'; import TextFieldHint from './TextFieldHint'; import TextFieldLabel from './TextFieldLabel'; import TextFieldUnderline from './TextFieldUnderline'; @@ -186,31 +185,9 @@ const TextField = React.createClass({ }, mixins: [ - ContextPure, StylePropable, ], - statics: { - getRelevantContextKeys(muiTheme) { - const textFieldTheme = muiTheme.textField; - - return { - floatingLabelColor: textFieldTheme.floatingLabelColor, - focusColor: textFieldTheme.focusColor, - textColor: textFieldTheme.textColor, - disabledTextColor: textFieldTheme.disabledTextColor, - backgroundColor: textFieldTheme.backgroundColor, - hintColor: textFieldTheme.hintColor, - errorColor: textFieldTheme.errorColor, - }; - }, - getChildrenClasses() { - return [ - EnhancedTextarea, - ]; - }, - }, - getDefaultProps() { return { disabled: false, @@ -268,14 +245,16 @@ const TextField = React.createClass({ getStyles() { const props = this.props; const { - floatingLabelColor, - focusColor, - textColor, - disabledTextColor, - backgroundColor, - hintColor, - errorColor, - } = this.constructor.getRelevantContextKeys(this.state.muiTheme); + textField: { + floatingLabelColor, + focusColor, + textColor, + disabledTextColor, + backgroundColor, + hintColor, + errorColor, + }, + } = this.state.muiTheme; const styles = { root: { diff --git a/src/buttons/flat-button-label.jsx b/src/buttons/flat-button-label.jsx index 5e85f3fe874861..8be7bdfeb847b0 100644 --- a/src/buttons/flat-button-label.jsx +++ b/src/buttons/flat-button-label.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import ContextPure from '../mixins/context-pure'; import getMuiTheme from '../styles/getMuiTheme'; function getStyles(props, state) { @@ -35,18 +34,6 @@ const FlatButtonLabel = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getRelevantContextKeys(muiTheme) { - return { - spacingDesktopGutterLess: muiTheme.rawTheme.spacing.desktopGutterLess, - }; - }, - }, - getInitialState() { return { muiTheme: this.context.muiTheme || getMuiTheme(), diff --git a/src/card/card-expandable.jsx b/src/card/card-expandable.jsx index d81c28a7658d6a..0be15392fdb867 100644 --- a/src/card/card-expandable.jsx +++ b/src/card/card-expandable.jsx @@ -3,7 +3,6 @@ import OpenIcon from '../svg-icons/hardware/keyboard-arrow-up'; import CloseIcon from '../svg-icons/hardware/keyboard-arrow-down'; import IconButton from '../icon-button'; import getMuiTheme from '../styles/getMuiTheme'; -import ContextPure from '../mixins/context-pure'; function getStyles() { return { @@ -37,18 +36,6 @@ const CardExpandable = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getChildrenClasses() { - return [ - IconButton, - ]; - }, - }, - getInitialState() { return { muiTheme: this.context.muiTheme || getMuiTheme(), diff --git a/src/date-picker/date-picker-dialog.jsx b/src/date-picker/date-picker-dialog.jsx index 5eedecee036b3a..206d4f59b57128 100644 --- a/src/date-picker/date-picker-dialog.jsx +++ b/src/date-picker/date-picker-dialog.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import ContextPure from '../mixins/context-pure'; import EventListener from 'react-event-listener'; import KeyCode from '../utils/key-code'; import Calendar from './calendar'; @@ -42,24 +41,6 @@ const DatePickerDialog = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getRelevantContextKeys(muiTheme) { - return { - calendarTextColor: muiTheme.datePicker.calendarTextColor, - }; - }, - getChildrenClasses() { - return [ - Calendar, - Dialog, - ]; - }, - }, - getDefaultProps: function() { return { DateTimeFormat: DateTime.DateTimeFormat, @@ -148,7 +129,7 @@ const DatePickerDialog = React.createClass({ const { calendarTextColor, - } = this.constructor.getRelevantContextKeys(this.state.muiTheme); + } = this.state.muiTheme.datePicker; const styles = { root: { diff --git a/src/flat-button.jsx b/src/flat-button.jsx index 77c47d53c03df8..7ffd8c72fe1215 100644 --- a/src/flat-button.jsx +++ b/src/flat-button.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import ContextPure from './mixins/context-pure'; import Transitions from './styles/transitions'; import Children from './utils/children'; import ColorManipulator from './utils/color-manipulator'; @@ -122,41 +121,10 @@ const FlatButton = React.createClass({ muiTheme: React.PropTypes.object, }, - //for passing default theme context to children childContextTypes: { muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getRelevantContextKeys(muiTheme) { - const buttonTheme = muiTheme.button; - const flatButtonTheme = muiTheme.flatButton; - - return { - buttonColor: flatButtonTheme.color, - buttonFilterColor: flatButtonTheme.buttonFilterColor, - buttonHeight: buttonTheme.height, - buttonMinWidth: buttonTheme.minWidth, - disabledTextColor: flatButtonTheme.disabledTextColor, - primaryTextColor: flatButtonTheme.primaryTextColor, - secondaryTextColor: flatButtonTheme.secondaryTextColor, - textColor: flatButtonTheme.textColor, - textTransform: flatButtonTheme.textTransform ? flatButtonTheme.textTransform : - (buttonTheme.textTransform ? buttonTheme.textTransform : 'uppercase'), - }; - }, - getChildrenClasses() { - return [ - EnhancedButton, - FlatButtonLabel, - ]; - }, - }, - getDefaultProps() { return { disabled: false, @@ -186,11 +154,10 @@ const FlatButton = React.createClass({ }; }, - //to update theme inside state whenever a new theme is passed down - //from the parent / owner using context componentWillReceiveProps(nextProps, nextContext) { - const newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme; - this.setState({muiTheme: newMuiTheme}); + this.setState({ + muiTheme: nextContext.muiTheme || this.state.muiTheme, + }); }, _handleKeyboardFocus(e, isKeyboardFocused) { @@ -232,17 +199,23 @@ const FlatButton = React.createClass({ } = this.props; const { - buttonColor, - buttonHeight, - buttonMinWidth, - disabledTextColor, - buttonFilterColor, - primaryTextColor, - secondaryTextColor, - textColor, - textTransform, - } = this.constructor.getRelevantContextKeys(this.state.muiTheme); - + button: { + height: buttonHeight, + minWidth: buttonMinWidth, + textTransform: buttonTextTransform, + }, + flatButton: { + buttonFilterColor, + color: buttonColor, + disabledTextColor, + fontSize, + fontWeight, + primaryTextColor, + secondaryTextColor, + textColor, + textTransform = buttonTextTransform || 'uppercase', + }, + } = this.state.muiTheme; const defaultTextColor = disabled ? disabledTextColor : primary ? primaryTextColor : secondary ? secondaryTextColor : @@ -254,8 +227,6 @@ const FlatButton = React.createClass({ const buttonRippleColor = rippleColor || defaultRippleColor; const buttonBackgroundColor = backgroundColor || buttonColor; const hovered = (this.state.hovered || this.state.isKeyboardFocused) && !disabled; - const fontSize = this.state.muiTheme.flatButton.fontSize; - const fontWeight = this.state.muiTheme.flatButton.fontWeight; const mergedRootStyles = Object.assign({}, { color: defaultTextColor, diff --git a/src/icon-button.jsx b/src/icon-button.jsx index 4c79a05abdfde7..00901f924f3640 100644 --- a/src/icon-button.jsx +++ b/src/icon-button.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import ContextPure from './mixins/context-pure'; import Transitions from './styles/transitions'; import PropTypes from './utils/prop-types'; import EnhancedButton from './enhanced-button'; @@ -132,36 +131,10 @@ const IconButton = React.createClass({ muiTheme: React.PropTypes.object, }, - //for passing default theme context to children childContextTypes: { muiTheme: React.PropTypes.object, }, - mixins: [ - ContextPure, - ], - - statics: { - getRelevantContextKeys(muiTheme) { - const spacing = muiTheme.rawTheme.spacing; - const palette = muiTheme.rawTheme.palette; - - return { - iconSize: spacing.iconSize, - textColor: palette.textColor, - disabledColor: palette.disabledColor, - }; - }, - - getChildrenClasses() { - return [ - EnhancedButton, - FontIcon, - Tooltip, - ]; - }, - }, - getDefaultProps() { return { disabled: false, diff --git a/src/mixins/context-pure.js b/src/mixins/context-pure.js deleted file mode 100644 index 6799a5995c31f9..00000000000000 --- a/src/mixins/context-pure.js +++ /dev/null @@ -1,55 +0,0 @@ -import shallowEqual from '../utils/shallow-equal'; - -function relevantContextKeysEqual(classObject, currentContext, nextContext) { - - //Get those keys from current object's context that we care - //about and check whether those keys have changed or not - if (classObject.getRelevantContextKeys) { - const currentContextKeys = classObject.getRelevantContextKeys(currentContext); - const nextContextKeys = classObject.getRelevantContextKeys(nextContext); - - if (!shallowEqual(currentContextKeys, nextContextKeys)) { - return false; - } - } - - //Check if children context keys changed - if (classObject.getChildrenClasses) { - const childrenArray = classObject.getChildrenClasses(); - for (let i = 0; i < childrenArray.length; i++) { - if (!relevantContextKeysEqual(childrenArray[i], currentContext, nextContext)) { - return false; - } - } - } - - //context keys are equal - return true; -} - -export default { - - //Don't update if state, prop, and context are equal - shouldComponentUpdate(nextProps, nextState, nextContext) { - - //If either the props or state have changed, component should update - if (!shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)) { - return true; - } - - //If current theme and next theme are both undefined, do not update - if (!this.context.muiTheme && !nextContext.muiTheme) { - return false; - } - - //If both themes exist, compare keys only if current theme is not static - if (this.context.muiTheme && nextContext.muiTheme) { - return !this.context.muiTheme.static && - !relevantContextKeysEqual(this.constructor, this.context.muiTheme, nextContext.muiTheme); - } - - //At this point it is guaranteed that exactly one theme is undefined so simply update - return true; - }, - -}; diff --git a/src/snackbar.jsx b/src/snackbar.jsx index 1872231a7afa38..09a0b3626bddee 100644 --- a/src/snackbar.jsx +++ b/src/snackbar.jsx @@ -3,7 +3,6 @@ import Transitions from './styles/transitions'; import ClickAwayable from './mixins/click-awayable'; import FlatButton from './flat-button'; import getMuiTheme from './styles/getMuiTheme'; -import ContextPure from './mixins/context-pure'; import StyleResizable from './mixins/style-resizable'; function getStyles(props, state) { @@ -140,29 +139,8 @@ const Snackbar = React.createClass({ mixins: [ StyleResizable, ClickAwayable, - ContextPure, ], - statics: { - getRelevantContextKeys(muiTheme) { - const theme = muiTheme.snackbar; - const spacing = muiTheme.baseTheme.spacing; - - return { - textColor: theme.textColor, - backgroundColor: theme.backgroundColor, - desktopGutter: spacing.desktopGutter, - desktopSubheaderHeight: spacing.desktopSubheaderHeight, - actionColor: theme.actionColor, - }; - }, - getChildrenClasses() { - return [ - FlatButton, - ]; - }, - }, - getInitialState() { return { open: this.props.open, diff --git a/test/mixin-context-pure-spec.js b/test/mixin-context-pure-spec.js deleted file mode 100644 index a6718b0e8ecc2d..00000000000000 --- a/test/mixin-context-pure-spec.js +++ /dev/null @@ -1,278 +0,0 @@ -import React from 'react'; -import ContextPure from 'mixins/context-pure'; -import getMuiTheme from 'styles/getMuiTheme'; -import TestUtils from 'react-addons-test-utils'; -import update from 'react-addons-update'; - -const GrandChildComponent = React.createClass({ - - contextTypes: { - muiTheme: React.PropTypes.object, - }, - - mixins: [ContextPure], - - statics: { - getRelevantContextKeys(muiTheme) { - return { - grandChildThemeProp: muiTheme.grandChildThemeProp, - }; - }, - }, - - renderCount: 0, - - getRenderCount() { - return this.renderCount; - }, - - render() { - this.renderCount++; - return
; - }, -}); - -const ChildComponent = React.createClass({ - contextTypes: { - muiTheme: React.PropTypes.object, - }, - - mixins: [ContextPure], - - statics: { - getRelevantContextKeys(muiTheme) { - return { - childThemeProp: muiTheme.childThemeProp, - }; - }, - getChildrenClasses() { - return [ - GrandChildComponent, - ]; - }, - }, - - getInitialState: function() { - return { - childState: 0, - }; - }, - - renderCount: 0, - - getGrandChildRenderCount() { - return this.refs.grandChild.getRenderCount(); - }, - - getRenderCount() { - return this.renderCount; - }, - - updateState(childState) { - this.setState({childState}); - }, - - render() { - this.renderCount++; - return ; - }, -}); - -const ParentComponent = React.createClass({ - - propTypes: { - staticTheme: React.PropTypes.bool, - }, - - childContextTypes: { - muiTheme: React.PropTypes.object, - }, - - - getDefaultProps: function() { - return { - staticTheme: true, - }; - }, - - getInitialState() { - return { - childProp: 0, - }; - }, - - getChildContext() { - return { - muiTheme: this.theme, - }; - }, - - componentWillMount() { - this.theme = getMuiTheme(); - this.theme.static = this.props.staticTheme; - this.theme.childThemeProp = 0; - this.theme.grandChildThemeProp = 0; - }, - - renderCount: 0, - - getChildRenderCount() { - return this.refs.child.getRenderCount(); - }, - - getGrandChildRenderCount() { - return this.refs.child.getGrandChildRenderCount(); - }, - - getRenderCount() { - return this.renderCount; - }, - - updateChildState(childState) { - this.refs.child.updateState(childState); - }, - - updateChildContextKey(childThemeProp) { - this.theme = update(this.theme, { - childThemeProp: {$set: childThemeProp}, - }); - this.forceUpdate(); - }, - - updateGrandChildContextKey(grandChildThemeProp) { - this.theme = update(this.theme, { - grandChildThemeProp: {$set: grandChildThemeProp}, - }); - this.forceUpdate(); - }, - - updateChildProp(childProp) { - this.setState({childProp}); - }, - - render() { - this.renderCount++; - return ; - }, -}); - -describe('Mixin-ContextPure', () => { - let parentElement; - - describe('when muiTheme.static is false', () => { - - beforeEach(() => { - parentElement = TestUtils.renderIntoDocument( - - ); - }); - - it('should not render when context is updated but did not change', () => { - parentElement.updateChildContextKey(0); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render when prop is updated but did not change', () => { - parentElement.updateChildProp(0); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render when state is updated but did not change', () => { - parentElement.updateChildState(0); - parentElement.getRenderCount().should.equal(1); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render when context props change', () => { - parentElement.updateChildContextKey(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render when props change', () => { - parentElement.updateChildProp(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render when state change', () => { - parentElement.updateChildState(1); - parentElement.getRenderCount().should.equal(1); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render grandchild when grandchild context props change', () => { - parentElement.updateGrandChildContextKey(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(2); - }); - }); - - describe('when muiTheme.static is true', () => { - beforeEach(() => { - parentElement = TestUtils.renderIntoDocument( - - ); - }); - - it('should not render when context is updated but did not change', () => { - parentElement.updateChildContextKey(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render when prop is updated but did not change', () => { - parentElement.updateChildProp(0); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render when state is updated but did not change', () => { - parentElement.updateChildState(0); - parentElement.getRenderCount().should.equal(1); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render when context props change', () => { - parentElement.updateChildContextKey(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should not render grandchild when grandchild context props change', () => { - parentElement.updateGrandChildContextKey(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(1); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render when props change', () => { - parentElement.updateChildProp(1); - parentElement.getRenderCount().should.equal(2); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - it('should render when state change', () => { - parentElement.updateChildState(1); - parentElement.getRenderCount().should.equal(1); - parentElement.getChildRenderCount().should.equal(2); - parentElement.getGrandChildRenderCount().should.equal(1); - }); - - }); - -});