Using React-Transition-Group, how can I create a sliding wizard?

118
February 27, 2022, at 05:30 AM

I'm having a bit of trouble with React-Transition-Group, it's been a couple of years since I last had to work with it.

Right now I'm working on a wizard widget for our group's app, basically asking yes-or-no questions and then transitioning to the next one. I do have a fading transition that works, but it would be better if I could somehow get a sliding transition, which (when the user answers yes or no), slides out the old slide, and slides in the new slide.

Here's my (simplified) WORKING code for fading:


const cssWidgetSlide = css`
  .widget-slide {
    transition: opacity ${DURATION_MS}ms ease-in;
  }
  .widget-slide-entering {
    opacity: 0;
  }
  .widget-slide-entered {
    opacity: 1;
  }
  .widget-slide-exiting {
    opacity: 0;
  }
  .widget-slide-exited {
    opacity: 1;
  }
`;

export const EnergyBillWidget = () => {
  const [slide, setSlide] = useState(0);
  const [inProp, setInProp] = useState(false);
  const totalSlides = 3;
  const animateIncrement = useCallback(
    (amount: number) => () => {
      setInProp(true);
      const tm = setTimeout(() => {
        setSlide(slide => {
          if (slide + amount < totalSlides - 1) {
            return slide + amount;
          }
          return slide;
        });
        setInProp(false);
      }, DURATION_MS);
      return () => clearTimeout(tm);
    },
    []
  );
  const listOfSlides = [
    <EnergySupplierBustSlide onYes={animateIncrement(2)} onNo={animateIncrement(1)} key="bust" />,
    <EnergySupplierSwitchSlide onNext={animateIncrement(1)} key="switch" />,
    <EnergySupplierCostSlide onNext={animateIncrement(1)} key="cost" />,
  ];
  return (
    <EnergyBillProvider>
      <style>{cssWidgetSlide}</style>
      <StyledShadowBox>
          <StyledDisplayArea>
            <Transition in={inProp} timeout={DURATION_MS}>
              {state => (
                <div className={`widget-slide widget-slide-${state}`}>{listOfSlides[slide]}</div>
              )}
            </Transition>
          </StyledDisplayArea>
      </StyledShadowBox>
    </EnergyBillProvider>
  );
};

Here's my FAILING code for the slide transition:


const cssSlideTransition = css`
  .widget-slider {
    transform: translate3d(0, 0, 0);
    z-index: 5;
    transition: all ${DURATION_MS}ms ease-in-out;
  }
  .widget-slider-enter {
    transform: translate3d(100%, 0, 0);
  }
  .widget-slider-enter-active {
    transform: translate3d(0, 0, 0);
  }
  .widget-slider-exit {
    transform: translate3d(0, 0, 0);
  }
  .widget-slider-exit-active {
    transform: translate3d(-100%, 0, 0);
  }
`;
export const EnergyBillWidget = () => {
  const [slide, setSlide] = useState(0);
  const [accordionIsOpen, setAccordionIsOpen] = useState(false);
  const totalSlides = 3;
  const animateIncrement = useCallback(
    (amount = 1) => () => {
      const tm = setTimeout(() => {
        setSlide(slide => {
          if (slide + amount < totalSlides) {
            return slide + amount;
          }
          return slide;
        });
      }, DURATION_MS);
      return () => clearTimeout(tm);
    },
    []
  );
  const listOfSlides = [
    () => (
      <EnergySupplierBustSlide onYes={animateIncrement(2)} onNo={animateIncrement(1)} key="bust" />
    ),
    () => <EnergySupplierSwitchSlide onNext={animateIncrement(1)} key="switch" />,
    () => <EnergySupplierCostSlide onNext={animateIncrement(1)} key="cost" />,
  ];
  return (
    <EnergyBillProvider>
      <style>{cssSlideTransition}</style>
      <StyledShadowBox>
        
          <TransitionGroup component={null}>
            <div>
              {listOfSlides.map((Component, index) => (
                <CSSTransition
                  key={`slide-${index}`}
                  timeout={DURATION_MS}
                  classNames="widget-slider"
                >
                  <div>{slide === index ? <Component /> : null}</div>
                </CSSTransition>
              ))}
            </div>
          </TransitionGroup>
       
      </StyledShadowBox>
    </EnergyBillProvider>
  );
};

I suspect what I need might not be TransitionGroup but rather SwitchTransition -- but at any rate, it's not really working either way.

Rent Charter Buses Company
READ ALSO
How to position content beside sidebar?

How to position content beside sidebar?

I am not very well versed in HTML and CSSI am currently building a web application using Django and I integrated a sidebar into my web application using Bootstrap, but it has messed my layouts, and I can't seem to figure out how to move the content in a block to the left of side of my sidebar

115
Changing Color of Text Based on Variable

Changing Color of Text Based on Variable

Trying to make a simple increase/decrease counterWhen var n is < 0 it changes to red, and same for ==, but when its greater than it stays black

145
Track position and changing css style

Track position and changing css style

How do you calculate opacity from 0 to 1 depending on the scroll for text elements?

120
TailwindCSS: Combining 2 transitions properties

TailwindCSS: Combining 2 transitions properties

I wanna have transition-transform and transition-shadow, not neither transition-all nor only onePutting the two not effecting, i couldn't find doc for it, i tried playing around like: transition-[transform, shadow] and obviously didn't work

167