americanexpress / react-albus

✨ React component library for building declarative multi-step flows.
Apache License 2.0
1.1k stars 89 forks source link

Go to step #22

Closed exdeniz closed 4 years ago

exdeniz commented 6 years ago

How to do on click go to step by id?

jackjocross commented 6 years ago

@exdeniz you should be able to use the push function to go to a step by id.

const GoToStepById = () => (
  <Wizard>
    <Steps>
      <Step
        id="merlin"
        render={({ next }) => (
          <div>
            <h1>Merlin</h1>
            <button onClick={next}>Next</button>
          </div>
        )}
      />
      <Step
        id="gandalf"
        render={({ push }) => (
          <div>
            <h1>Gandalf</h1>
            <button onClick={() => push('merlin')}>Merlin</button>
          </div>
        )}
      />
    </Steps>
  </Wizard>
);
meymeynard commented 6 years ago

Hello. Would like to ask a follow up question. Is it possible to go to a specific step upon page load? Thanks!

nathanforce commented 6 years ago

@meymeynard If I remember correctly you should be able to use onNext for this. A bit of a misnamed prop but anyhow..

 <Wizard
    onNext={({ step, push }) => {
      if (!step.id) {
        push("gandalf");
      }
    }}
  >
meymeynard commented 6 years ago

@nathanforce as far as I know, onNext is triggered when clicking the Next button, right?

jackjocross commented 6 years ago

onNext is also called with { step: { id: null } } on first mount so that you can do what @nathanforce shared and start at a specific step.

sanjesh commented 6 years ago

@exdeniz you should be able to use the push function to go to a step by id.

const GoToStepById = () => (
  <Wizard>
    <Steps>
      <Step
        id="merlin"
        render={({ next }) => (
          <div>
            <h1>Merlin</h1>
            <button onClick={next}>Next</button>
          </div>
        )}
      />
      <Step
        id="gandalf"
        render={({ push }) => (
          <div>
            <h1>Gandalf</h1>
            <button onClick={() => push('merlin')}>Merlin</button>
          </div>
        )}
      />
    </Steps>
  </Wizard>
);

TL;DR: If step order has to be retained when jumping steps then next and prev should not be used.

@crosscompile This works. but functionality of next and previous gets messed up. ie, if you have 5 steps and you jumped 2nd step using push, then prev will take you to 5th step and not 1st. This might be intended by the makers of library Im not sure.

joaomantovani commented 4 years ago

I'm posting my code if someone needs this.

The lastStep is a variable on localStorage, everytime the page is changed, I update this variable on localStorage with the actual step. All my <Step id /> are numeric and on a logic sequence, so it's possible to this logic

const handleStepChange = (step, push) => {
    const isOnFirstLoad = !step.id
    if (isOnFirstLoad) {
      push(`${lastStep}`)
    } else {
      const nextStep = lastStep + 1
      push(`${nextStep}`)
      setLastStep(nextStep)
    }
  }

  return (
    <>
      <GlobalStyle />

      <Wizard
        onNext={({ step, push }) => handleStepChange(step, push)}
        render={({ step, steps }) => {
          return (
            <>
              <Steps>
                <Step id='1' render={({ next }) => <Step1 next={next} />} />
                <Step id='2' render={({ next }) => <Step2 next={next} />} />
                <Step id='3' render={({ next }) => <Step3 next={next} />} />
                <Step id='4' render={({ next }) => <Step4 next={next} />} />
                <Step id='5' render={({ next }) => <Step5 next={next} />} />
                <Step id='6' render={({ next }) => <Step6 next={next} />} />
                <Step id='7' render={({ next }) => <Step7 next={next} />} />
                <Step id='8' render={({ next }) => <Step8 next={next} />} />
              </Steps>
            </>
          )
        }}
      />
    </>
  )