# 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>` | - |