# FeedbackInput

*Collect user feedback with combined rating and comment inputs, perfect for surveys, reviews, and [feedback forms](../../01_Onboarding/02_Concepts/08_Forms.md).*

The `FeedbackInput` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) provides a specialized input for collecting user feedback. It typically includes rating options and a text field for comments, making it ideal for surveys, reviews, and feedback forms.

## Basic Usage

Here's a simple example of a `FeedbackInput` with the default `Stars` variant:

```csharp
public class BasicFeedbackDemo : ViewBase
{    
    public override object? Build()
    {    
        var rating = UseState(3);
        return new FeedbackInput<int>(rating);
    }
}    
```

## Variants

`FeedbackInput`s come in several variants to suit different use cases:
 For star style feedback ( 1 star to 5 stars) the variant `FeedbackInputs.Stars` should be used.
 For binary style feedback ( yes, no, liked/disliked, recommended/not-recommended) type feedback
 the variant `FeedbackInputs.Thumbs` should be used. `FeedbackInputs.Emojis` should be used
 for collecting sentiment analysis feedbacks about anything.

```csharp
public class FeedbackDemo : ViewBase
{
    public override object? Build()
    {    
        // Initial guess feedbacks 
        var starFeedback = UseState(3);
        var thumbsFeedback = UseState(true);
        var emojiFeedback = UseState(4);
        return Layout.Vertical()
                | H3 ("Simple movie review")
                | new FeedbackInput<bool>(thumbsFeedback)
                      .Variant(FeedbackInputs.Thumbs)
                      .WithField()
                      .Label("Did you like the movie ?")
                | new FeedbackInput<int>(starFeedback)
                      .Variant(FeedbackInputs.Stars)
                      .WithField()
                      .Label("How would you like to rate the movie ?")
                | new FeedbackInput<int>(emojiFeedback)
                      .Variant(FeedbackInputs.Emojis)
                      .WithField()
                      .Label("How do you feel after seeing the movie ?");
    }  
}    
```

## Event Handling

The following example shows how change events can be handled for `FeedbackInput`s.

```csharp
public class FeedbackHandling: ViewBase
{    
    public override object? Build()
    {    
        var feedbackState = UseState(1);
        var exclamation = UseState("");
        exclamation.Set(feedbackState.Value switch
        {
            0 => "No rating yet",
            1 => "Seriously?",
            2 => "Oh! is it that bad?",
            3 => "Ah! you almost liked it!",
            4 => "Cool! Tell me more!",
            5 => "WOW! Would you recommend it?",
            _ => "Invalid rating"
        });
        return Layout.Vertical() 
                | new FeedbackInput<int>(feedbackState)
                | Text.Block(exclamation);
    }    
}
```

## Styling and Customization

`FeedbackInput`s can be customized with various styling options, including `Disabled` and `Invalid` states:

```csharp
public class StyledFeedbackDemo : ViewBase
{
    public override object? Build()
    {    
        var state = UseState(3);
        return Layout.Vertical()
                | new FeedbackInput<int>(state)
                      .Disabled()
                      .WithField().Label("Disabled")
                | new FeedbackInput<int>(state)
                      .Invalid("Validation error")
                      .WithField().Label("Invalid");
    }
}        
```


## API

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

### Constructors

| Signature |
|-----------|
| `new FeedbackInput<TNumber>(IAnyState state, string placeholder = null, bool disabled = false, FeedbackInputs variant = FeedbackInputs.Stars)` |
| `new FeedbackInput<TNumber>(TNumber value, Func<Event<IInput<TNumber>, TNumber>, ValueTask> onChange, string placeholder = null, bool disabled = false, FeedbackInputs variant = FeedbackInputs.Stars)` |
| `new FeedbackInput<TNumber>(TNumber value, Action<TNumber> state, string placeholder = null, bool disabled = false, FeedbackInputs variant = FeedbackInputs.Stars)` |
| `new FeedbackInput<TNumber>(string placeholder = null, bool disabled = false, FeedbackInputs variant = FeedbackInputs.Stars)` |
| `ToFeedbackInput(IAnyState state, string placeholder = null, bool disabled = false, FeedbackInputs? variant = null)` |


### Supported Types

| Group | Type | Nullable |
|-------|------|----------|
| Boolean | `bool` | `bool?` |
| Numeric | `int` | `int?` |


### Properties

| Name | Type | Setters |
|------|------|---------|
| `Disabled` | `bool` | `Disabled` |
| `Height` | `Size` | - |
| `Invalid` | `string` | `Invalid` |
| `Nullable` | `bool` | `Nullable` |
| `Placeholder` | `string` | `Placeholder` |
| `Scale` | `Scale?` | - |
| `Value` | `TNumber` | - |
| `Variant` | `FeedbackInputs` | `Variant` |
| `Visible` | `bool` | - |
| `Width` | `Size` | - |


### Events

| Name | Type | Handlers |
|------|------|----------|
| `OnBlur` | `Func<Event<IAnyInput>, ValueTask>` | `HandleBlur` |
| `OnChange` | `Func<Event<IInput<TNumber>, TNumber>, ValueTask>` | - |