react-transition-group icon indicating copy to clipboard operation
react-transition-group copied to clipboard

SwitchTransition with "out-in" and possible null item?

Open simonhrogers opened this issue 1 year ago • 1 comments

I’d like to transition a group of elements with mode="out-in", but there will often be no element to display.

What is the correct way to accommodate for the possibility of no element? I’ve tried doing it like so below, which was working well but of course from the "empty" element you actually need to switch the transition mode to "in-out", or there will be a 500ms delay while the empty element is transitioned out. This looks weird!

So I thought I could change the transition mode below, by setting previousActiveProject in state, but changing the transition mode occasionally seems to yield no transition being run at all – the element will just disappear immediately with no fade.

Thanks so much for any help on this!

<div className={`index-section-item-image index-section-item-project-image`}>
  <SwitchTransition mode={previousActiveProject ? "out-in" : "in-out"}>
    <CSSTransition
      key={!activeProject || isScrolling ? 'empty' : activeProject._id}
      addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
      classNames='fade'
    >
      {!activeProject || isScrolling ? (
        <div className="empty"></div>
      ) : (
        <SanityImage
          key={`${activeProject._id}-image`}
          image={activeProject.image}
          sizes={['25vw','25vw','25vw','25vw']}
        />
      )}
    </CSSTransition>
  </SwitchTransition>
</div>

simonhrogers avatar Jan 05 '23 19:01 simonhrogers

This was how I handled my case which is slightly different than yours, I know which thing is being hovered and if it's being hovered or not.

<SwitchTransition mode="out-in">
  {/* This is required to not leave an always showing card... stupid... */}
  {isProductHovered ? (
    <CSSTransition key={product.id} timeout={300} classNames="fade">
      <div className={`product-info`}>
        <div className="product-info__content">
          <div className="product-info__image">
            <img src={product.featuredImage} alt={product.title} />
          </div>
          <div className="product-info__name">{product.title}</div>
          <div className="product-info__description">
            {product.description}
          </div>
        </div>
      </div>
    </CSSTransition>
  ) : (
    <CSSTransition key="empty" timeout={300} classNames="fade">
      <div> </div>
    </CSSTransition>
  )}
</SwitchTransition>

SeedyROM avatar Feb 05 '24 22:02 SeedyROM