## Import

```jsx
import { Stepper } from "@cfa/react-core";
```

## Live Editor

```jsx
function StepperExample() {
  return (
    <Stepper.Root>
      <Stepper.Step content="Step One" state="complete" step={1} />
      <Stepper.Step content="Step Two" state="active" step={2} />
      <Stepper.Step content="Step Three" state="inactive" step={3} />
    </Stepper.Root>
  );
}
```

## Guidelines

### When to use

- Stepper is for a linear multi-step flow, such as onboarding, setup, or a multi-step form, so people can see where they are and what remains.

### Do

- Default to a horizontal layout when horizontal space allows. Use a vertical layout in modals, sidebars, or when steps need descriptions beside each indicator.
- Keep the full step path visible.
- Keep step labels short to avoid truncation or wrapping.
- Announce step changes with an `aria-live` region when the active step updates.

### Avoid

- Using Stepper when people can freely jump between any step without linear progression. Use Tabs.
- Using Stepper for continuous or percentage-based task progress. Use ProgressBar.

## Examples

### Controlled

The primary case may be the use with buttons to navigate between steps, but it can also be used with other components and API calls to change the active step.

We also expose a `useStepState` hook that can control the state for you, as well as provide useful utilities.

Here is an example of a controlled Stepper with buttons to navigate between steps:

```jsx
function ButtonControlledStepper() {
  const { steps, activeStep, decrementStep, incrementStep } = useStepState([
    { label: "Step 1" },
    { label: "Step 2", customField: 10 },
    { label: "Step 3" },
  ]);

  return (
    <>
      <Stepper.Root>
        {steps.map((s, i) => {
          return <Stepper.Step key={i} step={s.step} state={s.state} content={s.label} />;
        })}
      </Stepper.Root>

      <div style={{ display: "flex", gap: 8, marginTop: 32 }}>
        <Button
          size="md"
          onPress={() => decrementStep()}
          isDisabled={activeStep?.step === 1}
          variant="secondary"
        >
          Back
        </Button>
        <Button
          size="md"
          onPress={() => incrementStep()}
          isDisabled={(activeStep?.step ?? 0) >= steps.length}
        >
          Next
        </Button>
      </div>
    </>
  );
}
```

### Orientation

The Stepper can be `"horizontal"` (default) or `"vertical"`, set with the `orientation` prop.

```jsx
function VerticalStepper() {
  return (
    <Stepper.Root orientation="vertical">
      <Stepper.Step content="Step One" state="complete" step={1} />
      <Stepper.Step content="Step Two" state="active" step={2} />
      <Stepper.Step content="Step Three" state="inactive" step={3} />
      <Stepper.Step content="Step Four" state="inactive" step={4} />
    </Stepper.Root>
  );
}
```

### Content

The Stepper can be used to display content for each step. This is useful for multi-step forms or processes where each step has its own content.

There are many different ways you could accomplish this, but one way is to add custom properties into the `useStepState` hook.

Here is an example of a Stepper with content for each step:

```jsx
function ContentStepper() {
  const { steps, activeStep, decrementStep, incrementStep } = useStepState([
    {
      label: "Step 1",
      content: {
        title: "Step 1 Content Heading",
        body: `Lorem ipsum dolor sit amet, consectetur adipiscing elit...`,
      },
    },
    {
      label: "Step 2",
      content: {
        title: "Step 2 Content Heading",
        body: `Ut enim ad minim veniam, quis nostrud exercitation ullamco...`,
      },
    },
    {
      label: "Step 3",
      content: {
        title: "Step 3 Content Heading",
        body: `Duis aute irure dolor in reprehenderit in voluptate velit esse...`,
      },
    },
  ]);

  return (
    <>
      <Stepper.Root>
        {steps.map((s, i) => {
          return <Stepper.Step key={i} step={s.step} state={s.state} content={s.label} />;
        })}
      </Stepper.Root>

      <div style={{ margin: 16 }}>
        <h4>{activeStep?.content.title}</h4>
        <p>{activeStep?.content.body}</p>
      </div>

      <div style={{ display: "flex", gap: 8, marginTop: 32 }}>
        <Button
          size="md"
          onPress={() => decrementStep()}
          isDisabled={activeStep?.step === 1}
          variant="secondary"
        >
          Back
        </Button>
        <Button
          size="md"
          onPress={() => incrementStep()}
          isDisabled={(activeStep?.step ?? 0) >= steps.length}
        >
          Next
        </Button>
      </div>
    </>
  );
}
```

### Children

The `Stepper.Step` component can also accept `children`, however it is important to note that both `children` and `content` props should not be used simultaneously and if they are then the `content` will take precedence.

```jsx
function ChildrenStepper() {
  return (
    <Stepper.Root>
      <Stepper.Step state="complete" step={1}>
        Step One
      </Stepper.Step>
      <Stepper.Step state="active" step={2}>
        Step Two
      </Stepper.Step>
      <Stepper.Step state="inactive" step={3}>
        Step Three
      </Stepper.Step>
    </Stepper.Root>
  );
}
```

## Props

### Stepper.Root

| Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| children\* | `ReactNode` | - | The content of the Stepper (or the StepperStep). |
| aria-describedby | `string` | - | Identifies the element (or elements) that describes the object. |
| aria-details | `string` | - | Identifies the element (or elements) that provide a detailed, extended description for the object. |
| aria-label | `string` | - | Defines a string value that labels the current element. |
| aria-labelledby | `string` | - | Identifies the element (or elements) that labels the current element. |
| className | `string` | - | CSS class names to apply custom styling. |
| id | `string` | - | The unique identifier for the DOM element. |
| orientation | `"horizontal" \ | "vertical"` | `horizontal` | The orientation of the Stepper. |
| role | `AriaRole` | - | The ARIA role assigned to the element to improve accessibility. Example roles include "button", "navigation", "dialog", etc. |
| style | `CSSProperties` | - | Inline styles specified as a React-compatible CSS properties object. |

### Stepper.Step

| Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| step\* | `number` | - | - |
| children | `ReactNode` | - | The content or child elements nested within this component. |
| className | `string` | - | CSS class names to apply custom styling. |
| content | `string` | - | - |
| id | `string` | - | The unique identifier for the DOM element. |
| role | `AriaRole` | - | The ARIA role assigned to the element to improve accessibility. Example roles include "button", "navigation", "dialog", etc. |
| state | `StepperStepState` | `inactive` | - |
| style | `CSSProperties` | - | Inline styles specified as a React-compatible CSS properties object. |
| key | `Key \ | null` | - | - |
| ref | `Ref<HTMLLIElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set \`ref.current\` to \`null\` (or call the ref with \`null\` if you passed a callback ref).&#xA;@see \{@link https\://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |