# Stepper

*Display a step-by-step progress indicator with visual feedback. Perfect for wizards, multi-step [forms](../../01_Onboarding/02_Concepts/13_Forms.md), and sequential workflows.*

The `Stepper` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) displays a horizontal sequence of steps with visual indicators showing the current position, completed steps, and upcoming steps. Each step can have a symbol, icon, label, and description.

## Basic Usage

Create a simple stepper with steps:

```csharp
new Stepper(
    null,
    1,
    new StepperItem("1", null, "Step 1", "First step"),
    new StepperItem("2", null, "Step 2", "Second step"),
    new StepperItem("3", null, "Step 3", "Third step")
)
```

The `Stepper` constructor takes three main parameters:

```mermaid
graph LR
    A[Stepper] --> B[onSelect<br/>Event Handler]
    A --> C[selectedIndex<br/>Active Step Index]
    A --> D[items<br/>StepperItem Array]
    B --> B1["null = disabled<br/>handler = enabled"]
    C --> C1["Zero-based index<br/>Controls highlighting"]
    D --> D1["Symbol, Icon<br/>Label, Description"]
```

## Configuration Options

### Allow Forward Selection

Enable `AllowSelectForward` to allow clicking on future steps:

```csharp
public class StepperForwardSelectionDemo : ViewBase
{
    public override object? Build()
    {
        var selectedIndex = UseState(1);
        
        var items = new[]
        {
            new StepperItem("1", null, "Step 1"),
            new StepperItem("2", null, "Step 2"),
            new StepperItem("3", null, "Step 3")
        };
        
        return new Stepper(OnSelect, selectedIndex.Value, items).AllowSelectForward();
        
        ValueTask OnSelect(Event<Stepper, int> e)
        {
            selectedIndex.Set(e.Value);
            return ValueTask.CompletedTask;
        }
    }
}
```

### Dynamic Step States

Update step icons and states based on the current selection:

```csharp
public class StepperDynamicStatesDemo : ViewBase
{
    StepperItem[] GetItems(int selectedIndex) =>
    [
        new("1", selectedIndex > 0 ? Icons.Check : null, "Company", "Setup company"),
        new("2", selectedIndex > 1 ? Icons.Check : null, "Raise", "Raise capital"),
        new("3", null, "Founders", "Add founders"),
    ];
    
    public override object? Build()
    {
        var selectedIndex = UseState(0);
        
        var items = GetItems(selectedIndex.Value);
        
        return Layout.Vertical()
            | new Stepper(OnSelect, selectedIndex.Value, items)
            | (Layout.Horizontal().Gap(0)
                | new Button("Previous").Link().HandleClick(() =>
                {
                    selectedIndex.Set(Math.Clamp(selectedIndex.Value - 1, 0, items.Length - 1));
                })
                | new Button("Next").Link().HandleClick(() =>
                {
                    selectedIndex.Set(Math.Clamp(selectedIndex.Value + 1, 0, items.Length - 1));
                })
            );
        
        ValueTask OnSelect(Event<Stepper, int> e)
        {
            selectedIndex.Set(e.Value);
            return ValueTask.CompletedTask;
        }
    }
}
```


## API

[View Source: Stepper.cs](https://github.com/Ivy-Interactive/Ivy-Framework/blob/main/src/Ivy/Widgets/Primitives/Stepper.cs)

### Constructors

| Signature |
|-----------|
| `new Stepper(Func<Event<Stepper, int>, ValueTask> onSelect, int? selectedIndex, IEnumerable<StepperItem> items)` |


### Properties

| Name | Type | Setters |
|------|------|---------|
| `AllowSelectForward` | `bool` | `AllowSelectForward` |
| `Height` | `Size` | - |
| `Items` | `StepperItem[]` | - |
| `Scale` | `Scale?` | - |
| `SelectedIndex` | `int?` | - |
| `Visible` | `bool` | - |
| `Width` | `Size` | - |


### Events

| Name | Type | Handlers |
|------|------|----------|
| `OnSelect` | `Func<Event<Stepper, int>, ValueTask>` | `HandleSelect` |