简体   繁体   中英

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

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;
}

Change

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

To

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

and it should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM