openedx / wg-frontend

Open edX Frontend Working Group
4 stars 1 forks source link

Add documentation example of showing a step in an error state #51

Closed adamstankiewicz closed 2 years ago

adamstankiewicz commented 2 years ago

Paragon ticket: https://openedx.atlassian.net/browse/PAR-638

Description

On the existing documentation for Stepper, there is no indication that a step may be configured to be in an error state, unless you realize that by looking at the props API and/or the Figma spec.

image

AC

bseverino commented 2 years ago

Wanted to note before I forget: while working on this, I noticed a bug. If a step is updated, it seems to get deleted and readded to the end of the list. So if the first step here enters an error state:

Screen Shot 2022-01-13 at 10 01 02 AM

The offending step gets sent to the end of the list instead of holding its place:

Screen Shot 2022-01-13 at 10 01 14 AM

Looking through our codebase, the only place we're using this is in the course authoring MFE, but it's only possible to enter an error state on the last step of the component, so the order wouldn't matter.

I believe this is the line that's causing it but I haven't had a chance to test out a fix yet: https://github.com/openedx/paragon/blob/master/src/Stepper/StepperStep.jsx#L23

bseverino commented 2 years ago

^ snippet for the example above:

() => {
  const steps = ['checkbox', 'success'];
  const [currentStep, setCurrentStep] = useState(steps[0]);
  const [isChecked, check, uncheck, toggleChecked] = useToggle(false);
  const [hasError, setError, removeError] = useToggle(false);

  const evaluateCheckbox = () => {
    if (isChecked) {
      removeError();
      setCurrentStep('success');
    } else {
      setError();
    }
  };

  const resetCheckbox = () => {
    uncheck();
    removeError();
  };

  return (
    <Stepper activeKey={currentStep}>
      <Stepper.Header />

      <Container size="sm" className="py-5">
        <Stepper.Step
          eventKey="checkbox"
          title="Check the Box"
          description={hasError ? 'Please check the box to continue.' : ''}
          hasError={hasError}
        >
          <h2>Check the box</h2>
          <Form.Checkbox checked={isChecked} onChange={toggleChecked}>
            Check me!
          </Form.Checkbox>
        </Stepper.Step>

        <Stepper.Step eventKey="success" title="Success!">
          <h2>Success!</h2>
          <p>You may now complete this demo.</p>
        </Stepper.Step>
      </Container>

      <div className="py-3">
        <Stepper.ActionRow eventKey="checkbox">
          <Button variant="outline-primary" onClick={resetCheckbox}>
            Cancel
          </Button>
          <Stepper.ActionRow.Spacer />
          <Button onClick={() => evaluateCheckbox()}>Next</Button>
        </Stepper.ActionRow>

        <Stepper.ActionRow eventKey="success">
          <Button variant="outline-primary" onClick={() => setCurrentStep('checkbox')}>
            Previous
          </Button>
          <Stepper.ActionRow.Spacer />
          <Button onClick={() => alert('Completed')}>Complete</Button>
        </Stepper.ActionRow>
      </div>
    </Stepper>
  )
}