# Prompts

*Interact with users and gather input using Ivy's [alert](./17_Alerts.md) and [dialog](../../02_Widgets/03_Common/15_Dialog.md) system.*

## Basic Usage

Here's a simple example using [UseAlert](./17_Alerts.md), [Layout](./04_Layout.md), and [Button](../../02_Widgets/03_Common/01_Button.md) to show a confirmation alert:

```csharp
public class BasicPromptView : ViewBase
{
    public override object? Build()
    {
        var (alertView, showAlert) = UseAlert();
        var client = UseService<IClientProvider>();
        
        return Layout.Vertical(
            new Button("Delete Item", onClick: _ =>
            {
                showAlert("Are you sure you want to delete this item?", result =>
                {
                    if (result == AlertResult.Ok)
                    {
                        // Item would be deleted here
                        client.Toast("Item deleted!", "Success");
                    }
                }, "Delete Item");
            }),
            alertView
        );
    }
}
```

```mermaid
flowchart LR
    A[User Action] --> B{Input Type}
    B -->|Confirm| C[UseAlert<br/>showAlert]
    B -->|Text| D[Form.ToDialog]
    B -->|Multiple| E[Custom Form<br/>ToDialog]
    B -->|Chain| F[Alert → Alert]
    C --> G[AlertResult]
    D --> H[Form Submit]
    E --> H
    F --> G
```

### Text Input Prompts

Collect text input from users using dialogs with [forms](./08_Forms.md):

```csharp
public record RenameRequest
{
    public string Name { get; set; } = "Current Item Name";
}

public class RenameView : ViewBase
{
    public override object? Build()
    {
        var client = UseService<IClientProvider>();
        var isOpen = UseState(false);
        var renameData = UseState(new RenameRequest());
        
        UseEffect(() => {
            if (!isOpen.Value && !string.IsNullOrEmpty(renameData.Value.Name))
            {
                // Item would be renamed here
                client.Toast($"Renamed to: {renameData.Value.Name}", "Success");
            }
        }, [isOpen]);
        
        return Layout.Vertical(
            new Button(
                "Rename",
                onClick: _ => isOpen.Set(true)
            ),
            isOpen.Value ? renameData.ToForm()
                .Label(e => e.Name, "Enter new name:")
                .ToDialog(isOpen, 
                    title: "Rename Item", 
                    submitTitle: "Rename"
                ) : null
        );
    }
}
```

### Custom Prompts

Create custom dialogs with multiple inputs:

```csharp
public record CustomOptions
{
    public bool Option1 { get; set; }
    public bool Option2 { get; set; }
    public string CustomText { get; set; } = "";
}

public class CustomPromptView : ViewBase
{
    public override object? Build()
    {
        var client = UseService<IClientProvider>();
        var isOpen = UseState(false);
        var options = UseState(new CustomOptions());
        
        UseEffect(() => {
            if (!isOpen.Value && (options.Value.Option1 || options.Value.Option2 || !string.IsNullOrEmpty(options.Value.CustomText)))
            {
                // Options would be saved here
                client.Toast("Options saved!", "Success");
            }
        }, [isOpen]);
        
        return Layout.Vertical(
            new Button(
                "Custom Prompt",
                onClick: _ => isOpen.Set(true)
            ),
            isOpen.Value ? options.ToForm()
                .Builder(e => e.Option1, e => e.ToBoolInput("Option 1"))
                .Builder(e => e.Option2, e => e.ToBoolInput("Option 2"))
                .Builder(e => e.CustomText, e => e.ToTextInput("Custom text"))
                .ToDialog(isOpen, 
                    title: "Select Options", 
                    submitTitle: "Save"
                ) : null
        );
    }
}
```

## Examples


### Confirmation with Custom Options

```csharp
public record DeleteOptions
{
    public bool DeleteAssociatedFiles { get; set; }
    public bool ArchiveInsteadOfDelete { get; set; }
    public string ReasonForDeletion { get; set; } = "";
}

public class DeleteWithOptionsView : ViewBase
{
    public override object? Build()
    {
        var (alertView, showAlert) = UseAlert();
        var client = UseService<IClientProvider>();
        var isOptionsOpen = UseState(false);
        var deleteOptions = UseState(new DeleteOptions());
        
        UseEffect(() => {
            if (!isOptionsOpen.Value && (deleteOptions.Value.DeleteAssociatedFiles || deleteOptions.Value.ArchiveInsteadOfDelete || !string.IsNullOrEmpty(deleteOptions.Value.ReasonForDeletion)))
            {
                // Deletion with options would be performed here
                client.Toast("Item deleted with custom options", "Success");
            }
        }, [isOptionsOpen]);
        
        return Layout.Vertical(
            new Button(
                "Delete with Options",
                onClick: _ => {
                    showAlert(
                        "This will permanently delete the item. Do you want to configure deletion options?",
                        result => {
                            if (result == AlertResult.Yes)
                            {
                                isOptionsOpen.Set(true);
                            }
                            else if (result == AlertResult.No)
                            {
                                // Simple delete without options
                                client.Toast("Item deleted", "Success");
                            }
                        },
                        "Delete Options",
                        AlertButtonSet.YesNoCancel
                    );
                }
            ).Destructive(),
            alertView,
            isOptionsOpen.Value ? deleteOptions.ToForm()
                .Builder(e => e.DeleteAssociatedFiles, e => e.ToBoolInput("Delete associated files"))
                .Builder(e => e.ArchiveInsteadOfDelete, e => e.ToBoolInput("Archive instead of delete"))
                .Builder(e => e.ReasonForDeletion, e => e.ToTextInput("Reason for deletion"))
                .ToDialog(isOptionsOpen, 
                    title: "Delete Options", 
                    submitTitle: "Delete"
                ) : null
        );
    }
}
```