1.0.1 • Published 2 years ago

use-steps v1.0.1

Weekly downloads
28
License
MIT
Repository
github
Last release
2 years ago

use-steps npm npm.io

A simple abstraction for complex stepped flows.

npm i use-steps --save

Usage

use-steps only provides logic and (optionally) handles animation timing. You need to bring your own UI.

import React from 'react'
import { useSteps, Step as StepProps } from 'use-steps'

enum StepIds {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three',
  FOUR = 'four',
}

/**
 * These props can be anything, and allow you to type arbitrary data and add it
 * to each step object below.
 */
type StepProps = {
  component: React.ReactNode
}

function Step({ id, active, valid, next, prev, goTo, goPrev, goNext }: StepProps) {
  // maybe handle animations here
  return <div>You're on step: {id}</div>
}

function Steps(props) {
  const [activeStep, setActiveStep] = React.useState(StepIds.ONE)

  const { steps, goTo, goNext, goPrev } = useSteps({
    activeStepId: activeStep,
    activeStepIdSet: setActiveStep,
    steps: [
      {
        id: StepIds.ONE,
        next() {
          return props.someValue ? StepIds.TWO : StepIds.THREE
        },
        // define different components for each step if you want
        component: Step,
      },
      {
        id: StepIds.TWO,
        valid() {
          // guard against reaching this step
          return props.someValue ? true : false
        },
        prev() {
          return StepIds.ONE
        },
        next() {
          return StepIds.THREE
        },
        component: Step,
      },
      {
        id: StepIds.THREE,
        prev() {
          // conditionally set steps
          return props.someValue ? StepIds.TWO : StepIds.ONE
        },
        next() {
          return StepIds.FOUR
        },
        component: Step,
      },
      {
        id: StepIds.FOUR,
        prev() {
          return StepIds.THREE
        },
        component: Step,
      },
    ],
  })

  return (
    <>
      {steps.map((props) => (
        <step.component key={props.id} {...props} />
      ))}

      <button onClick={goPrev}>Prev</button>
      <button onClick={goNext}>Next</button>
    </>
  )
}

Animation

use-steps can help with animations as well. If you provide an animationSpeed value, the library will stagger the value of active to provide time for you to animate your screens in and out. Then, you'll want to use something like react-transition-group or mounty to handle animations.

Here's an example with mounty. Here, you would provide animations styles to .step and .is-active.

import cx from 'classnames'
import { Mounty } from 'mounty'

const animationSpeed = 300 // 300ms

function Steps(props) {
  const [activeStep, setActiveStep] = React.useState(StepIds.ONE)

  const stepper = useSteps({
    animationSpeed,
    activeStepId: activeStep,
    activeStepIdSet: setActiveStep,
    steps: [...]
  })

  return (
    <>
      {steps.map(step => (
        <Mounty key={step.id} in={step.active} timeout={animationSpeed} shouldUnmount>
          {state => {
            return (
              <div className={cx('step', {
                'is-visible': state.ready || state.entering || state.entered
              })}>
                {children}
              </div>
            );
          }}
        </Mounty>
      ))}
    </>
  )
}

License

MIT License © Truework

1.1.0-beta.1

2 years ago

2.0.0-beta.1

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.2.1

4 years ago

0.2.0

4 years ago

0.1.0

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago