Dan
Dan

Reputation: 789

Decide order of CSS Transitions

Funky problem i'm having, although i bet theres a slick way to solve it.

The circumstance is that i have a table that has three column sort states: completely unsorted, in which case i dont want any icon present, sorted ascending, in which i want an up arrow, and sorted descending, in which i want a down arrow.

clicking the column header should take you through these three states.

starts off => click => ascending => click => descending => click => back to off

This all works fine and dandy, except for the fact that i want to use the same Caret element, and then use css transition's to fade it in from opacity: 0 to opacity: 1 , then on click rotate it 180deg to show a down arrow for descending, then finally when clicked again to remove the sort, i want it to fade out WITHOUT ROTATING BACK TO 0 DEG

That last part is where the problem lies.

EDIT

I have only recreated the behavior in the sandbox, but i am really using react-table, so there are only three possible states since it is controlled by the package:

initial state: {showCaret: false, flipped: false}
first click: {showCaret: true, flipped: false}
second click: {showCaret: true, flipped: true}
third click, back to initial: {showCaret: false, flipped: false}

the state changes are controlled by react-table, so i cant setTimeout on the flipped variable.

I am looking for a purely CSS way to achieve this goal without manipulating the way the state changes, if possible

END EDIT

I've attached a codesandbox to demonstrate. First click Show Caret, then Flip Caret, then Hide Caret. The css is set up basically the same as mine is currently in my actual project too.

https://codesandbox.io/embed/admiring-rain-svsc9?fontsize=14&hidenavigation=1&theme=dark

Upvotes: 0

Views: 221

Answers (2)

tmdesigned
tmdesigned

Reputation: 2254

It sounds like what you want is for the arrow to disappear, but not to rotate back to its starting orientation as it disappears.

Since you are handling and tracking all this with React state, you could just set those two states separately, timed .3s apart (since that is your CSS transition time).

You could do this in a number of ways. To demonstrate it, in this fork of your example I have you just setting the on/off visibility to off, and then separately, in componentDidUpdate, I have it watching for whenever it's turned off, at which point it waits 300ms (.3s) and then sets the rotate state back.

componentDidUpdate(oldProps, oldState) {
    if (oldState.showCaret && !this.state.showCaret) {
      //it was just hidden
      setTimeout(() => {
        this.setState({
          flipped: false
        });
      }, 300);
    }
}

https://codesandbox.io/s/sparkling-pine-9igec

EDIT, with CSS only solution

https://codesandbox.io/s/pensive-wilbur-opxzf

/* flipped taking care of rotating the img tag */
.image {
  transition: transform 0.3s linear 2s;
}
.flipped {
  transform: rotate(180deg);
  transition: transform 0.3s;
}

Upvotes: 1

Ricardo Pierre-Louis
Ricardo Pierre-Louis

Reputation: 184

Change


    onClick={() => this.setState({ showCaret: false, flipped: false })}

To


    onClick={() => this.setState({ showCaret: false })}

and it should work.

Upvotes: 0

Related Questions