Reputation: 9194
I have an error bar that needs to ease-in when error = true
.
In the render()
I have:
render() {
const { errors } = this.props;
return (
<div id='messages'>
<div className={ errors ? 'show-messages' : 'hidden-messages' }>
<Container>{ this.renderMessage() }</Container>
</div>
</div>
)
}
The user tries to login, for example, and if the credentials are bad the server responds which causes this.props.errors
to become true
and show-messages
.
However, I want the bar to ease-in
.
This is the latest CSS I have tried:
.hidden-messages {
visibility: hidden;
transition: width 2s, height 2s;
-webkit-transition: width 2s, height 4s;
transition-delay: 5s;
}
.show-messages {
visibility: visible;
background-color: #FFF;
transition: width 2s, height 2s;
-webkit-transition: width 2s, height 4s;
transition-delay: 5s;
}
Started with just transition:
, but was't getting anywhere. Read somewhere you need to add transition-delay
so tried that and it didn't work.
I think what the issue the ternary is basically an on/off switch and doesn't really establish any kind of relationship between .hidden-messages
and .show-messages
or something. In other words, ease in from what... as far as it knows it has been visible? How do I accomplish this?
EDIT: I tried what Jason McFarlane provided in his CodePen example, and variations of it, and couldn't reproduce the results.
Also, based on the below statement I did modify a few things:
If the state you want is to hide/show then you should toggle a hide or show class on top of the default state.
Example: if your default state is to have the messages shown you always want that class to be on that div.
Since my default state is hide-messages
, I ended up with the below. Also, I did change the ternary in his example from show-messages.hide-messages
to show-messages hide-messages`. I looked at how the DOM was being rendered in the CodePen example, and the latter is how it was changing the class, so I changed to that. Still no luck.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { clearMessages } from '../../actions/messages';
import {
Alert,
Container
} from 'reactstrap';
import styles from '../../../assets/scss/messages.scss';
class Messages extends Component {
constructor(props) {
super(props);
this.state = {
};
this.closeMessage = this.closeMessage.bind(this);
}
closeMessage() {
this.props.clearMessages();
}
renderMessage() {
const { errors } = this.props;
if (errors) {
return (
<Alert color='danger'>
<i onClick={ this.closeMessage } className='float-right fas fa-times'></i>
<span
dangerouslySetInnerHTML={{__html: errors.non_field_errors[0]}}>
</span>
</Alert>
);
}
}
render() {
const { errors } = this.props;
return (
<div id='messages'>
<div className={ errors ? 'hide-messages show-messages' : 'hide-messages' }>
<Container>{ this.renderMessage() }</Container>
</div>
</div>
)
}
}
function mapStateToProps(state) {
return {
errors: state.messages.errors
}
}
export default connect(mapStateToProps, { clearMessages })(Messages);
@import 'declarations';
#messages {
position: relative;
top: 105px;
.hide-messages {
visibility: hidden;
height: 0;
width: 0;
}
.hide-messages.show-messages {
visibility: visible;
background-color: $red;
transition: height 5s ease-in !important;
height: 100%;
width: 100%;
}
.alert-danger {
background-color: $red;
margin-bottom: 0;
border: none;
padding-left: 0;
padding-right: 0;
color: white;
i {
cursor: pointer;
}
}
}
This is what it loos like. So the default is no red banner and it should ease in.
Upvotes: 2
Views: 7745
Reputation: 2175
The ternary is correct as the on off switch but the implementation is where you are facing the issue. On a CSS transition you want a default state and to toggle an additional state on or off of that.
If the state you want is to hide/show then you should toggle a hide or show class on top of the default state.
Example: if your default state is to have the messages shown you always want that class to be on that div.
<div className={ errors ? 'show-messages' : 'show-messages.hide-messages' }>
You are then going to have to change your CSS
.show-messages {
visibility: visible;
transition: height 0.3s ease-in;
height:200px;
width: 200px;
background: #d8d8d8;
}
.show-messages.hide-messages {
visibility: hidden;
height: 0;
width: 0;
}
I created a codepen https://codepen.io/anon/pen/gKmpgw you will have to play around with the CSS attributes you want to animate
Upvotes: 5