From 4c5ba980d855ec23d0c4d97016f212369d7265db Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Thu, 30 May 2019 11:49:49 -0400 Subject: [PATCH] feat: add global transition disable switch (#506) --- src/Transition.js | 12 +++---- src/config.js | 3 ++ src/index.js | 9 ++--- stories/Transition.js | 21 ++++++----- www/src/components/Layout.js | 3 ++ www/src/pages/testing.js | 68 ++++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 src/config.js create mode 100644 www/src/pages/testing.js diff --git a/src/Transition.js b/src/Transition.js index a12cf71f..3fc7308c 100644 --- a/src/Transition.js +++ b/src/Transition.js @@ -2,6 +2,7 @@ import * as PropTypes from 'prop-types' import React from 'react' import ReactDOM from 'react-dom' +import config from './config' import { timeoutsShape } from './utils/PropTypes' import TransitionGroupContext from './TransitionGroupContext' @@ -223,15 +224,13 @@ class Transition extends React.Component { performEnter(node, mounting) { const { enter } = this.props - const appearing = this.context - ? this.context.isMounting - : mounting + const appearing = this.context ? this.context.isMounting : mounting const timeouts = this.getTimeouts() const enterTimeout = appearing ? timeouts.appear : timeouts.enter // no enter animation skip right to ENTERED // if we are mounting and running this it means appear _must_ be set - if (!mounting && !enter) { + if ((!mounting && !enter) || config.disabled) { this.safeSetState({ status: ENTERED }, () => { this.props.onEntered(node) }) @@ -256,7 +255,7 @@ class Transition extends React.Component { const timeouts = this.getTimeouts() // no exit animation skip right to EXITED - if (!exit) { + if (!exit || config.disabled) { this.safeSetState({ status: EXITED }, () => { this.props.onExited(node) }) @@ -312,7 +311,8 @@ class Transition extends React.Component { onTransitionEnd(node, timeout, handler) { this.setNextCallback(handler) - const doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener + const doesNotHaveTimeoutOrListener = + timeout == null && !this.props.addEndListener if (!node || doesNotHaveTimeoutOrListener) { setTimeout(this.nextCallback, 0) return diff --git a/src/config.js b/src/config.js new file mode 100644 index 00000000..a726e96e --- /dev/null +++ b/src/config.js @@ -0,0 +1,3 @@ +export default { + disabled: false, +} diff --git a/src/index.js b/src/index.js index bbf1835e..0fca170b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ -export { default as CSSTransition } from './CSSTransition'; -export { default as ReplaceTransition } from './ReplaceTransition'; -export { default as TransitionGroup } from './TransitionGroup'; -export { default as Transition } from './Transition'; +export { default as CSSTransition } from './CSSTransition' +export { default as ReplaceTransition } from './ReplaceTransition' +export { default as TransitionGroup } from './TransitionGroup' +export { default as Transition } from './Transition' +export { default as config } from './config' diff --git a/stories/Transition.js b/stories/Transition.js index db8093d1..2044e49f 100644 --- a/stories/Transition.js +++ b/stories/Transition.js @@ -1,9 +1,12 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; +import React from 'react' +import { storiesOf } from '@storybook/react' import { Fade, Collapse } from './transitions/Bootstrap' -import StoryFixture from './StoryFixture'; +import StoryFixture from './StoryFixture' +import { config } from '../src/index' + +config.disabled = true class ToggleFixture extends React.Component { state = { show: this.props.defaultIn } @@ -12,15 +15,17 @@ class ToggleFixture extends React.Component {
{React.cloneElement(this.props.children, { - in: this.state.show + in: this.state.show, })}
) @@ -45,4 +50,4 @@ storiesOf('Transition', module) - )); + )) diff --git a/www/src/components/Layout.js b/www/src/components/Layout.js index 8e4c8df7..34aceb57 100644 --- a/www/src/components/Layout.js +++ b/www/src/components/Layout.js @@ -50,6 +50,9 @@ const Layout = ({ data, children }) => ( With React Router + + Testing + diff --git a/www/src/pages/testing.js b/www/src/pages/testing.js new file mode 100644 index 00000000..47d20541 --- /dev/null +++ b/www/src/pages/testing.js @@ -0,0 +1,68 @@ +import { graphql } from 'gatsby'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { Container } from 'react-bootstrap'; +import Layout from '../components/Layout'; +import Example from '../components/Example'; + +const propTypes = { + location: PropTypes.object.isRequired, + data: PropTypes.shape({ + site: PropTypes.shape({ + siteMetadata: PropTypes.shape({ + componentPages: PropTypes.arrayOf( + PropTypes.shape({ + path: PropTypes.string.isRequired, + displayName: PropTypes.string.isRequired, + }) + ).isRequired, + }).isRequired, + }).isRequired, + }).isRequired, +}; + +const Testing = ({ data, location }) => ( + + +

Testing Components with Transitions

+

+ In some situations, like visual snapshot testing, it's helpful to + disable transitions so they don't complicate the test, or introduce + abitrary waits. To make this easier react-transition-group{' '} + exposes a way to globally toggle transitions. When set,{' '} + all transitions, when toggled, will immediately switch + to their entered or exited states as appropriate. +

+
+        
+          {`
+import { config } from 'react-transition-group
+
+config.disabled = true
+              `.trim()}
+        
+      
+
+

+ Note: This does not automatically disable + animations. It only disabled waits in Transition. You may + also have to disable animation as appropriate for the library. + example:{' '} + Mocking in Velocity.js +

+
+
+
+); + +Testing.propTypes = propTypes; + +export default Testing; + +export const pageQuery = graphql` + query TestingQuery { + site { + ...Layout_site + } + } +`;