# ColorInput
*Select colors visually with an intuitive color picker [interface](../../01_Onboarding/02_Concepts/02_Views.md) that returns values suitable for [styling](../../01_Onboarding/02_Concepts/02_Views.md) and [theming](../../01_Onboarding/02_Concepts/12_Theming.md) applications.*
The `ColorInput` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) provides a color picker interface for selecting color values. It allows users to visually choose colors and returns the selected color in a format suitable for use in styles and [themes](../../01_Onboarding/02_Concepts/12_Theming.md).
## Basic Usage
Here's a simple example of a `ColorInput` that updates a [state](../../03_Hooks/02_Core/03_UseState.md) with the selected color:
```csharp
public class ColorDemo : ViewBase
{
public override object? Build()
{
var colorState = UseState("#ff0000");
return colorState.ToColorInput();
}
}
```
### Using the Non-Generic Constructor
For convenience, you can create a `ColorInput` without specifying the generic type, which defaults to `string`:
```csharp
// Using the non-generic constructor (defaults to string)
var colorInput = new ColorInput();
// With placeholder
var colorInputWithPlaceholder = new ColorInput("Choose a color");
// With all options
var colorInputFull = new ColorInput(
placeholder: "Select your favorite color",
disabled: false,
variant: ColorInputs.TextAndPicker
);
```
## Variants
`ColorInput` has four variants:
| Variant | Description |
|---------|-------------|
| `ColorInputs.Text` | Text input for entering hex codes manually |
| `ColorInputs.Picker` | Color picker only |
| `ColorInputs.TextAndPicker` | Text input with color picker (default) |
| `ColorInputs.Swatch` | Grid of predefined colors from `Colors` enum |
The following code shows all variants in action:
```csharp
public class ColorVariantsDemo : ViewBase
{
public override object? Build()
{
var colorState = UseState("red");
return Layout.Grid().Columns(2).ColumnWidths(Size.Units(30), null)
| Text.P("Just Text").Small() | colorState.ToColorInput().Variant(ColorInputs.Text)
| Text.P("Just Picker").Small() | colorState.ToColorInput().Variant(ColorInputs.Picker)
| Text.P("Text and Picker").Small() | colorState.ToColorInput().Variant(ColorInputs.TextAndPicker)
| Text.P("Swatch").Small() | colorState.ToColorInput().Variant(ColorInputs.Swatch);
}
}
```
### Swatch Variant
The `Swatch` variant displays a grid of predefined colors from the `Colors` enum. This is useful when you want users to select from a specific set of theme-aware colors rather than arbitrary hex values.
```csharp
public class ColorSwatchDemo : ViewBase
{
public override object? Build()
{
var colorState = UseState(Colors.Blue);
return Layout.Vertical()
| colorState.ToColorInput().Variant(ColorInputs.Swatch)
| Text.P($"Selected: {colorState.Value}");
}
}
```
## Event Handling
ColorInput can handle change events using the `onChange` parameter.
The following demo shows how the `Picker` variant can be used with a code
block so that
```csharp
public class ColorChangedDemo : ViewBase
{
public override object? Build()
{
var colorState = UseState("#ff0000");
var colorName = UseState(colorState.Value);
var onChangeHandler = (Event<IInput<string>, string> e) =>
{
colorName.Set(e.Value);
colorState.Set(e.Value);
};
return Layout.Vertical()
| H3("Hex Color Picker")
| (Layout.Horizontal()
| new ColorInput<string>
(colorState.Value, onChangeHandler)
.Variant(ColorInputs.Picker)
| new CodeBlock(colorName.Value)
.ShowCopyButton()
.ShowBorder());
}
}
```
## Styling
`ColorInput` can be customized with various styling options, such as setting a placeholder or disabling the input.
```csharp
public class ColorStylingDemo : ViewBase
{
public override object? Build()
{
var colorState = UseState("#ff0000");
return Layout.Grid().Columns(2).ColumnWidths(Size.Units(30), null)
| Text.P("Disabled").Small() | colorState.ToColorInput().Disabled()
| Text.P("Invalid").Small() | colorState.ToColorInput().Invalid("Invalid color value");
}
}
```
## API
[View Source: ColorInput.cs](https://github.com/Ivy-Interactive/Ivy-Framework/blob/main/src/Ivy/Widgets/Inputs/ColorInput.cs)
### Constructors
| Signature |
|-----------|
| `new ColorInput(IAnyState state, string placeholder = null, bool disabled = false, ColorInputs variant = ColorInputs.TextAndPicker)` |
| `new ColorInput(string value, Func<Event<IInput<string>, string>, ValueTask> onChange, string placeholder = null, bool disabled = false, ColorInputs variant = ColorInputs.TextAndPicker)` |
| `new ColorInput(string value, Action<Event<IInput<string>, string>> onChange, string placeholder = null, bool disabled = false, ColorInputs variant = ColorInputs.TextAndPicker)` |
| `new ColorInput(string placeholder = null, bool disabled = false, ColorInputs variant = ColorInputs.TextAndPicker)` |
| `ToColorInput(IAnyState state, string placeholder = null, bool disabled = false, ColorInputs? variant = null)` |
### Supported Types
| Group | Type | Nullable |
|-------|------|----------|
| Text | `string` | - |
| Enum | `Colors` | `Colors?` |
### Properties
| Name | Type | Setters |
|------|------|---------|
| `Disabled` | `bool` | `Disabled` |
| `Foreground` | `bool?` | `Foreground` |
| `Height` | `Size` | - |
| `Invalid` | `string` | `Invalid` |
| `Nullable` | `bool` | `Nullable` |
| `Placeholder` | `string` | `Placeholder` |
| `Scale` | `Scale?` | - |
| `Value` | `string` | - |
| `Variant` | `ColorInputs` | `Variant` |
| `Visible` | `bool` | - |
| `Width` | `Size` | - |
### Events
| Name | Type | Handlers |
|------|------|----------|
| `OnBlur` | `Func<Event<IAnyInput>, ValueTask>` | `HandleBlur` |
| `OnChange` | `Func<Event<IInput<string>, string>, ValueTask>` | - |
## Examples
### ColorPicker control can be used in a developer tool setting that generates CSS blocks.
```csharp
public class CSSColorDemo : ViewBase
{
public override object? Build()
{
var color = UseState("#333333");
var bgColor = UseState("#F5F5F5");
var border = UseState("#CCCCCC");
var template = """
.my-element {
color: [COLOR];
background-color: [BG_COLOR];
border: 1px solid [BORDER];
}
""";
var genCode = UseState("");
genCode.Set(template.Replace("[COLOR]",color.Value)
.Replace("[BG_COLOR]",bgColor.Value)
.Replace("[BORDER]",border.Value));
return Layout.Vertical()
| H3("CSS Block Generator")
| (Layout.Horizontal()
| Text.InlineCode("color")
.Width(35)
| color.ToColorInput()
.Variant(ColorInputs.Picker))
| (Layout.Horizontal()
| Text.InlineCode("background-color")
.Width(35)
| bgColor.ToColorInput()
.Variant(ColorInputs.Picker))
| (Layout.Horizontal()
| Text.InlineCode("border")
.Width(35)
| border.ToColorInput()
.Variant(ColorInputs.Picker))
| new CodeBlock(genCode.Value)
.Language(Languages.Css)
.ShowCopyButton();
}
}
```