Code Monkey home page Code Monkey logo

react-css-transition-replace's Introduction

React CSS Transition Replace

A React component to animate replacing one element with another.

While ReactCSSTransitionGroup does a great job of animating changes to a list of components and can even be used to animate the replacement of one item with another, proper handling of the container height in the latter case is not built in. This component is designed to do exactly that with an API closely following that of ReactCSSTransitionGroup.

Using react-css-transition-replace provides two distinct benefits:

  • It automatically handles the positioning of the animated components, and
  • allows changes in the height of container to be handled and animated with ease when various content heights differ, even when absolute positioning is used.

Animations are fully configurable with CSS, including having the entering component wait to enter until the leaving component's animation completes. Following suit with the React.js API the one caveat is that the transition duration must be specified in JavaScript as well as CSS.

Live Examples | Change Log | Upgrade Guide

Installation

Install via npm:

npm install --save react-css-transition-replace

Important Note

All functional child components must be wrapped in forwardRef to work correctly.

Usage

A ReactCSSTransitionReplace component can only have a single child. Other than that, the basic usage follows the exact same API as ReactCSSTransitionGroup, with support for transitionEnter, transitionLeave and transitionAppear. When the key of the child component changes, the previous component is animated out and the new component animated in. During this process:

  • All leaving components continue to be rendered; if the animation is slow there may be multiple components in the process of leaving.
  • The entering component is positioned on top of the leaving component(s) with absolute positioning.
  • The height of the container is set to that of the leaving component, and then immediately to that of the entering component. If the transitionName is a String the {animation-name}-height class name is applied to it, and if transitionName is an Object the transitionName.height class will be used if present.
  • The leaving component will be passed an isLeaving prop while transitioning out.

This provides many possibilities for animating the replacement as illustrated in the examples below.

Additionally, the boolean property changeWidth can be used to animate changing the width of the component. This change will happen at the same time as changing the height. Animating this change should be done using the same class name that is used for animating the change in height.

It is also possible to remove the child component (i.e. leave ReactCSSTransitionReplace with no children) which will animate the height going to zero along with the leave transition. Similarly, a single child can be added to an empty ReactCSSTransitionReplace, triggering the inverse animation.

By default a span is rendered as a wrapper of the child components. Each child is also wrapped in a span used in the positioning of the actual rendered child. These can be overridden with the component and childComponent props respectively.

Cross-fading two components

The ReactCSSTransitionReplace component is used exactly like its ReactCSSTransitionGroup counterpart:

import ReactCSSTransitionReplace from 'react-css-transition-replace';

render() {
  return (
    <ReactCSSTransitionReplace transitionName="cross-fade"
                               transitionEnterTimeout={1000} transitionLeaveTimeout={1000}>
      <SomeComponent key="uniqueValue"/>
    </ReactCSSTransitionReplace>
  );
}

To realize cross-fading of two components all that remains is to define the enter and leave opacity transitions in the associated CSS classes:

.cross-fade-leave {
  opacity: 1;
}
.cross-fade-leave.cross-fade-leave-active {
  opacity: 0;
  transition: opacity 1s ease-in;
}

.cross-fade-enter {
  opacity: 0;
}
.cross-fade-enter.cross-fade-enter-active {
  opacity: 1;
  transition: opacity 1s ease-in;
}

.cross-fade-height {
  transition: height 0.5s ease-in-out;
}

Note the additional .cross-fade-height class. This indicates how the container height is to be animated if the heights of the entering and leaving components are not the same. You can see this in action here.

Fade out, then fade in

To fade a component out and wait for its transition to complete before fading in the next, simply add a delay to the enter transition.

.fade-wait-leave {
  opacity: 1;
}
.fade-wait-leave.fade-wait-leave-active {
  opacity: 0;
  transition: opacity 0.4s ease-in;
}

.fade-wait-enter {
  opacity: 0;
}
.fade-wait-enter.fade-wait-enter-active {
  opacity: 1;
  /* Delay the enter animation until the leave completes */
  transition: opacity 0.4s ease-in 0.6s;
}

.fade-wait-height {
  transition: height 0.6s ease-in-out;
}

Note: The transitionEnterTimeout specified in the JS must be long enough to allow for the delay and the duration of the transition. In this case:

<ReactCSSTransitionReplace transitionName="fade-wait"
                           transitionEnterTimeout={1000} transitionLeaveTimeout={400}>

See the live example here.

React-Router v4

Animated transitions of react-router v4 routes is supported with two caveats shown in the example below:

  1. The current location must be applied to the Switch to force it to maintain the previous matched route on the leaving component.
  2. If the Switch might render null, i.e. there is no catch-all "*" route, the Switch must be wrapped in a div or similar for the leave transition to work; if not the previous component will disappear instantaneously when there is no match.
<Router>
  <div className="router-example">
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/one">One</Link>
      </li>
      <li>
        <Link to="/two">Two</Link>
      </li>
      <li>
        <Link to="/three">Three (no match)</Link>
      </li>
    </ul>
    <Route
      render={({ location }) => (
        <ReactCSSTransitionReplace
          transitionName="fade"
          transitionEnterTimeout={500}
          transitionLeaveTimeout={500}
        >
          <div key={location.pathname}>
            <Switch location={location}>
              <Route path="/" exact component={Home} />
              <Route path="/one" component={One} />
              <Route path="/two" component={Two} />
            </Switch>
          </div>
        </ReactCSSTransitionReplace>
      )}
    />
  </div>
</Router>

See the live example here.

Hardware acceleration for smoother transitions

For smoother transitions hardware acceleration, which is achieved by using translate3d instead of the 2D translations, should be used whenever possible. For example, to realize a mobile app transition between pages one might use:

.page-enter,
.page-leave {
  position: absolute;
  -webkit-transition: transform 250ms ease-in-out, opacity 250ms ease-in-out;
  transition: transform 250ms ease-in-out, opacity 250ms ease-in-out;
}

.page-enter {
  left: 100vw;
}

.page-enter.page-enter-active {
  -webkit-transform: translate3d(-100vw, 0, 0);
  transform: translate3d(-100vw, 0, 0);
}

.page-leave {
  left: 0;
}

.page-leave.page-leave-active {
  -webkit-transform: translate3d(-100vw, 0, 0);
  transform: translate3d(-100vw, 0, 0);
}
<ReactCSSTransitionReplace
  transitionName="page"
  transitionEnterTimeout={250}
  transitionLeaveTimeout={250}
>
  <div key="page01">My page 01 content</div>
</ReactCSSTransitionReplace>

Tips

  1. In general animating block or inline-block level elements is more stable that inline elements. If the height changes in random ways ensure that there isn't a span or other inline element used as the outer element of the components being animated.
  2. The overflow of the container is set to 'hidden' automatically, which changes the behaviour of collapsing margins from the default 'visible'. This may cause a glitch in the height at the start or end of animations. To avoid this you can:
    • Keep the overflow hidden permanently with custom styles/classes if that will not cause undesired side-effects.
    • Only use Single-direction margin declarations to avoid collapsing margins overall.
    • Turn this feature off by setting the overflowHidden={false} prop when hidden overflow is not needed, for example when transitions are in place and content is of the same height.
  3. If the .*-height class (or transitionName.height) is not specified the change in container height will not be animated but instead jump to the height of the entering component instantaneously. It can, therefore, be omitted if all content is known to be of the same height without any adverse side-effects, and absolute positioning related height issues will still be avoided.

Contributing

PRs are welcome.

License

This software is free to use under the MIT license. See the LICENSE file for license text and copyright information.

react-css-transition-replace's People

Contributors

adrianmcli avatar awreccan avatar cgarvis avatar jdelstrother avatar krtcom avatar le0nik avatar marnusw avatar petetnt avatar skempin avatar w33ble avatar wifilinker avatar zabojad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-css-transition-replace's Issues

ReactCSSTransitionReplace inside another error

Hello,

I have tried using animations within the following environment:
Inside a <ReactCSSTransitionReplace> i'm trying to use another component with the same tag inside it. The problem here is that the outer component animation works fine while for the inner, it does not.

react/lib/Object.assign not in react 0.15

Module not found: Error: Cannot resolve module 'react/lib/Object.assign' in .../node_modules/react-css-transition-replace/lib

Apparently the react team suggests using lodash/underscore for utility functions now.

Error after upgrade to v4.0

Hello!
I have an issue after the v4 upgrade regarding dom-helpers: Cannot find module 'dom-helpers/util/requestAnimationFrame'

Here is my config:
react: 16.10.1
react-css-transition-replace: 4.0.0

I tried to install dom-helpers (v5.1.0) but it didn't changed. After that i've searched in your package.json and found you already use it.

So i ran through their package and found out there is no "utils" folder. It seems to be renamed to "dom-helpers/animationFrame" and has to be used like:
"animationFrame.request(cb) returns an ID for canceling"

I did the change in the ReactCssTransitionReplace.js file, and there is another error occuring: "Cannot find module 'dom-helpers/class/addClass'"

I guess this is the same error pattern as the previous one, but i have to go to work so i can't continue to investigate on this for now.

In the meantime if you have an idea on how to fix that, i'd appreciate it :)

Anyway, cheers for the excellent work!

EDIT:
So i continued to change imports to match files of dom-helpers package, ended up with something like this in ReactCssTransitionReplaceChild.js:

import addClass from 'dom-helpers/addClass'
import removeClass from 'dom-helpers/removeClass'
import animationFrame from 'dom-helpers/animationFrame'
import transitionEnd from 'dom-helpers/transitionEnd'

And removed line 21 to 23. I'm not sure about TransitionEnd, as it completely delete animationEnd event.

Anyway, it does compile... until dom-helpers uses "window" and breaks my ssr.

So i'm rolling back to 3.0.3 until we solve this issue.

EDIT 2:
Possible solution: maybe rollback dom-helpers to the last working version (^3.3.1)?

Support for more than one child?

I'm currently trying to figure out how to properly animate a list of Bootstrap breadcrumbs. Using CSSTransitionGroup from React results in the breadcrumbs list to expand to accommodate both the entering and leaving breadcrumbs and then contracting again when the leaving component is removed from the DOM.

I was hoping to use this component to fix my problem, but unfortunately, it is restricted to a single child. What would be required to also support multiple children? Would you be interested in merging such a feature?

Carousel transition entering content occasionally appears at final position

I'm not totally sure how to debug this, and it is somewhat inconsistent.
When using a carousel replace, sometimes the entering content appears at its final position and doesn't transition in.

transition-bug

My transition CSS is as follows

.carousel-swap-leave, .carousel-swap-left-leave {
    transition: transform @transition-time ease-in-out;
    transform: translate3d(0, 0, 0);
  }
  .carousel-swap-leave-active, .carousel-swap-left-leave-active {
    transform: translate3d(-100%, 0, 0);
  }

  .carousel-swap-enter, .carousel-swap-left-enter {
    transition: transform @transition-time ease-in-out;
    transform: translate3d(100%, 0, 0);
  }
  .carousel-swap-enter-active, .carousel-swap-left-enter-active {
    transform: translate3d(0, 0, 0);
  }


  .carousel-swap-right-leave {
    transition: transform @transition-time ease-in-out;
    transform: translate3d(0, 0, 0);
  }
  .carousel-swap-right-leave-active {
    transform: translate3d(100%, 0, 0);
  }

  .carousel-swap-right-enter {
    transition: transform @transition-time ease-in-out;
    transform: translate3d(-100%, 0, 0);
  }
  .carousel-swap-right-enter-active {
    transform: translate3d(0, 0, 0);
  }

  .carousel-swap-height, .carousel-swap-right-height, .carousel-swap-left-height {
    transition: height @transition-time ease-out;
  }

And my jsx is pretty simple:

<ReactCSSTransitionReplace transitionName={`carousel-swap-${this.state.direction}`} transitionEnterTimeout={EditorModal.CAROUSEL_TRANSITION_TIME} transitionLeaveTimeout={EditorModal.CAROUSEL_TRANSITION_TIME}>
          <div key={details.key}>
            {details.text}
          </div>
</ReactCSSTransitionReplace>

Any ideas on what could be wrong?

ReactCSSTransitionReplace with react-router v4 Bug?

Hello. I think what found bug. When animation is start I see next route not current.
image
On screen you can see two Switch with child Route. In first Switch with ref "curr" you can see Login Route and in last Switch with ref "next" you can see Login route.
It is bug or somewhing else?
I have this jsx:

<ReactCSSTransitionReplace
	component="div"
	className="transition-wrapper"
	transitionName="wq-fadeOutLeft"
	transitionEnterTimeout={10000}
	transitionLeaveTimeout={10000}>
	<Switch key={location.pathname} location={location}>
	{
		routes && routes.length > 0 ?
			routes.map(({component: Component, ...rest}, index) => (
				<Route key={location.key} {...rest}
				       render={matchProps => (
					       <Component {...matchProps} routes={rest.routes} />
				       )}
				/>)
			)
			: ''
	}
	</Switch>
</ReactCSSTransitionReplace>

and css:

.wq-fadeOutLeft-leave {
	opacity: 1;
}
.wq-fadeOutLeft-leave.wq-fadeOutLeft-leave-active {
	opacity: 0;
	transition: opacity 10s ease-in, transform 10s ease-in-out;
	transform: translate3d(-500px, 0, 0);
}

.wq-fadeOutLeft-enter {
	opacity: 0.01;
	transform: translate3d(500px, 0, 0);
}
.wq-fadeOutLeft-enter.wq-fadeOutLeft-enter-active {
	opacity: 1;
	transition: opacity 10s ease-in, transform 10s ease-in-out;
	transform: translate3d(0, 0, 0);
}

React router redirection is bugged

I have stumbled on an issue with using this package with react-router.

When i use <Redirect /> component from react-router-dom module inside the <Switch /> component which is rendered by transition i am getting a warning:

You tried to redirect to the same route you're currently on: "/route"

I have make sandbox to reproduce this issue.To reproduce it click on the force redireciton link.

This is very annoying because when i am testing my application this makes infinitive loop of redirection.

Btw. Thanks for this module.

Cheers!

Passing invalid attibutes

React 15.2 errors on passing invalid attributes to elements. Have a fix and send a pull request that basically strips out the react-css-transition-replace attributes before sending them along.

Breaks since 15.4.0 was released

Started getting an error today and it looks like it is related to importing a private file from the React codebase.

Error I'm seeing:

ERROR in ./~/react-css-transition-replace/~/react/lib/ReactAddonsDOMDependencies.js
Module not found: Error: Cannot resolve module 'react-dom/lib/ReactDOM' in PROJECT/node_modules/react-css-transition-replace/node_modules/react/lib
 @ ./~/react-css-transition-replace/~/react/lib/ReactAddonsDOMDependencies.js 13:15-48

ERROR in ./~/react-css-transition-replace/~/react/lib/ReactAddonsDOMDependencies.js
Module not found: Error: Cannot resolve module 'react-dom/lib/ReactInstanceMap' in PROJECT/node_modules/react-css-transition-replace/node_modules/react/lib
 @ ./~/react-css-transition-replace/~/react/lib/ReactAddonsDOMDependencies.js 14:23-64

ERROR in ./~/react-css-transition-replace/~/react/lib/ReactTransitionEvents.js
Module not found: Error: Cannot resolve module 'react-dom/lib/getVendorPrefixedEventName' in PROJECT/node_modules/react-css-transition-replace/node_modules/react/lib
 @ ./~/react-css-transition-replace/~/react/lib/ReactTransitionEvents.js 15:33-84

I'm using 15.3.2 specifically in the project but webpack build ends up trying to use the newer version of React for the production build.

Can I use this with react-router v4?

I'd like to be able to do something like this:

        <Route render={({ location }) => (
            <div>
                    <ReactCSSTransitionReplace
                        transitionName="cross-fade"
                        transitionEnterTimeout={1000}
                        transitionLeaveTimeout={1000}
                    >
                        <Route key={location.key + "one"} exact path="/" component={HomePage}/>
                        <Route key={location.key + "two"}  path="/two" component={SomeOtherComponent}/>
                        <Route key={location.key + "three"}  path="/three" component={YetAnotherComponent}/>
                    </ReactCSSTransitionReplace>
            </div>
        )}/>

However, I can't because RCTReplace expects an only child. Is there any sort of workaround I can do?

allow prop `transitionName` to be type of `object`

On this example I get the following warning.

        <ReactCSSTransitionReplace
          component='div'
          transitionName={{
            enter: PreviewEnter,
            leave: PreviewLeave
          }}
          transitionEnterTimeout={400}
          transitionLeaveTimeout={400}
        >
          { this.renderPreview() }
        </ReactCSSTransitionReplace>
Failed propType: Invalid prop `transitionName` of type `object` supplied to `ReactCSSTransitionReplace`, expected `string`

I am expecting an object is also okay, according to ReactCSSTransitionGroup
https://facebook.github.io/react/docs/animation.html#custom-classes

The functionality seems to be there, but the warning is a red herring

Warning: You are manually calling a React.PropTypes validation function for the `formControlFeedback` prop on `Glyphicon`.

Hi,

I'm getting this warning:

Warning: You are manually calling a React.PropTypes validation function for the formControlFeedback prop on Glyphicon. This is deprecated and will not work in production with the next major version. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details.

The only place I see reference to these objects is in this file:

node_modules/react-css-transition-replace/gh-pages/app.js

I am using webpack's DllPlugin to pre-package this, something like this:

{
    entry: {
        vendor: [
            "react",
            'redux',
            'react-css-transition-replace'
        ]
    }
}

I see it get picked up into the webpack DLL
Is there a way that the gh-pages directory can be excluded from the package you push to NPM?

/***/ },
/* 309 */
/***/ function(module, exports, __webpack_require__) {

"use strict";


var _extends = __webpack_require__(17)['default'];

var _interopRequireDefault = __webpack_require__(14)['default'];

exports.__esModule = true;

var _classnames = __webpack_require__(15);

var _classnames2 = _interopRequireDefault(_classnames);

var _react = __webpack_require__(0);

var _react2 = _interopRequireDefault(_react);

var _reactPropTypesLibDeprecated = __webpack_require__(318);

var _reactPropTypesLibDeprecated2 = _interopRequireDefault(_reactPropTypesLibDeprecated);

var Glyphicon = _react2['default'].createClass({
  displayName: 'Glyphicon',

  propTypes: {
    /**
     * bootstrap className
     * @private
     */
    bsClass: _react2['default'].PropTypes.string,
    /**
     * An icon name. See e.g. http://getbootstrap.com/components/#glyphicons
     */
    glyph: _react2['default'].PropTypes.string.isRequired,
    /**
     * Adds 'form-control-feedback' class
     * @private
     */
    formControlFeedback: _reactPropTypesLibDeprecated2['default'](_react2['default'].PropTypes.bool, 'Use `<FormControl.Feedback>`.')
  },

  getDefaultProps: function getDefaultProps() {
    return {
      bsClass: 'glyphicon'
    };
  },

  render: function render() {
    var _classNames;

    var className = _classnames2['default'](this.props.className, (_classNames = {}, _classNames[this.props.bsClass] = true, _classNames['glyphicon-' + this.props.glyph] = true, _classNames['form-control-feedback'] = this.props.formControlFeedback, _classNames));

    return _react2['default'].createElement(
      'span',
      _extends({}, this.props, { className: className }),
      this.props.children
    );
  }
});

exports['default'] = Glyphicon;
module.exports = exports['default'];

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs.

I'm running into this issue when trying to use react-css-transition-replace:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).

I thought it is because the npm version uses 0.14.0-rc1 but even when using the master version that uses 0.14.0, I get this...

Any idea what I'm doing wrong ?

Add option to not animate height changes

This component is great! Is there any way to not animate height changes of components? I want to replace one component with another, and I don't care that they are different heights.

Children update is ignored when animation is in progress

You can easily reproduce this bug in the "Cross-fade transition" example in demo.

If you quickly click twice (like doubleclick) on the image, the page will show the 2nd image. But at this moment, the parent component has already changed its state twice (swapped: false->true->false) and expecting <ReactCSSTransitionReplace> to show the 1st image. Apparently <ReactCSSTransitionReplace> ignored the 2nd change because the animation was not completed.

Now if you click on the image again (swapped is changed to true), nothing will happen on the page.

Cannot read property 'offsetHeight' of null

Hi, i am getting the error: Cannot read property 'offsetHeight' of null, sometimes. I have a

element that is doing the following:

<ReactCSSTransitionReplace transitionName="fade-wait" 
                                     overflowHidden={false}
                                     transitionEnterTimeout={Constants.Feed.FadeTransitionInterval.Enter} 
                                     transitionLeaveTimeout={Constants.Feed.FadeTransitionInterval.Leave}>
            <MyElement key={this.state.key} data={data} />
</ReactCSSTransitionReplace>

In chrome:

 this.setState({
        nextChild: nextChild,
        height: _reactDom2['default'].findDOMNode(this.refs.curr).offsetHeight //<-- null
      }, function () {
        return _this2.setState({
          height: _reactDom2['default'].findDOMNode(_this2.refs.next).offsetHeight
        });
      });

I would like to narrow down the error for you, but it seems to happen very unpredicatbly, as i have an array of 15 objects and using setInterval, i'm replacing the element every 5s or so, when i idle for 20mins or so, the null exception occurs but in the timespan, it would have rotated at least a couple hundred times. Is it due to garbage collection?

Component refresh after finishing transition

I'm using your crossfade example with react-router:

<ReactCSSTransitionReplace transitionName="cross-fade" transitionAppear={true} transitionAppearTimeout={1000} transitionEnterTimeout={1000} transitionLeaveTimeout={1000}>
  {React.cloneElement(this.props.children, { key: this.props.location.pathname,})}
</ReactCSSTransitionReplace>

But as soon as the fade finishes, the component being routed to is refreshed and all the animations within the component (if any) refresh as well.

Edit: It seems according to dev tools that it inserts a new version of the component after the animation finishes. Any way around this?

Transition are not putting 'enter' class into element, only 'enter-active'

image

As you can see above, the appearing element have class CrossFade-enter-active, but don't have CrossFade-enter class, causing the appearing element not fade (it appears as 100% opacity, while the other fade correctly to disappear), see below.

bug-replace

I really don't know what is causing this.

My setup:

Usage:

<Replace
  transitionName="CrossFade"
  transitionEnterTimeout={1000}
  transitionLeaveTimeout={1000}
>
  {renderMethod()}
</Replace>

Note: renderMethod return a div with unique key

CSS:

.CrossFade-leave {
  opacity: 1;
}

.CrossFade-leave.CrossFade-leave-active {
  opacity: 0;
  transition: opacity 1s ease-in;
}

.CrossFade-enter {
  opacity: 0;
}

.CrossFade-enter.CrossFade-enter-active {
  opacity: 1;
  transition: opacity 1s ease-in;
}

.CrossFade-height {
  transition: height 500ms ease-in-out;
}

Support CommonJS

Small thing that caught my eye when upgrading from a 0.x version to 1.x. : )

Currently react-css-transition-replace is not compatible with CommonJS. So you need to remember to add .default when importing it.

const ReactCSSTransitionReplace = require('react-css-transition-replace').default;

Although most people are using ES2015 these days, I think it would be nice to be compatible with CommonJS or at least document the lack of support.

Thanks ๐Ÿ‘

Container height jump to height of next component

Hi there,

I was struggling with this problem for a while until I noticed this at the bottom of your very helpful page :)

If the .*-height class (or transitionName.height) is not specified the change in container height will not be animated but instead jump to the height of the entering component instantaneously.

Still I'm not sure what to do here. It's happening on the carousel-swap, and I've tried going my css file and setting .carousel-swap { height: }, but is that the way to go about it? I'm not sure either what the *-height class is? :)

Hope you can help!

  • Nikoflash

Some elements enter suddenly, but leave properly

I'm using react-css-transition-replace with a translate transition to slide across the page. Some children appear abruptly without sliding in, but will slide out nicely. The specific elements causing the problem are created with react-rangeslider. I suspect it's something to do with the resize observer, which that library uses to detect size changes on the created elements.

Are there known issues with the resize observer polyfill or window resize event listener and this transition library?

Transition not working with nuka-carousel

Hey @marnusw,

Thanks for your awesome package.
I successfully implemented your project to display transitions between page changes of a wizard.
But as soon as the next page contains a nuka-carousel the transition isn't working correctly. To be more specific, the next page is displayed instantly before the transition of the first one has ende. This way the content overlaps.
Do you have any idea what could cause this misbehaviour?
Just let me know if you need more details.

height is not calculating correctly if children has margin

Not sure if I am missing something, but I am using this package with react-router and pass this:

{React.cloneElement(this.props.children, {key: location.pathname})} to my ReactCSSTransitionReplace element.

In relation, if the root elements of the children routes has margin-top style prop, the transition height is not calculated correctly.

Instead have to use padding-top.

Thanks for great package!

Demo not working?

Hi,

I'm currently experiencing some issues on my project when I have two ReactCSSTransitionReplace in my component. Only the second one is actually working for some unknown reasons...
But I went on the demo page and it seems that none of the examples are working.
Is it correct?

Cheers.

Height will sometimes get stuck at 0 when transitions are interleaved

When switching children really fast (e.g. triggered by a click event), the height of the wrapper element will sometimes get stuck at 0px. I can reproduce this on the samples page:

http://marnusw.github.io/react-css-transition-replace/

Just click the one of the demos as fast as you can for about a minute (I've found the fade out / fade in example to show the bug most consistently). At some point, the content will disappear when I do this.

I've done some debugging and traced the problem to lines 98-102:

// Enqueue setting the next height to trigger the height transition.
this.timeout = setTimeout(() => {
    this.setState({height: this.state.nextChild ? ReactDOM.findDOMNode(this.refs.next).offsetHeight : 0});
    this.timeout = null;
}, TICK);

Changing it like this will fix the problem, but cause occasional glitches which I'm not sure how to fix:

this.timeout = setTimeout(() => {
    const nextNode = ReactDOM.findDOMNode(this.refs.next);
    if (nextNode) {
        this.setState({height: nextChild ? nextNode.offsetHeight : 0});
    }
    this.timeout = null;
}, TICK);

I guess this is related to http://github.com/marnusw/react-css-transition-replace/issues/4.

Update README.md

I've found that it's also possible to use prop transitionAppear={true} to animate element on initial mount. It would be nice to update README.md and inform about this possibility.

Thanks for your library. You did a good job.

3.0.0 changelog/breaking changes?

May you provide a changelog/breaking changes list from 2.0 to 3.0? It's quite difficult to spot the differences otherwise.

Thanks.

Child ref function called again with CSSTransitionGroupChild

Current behavior
The ref function given to the child component is called with both the child component refence and the CSSTransitionGroupChild component.

Expected behavior
The ref function should on be called with the child component.

Steps to reproduce
See the example and console output on https://codesandbox.io/s/5v2nm9zo0l?expanddevtools=1

References
Related issue in react-transition-group can be found at reactjs/react-transition-group#29 (merged fix in reactjs/react-transition-group#39)

container component doesn't keep style prop on replace

      <ReactCSSTransitionReplace
        component='div'
        style={{ overflowY: 'auto' }}
        transitionName={{
          enter: PreviewEnter,
          leave: PreviewLeave
        }}
        transitionEnterTimeout={300}
        transitionLeaveTimeout={300}
      >
        { this.renderPreview() }
      </ReactCSSTransitionReplace>

on first render the inline style css overflow-y: auto is there, but on change of { this.renderPreview() } the outer container's inline style is gone

Remove deprecated componentWillMount and componentWillReceiveProps

This library provides warnings in strict more:

componentWillMount: Please update the following components to use componentDidMount instead: CSSTransitionGroupChild, ReactCSSTransitionReplace

componentWillReceiveProps: Please update the following components to use static getDerivedStateFromProps instead: ReactCSSTransitionReplace

Issue with components that contain inputs

I have a component that when clicking on a button it replaces it with another component that contains a few text inputs.

Every time there's a call the setState the focused input gets blurred.
I've look into a few possible sources for this issue but it seems that if I remove the use of react-css-transition-replace everything seems to be working fine.

Any ideas?
Thanks!

Prop changes doesn't proc rerender inside ReactCSSTransitionReplace children

I'm using ReactCSSTransitionReplace in my application. Function this.getMenu returns a different menu depending on the currentUnit and data and when the menu changes it is animated (this is expected).

return <ReactCSSTransitionReplace
  style={{ height: '100%' }}
  transitionName={this.isSelected() ? slideLeft : slideRight}
  transitionEnterTimeout={400}
  transitionLeaveTimeout={400}
>
  {this.getMenu(this.props.currentUnit, this.props.data)}
</ReactCSSTransitionReplace>

But when I update the currentUnit prop on my component, menus shouldn't change - inside the current menu the highlighted entry should change, but it should not trigger an animation (which is also expected). But the problem is - while the prop successfully propagates inside the getMenu function (when I put a console.log there it receives new prop), the changes doesn't reflect in the browser - nothing changes. It has to be an issue with RCTR because when I remove it, the problem doesn't occur. Maybe it implements sCU somewhere and it doesn't catch the changing prop? Is there a workaround?

Edit 1: The issue is still there in 3.0.1.

No way to pass custom height className

Currently it's not allowed and doesn't work with css-modules.

I'll submit a PR with for it with one of the possible ways to achieve it.

Also, if transitionName is an object, the height className would currently be [object Object]-height, which is not intended, I'm sure.

Problem with overlaying elements

With version 3.0 we're having problems with elements that are overlaying the transitioning elements: The transitioning element is displayed above a pop up, instead of underneath it as in 2.2.1.

Specifically this emitted HTML causes trouble:

<div style="position: relative; overflow: hidden;">
  <span style="position: relative;">
    ...
  </span>
</div>

Removing the style attributes on both elements makes it work again (tested on Chrome 61 and Firefox 55), but I'm guessing this is no option.

This can be seen e.g. here (excuse the certificate error): https://tb.iks.cs.ovgu.de/
After signing in with the default login data, clicking the gravatar in the top bar reveals a dropdown, but the links are not accessible as the greeter, which uses react-css-transition-replace (the white text on black), is overlaying the elements.

Also: we found no way to solve this using z-index.

nextChild span

i can see i'm able to set any component i want, but it seems there's additional wrapper which is by default - span, this is not good in cases where you have div > span > div; or maybe there's a way to set it like componentChild?

Is it working at all?

I npm installed this lib, tried to use according to docs, and got this error:
./~/react-css-transition-replace/lib/ReactCSSTransitionReplaceChild.js Module not found: Error: Can't resolve 'react-transition-group/CSSTransitionGroupChild' in 'C:\Users\PainKiller\Desktop\project\node_modules\react-css-transition-replace\lib'

Animation not working with Redirect components

Animations don't work when using the Redirect component from react-router-dom. The "exiting" component just disappears immediately. Animations work fine with Link components.

Does this library not work correctly with Redirects?

Thank you!

scrollTop gets set to 0 on the leaving component before the animation starts, causing a visual jump

Steps to reproduce:
-- scrollable component, scrolled somewhere "not at the top"
-- any other component
-- place the scrollable component in a reactCSSTransitionReplace component
-- swap out the scrollable component.

Expected:
-- the 'old' scrollable component just animates

Actual:
-- the 'old' scrollable component jumps to scrollTop=0 and then the animation begins

Is there a way to leave the old scrollable component "where it is"?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.