# Widgets
*Discover the fundamental [building blocks](./02_Views.md) of Ivy [applications](./15_Apps.md) - Widgets provide declarative UI components inspired by React's component mode.*
Widgets are the fundamental building blocks of the Ivy framework. They represent the smallest unit of UI and are used to construct [Views](./02_Views.md).
## Basic usage
Ivy provides a comprehensive set of widgets organized into several [categories](../../02_Widgets/_Index.md):
The most frequently used widgets for building user interfaces:
```csharp
Layout.Vertical().Gap(2)
| new Badge("Primary")
| new Badge("New")
| new Button("Primary Button")
| new Progress(75)
| new Card("Card Content")
```
### Widget Library
Ivy ships with a comprehensive set of strongly-typed widgets:
| Category | Examples |
|----------|----------|
| Common | [Button](../../02_Widgets/03_Common/01_Button.md), [Badge](../../02_Widgets/03_Common/02_Badge.md), [Progress](../../02_Widgets/03_Common/10_Progress.md), [Table](../../02_Widgets/03_Common/08_Table.md), [Card](../../02_Widgets/03_Common/04_Card.md), [Tooltip](../../02_Widgets/03_Common/03_Tooltip.md), [Expandable](../../02_Widgets/03_Common/06_Expandable.md), [Blades](../../02_Widgets/03_Common/12_Blades.md), [Details](../../02_Widgets/03_Common/05_Details.md), [DropDownMenu](../../02_Widgets/03_Common/11_DropDownMenu.md), [List](../../02_Widgets/03_Common/07_List.md)... |
| Inputs | [TextInput](../../02_Widgets/04_Inputs/02_TextInput.md), [NumberInput](../../02_Widgets/04_Inputs/03_NumberInput.md), [BoolInput](../../02_Widgets/04_Inputs/04_BoolInput.md), [DateTimeInput](../../02_Widgets/04_Inputs/07_DateTimeInput.md), [FileInput](../../02_Widgets/04_Inputs/10_FileInput.md), [Feedback](../../02_Widgets/04_Inputs/13_FeedbackInput.md), [DateRange](../../02_Widgets/04_Inputs/08_DateRangeInput.md), [Color](../../02_Widgets/04_Inputs/09_ColorInput.md), [CodeInput](../../02_Widgets/04_Inputs/11_CodeInput.md), [ReadOnly](../../02_Widgets/04_Inputs/14_ReadOnlyInput.md), [AsyncSelect](../../02_Widgets/04_Inputs/06_AsyncSelectInput.md)... |
| Primitives | [Text](../../02_Widgets/01_Primitives/01_TextBlock.md), [Icon](../../02_Widgets/01_Primitives/02_Icon.md), [Image](../../02_Widgets/01_Primitives/03_Image.md), [Markdown](../../02_Widgets/01_Primitives/14_Markdown.md), [Json](../../02_Widgets/01_Primitives/17_Json.md), [CodeBlock](../../02_Widgets/01_Primitives/10_CodeBlock.md), [Avatar](../../02_Widgets/01_Primitives/08_Avatar.md), [Box](../../02_Widgets/01_Primitives/04_Box.md), [Callout](../../02_Widgets/01_Primitives/12_Callout.md), [Error](../../02_Widgets/01_Primitives/13_Error.md), [Spacer](../../02_Widgets/01_Primitives/06_Spacer.md), [Separator](../../02_Widgets/01_Primitives/07_Separator.md), [Xml](../../02_Widgets/01_Primitives/16_Xml.md), [Html](../../02_Widgets/01_Primitives/15_Html.md)... |
| Layouts | [GridLayout](../../02_Widgets/02_Layouts/03_GridLayout.md), [TabsLayout](../../02_Widgets/02_Layouts/07_TabsLayout.md), [SidebarLayout](../../02_Widgets/02_Layouts/06_SidebarLayout.md), [FloatingPanel](../../02_Widgets/02_Layouts/09_FloatingPanel.md), [ResizablePanelGroup](../../02_Widgets/02_Layouts/08_ResizablePanelGroup.md), [Header](../../02_Widgets/02_Layouts/04_HeaderLayout.md), [Footer](../../02_Widgets/02_Layouts/05_FooterLayout.md), [Wrap](../../02_Widgets/02_Layouts/02_WrapLayout.md)... |
| Effects | [Animation](../../02_Widgets/05_Effects/Animation.md), [Confetti](../../02_Widgets/05_Effects/Confetti.md)... |
| Charts | [LineChart](../../02_Widgets/06_Charts/01_LineChart.md), [BarChart](../../02_Widgets/06_Charts/02_BarChart.md), [PieChart](../../02_Widgets/06_Charts/04_PieChart.md), [AreaChart](../../02_Widgets/06_Charts/03_AreaChart.md)... |
| Advanced | [Sheet](../../02_Widgets/07_Advanced/02_Sheet.md), [Chat](../../02_Widgets/07_Advanced/04_Chat.md)... |
### Common Widgets
The common widgets category offers you the opportunity to work with essential UI elements including [badges](../../02_Widgets/03_Common/02_Badge.md), [blades](../../02_Widgets/03_Common/12_Blades.md), [buttons](../../02_Widgets/03_Common/01_Button.md), [cards](../../02_Widgets/03_Common/04_Card.md), [details](../../02_Widgets/03_Common/05_Details.md) implementations, [dropdown menus](../../02_Widgets/03_Common/11_DropDownMenu.md), [expandable](../../02_Widgets/03_Common/06_Expandable.md) sections, [lists](../../02_Widgets/03_Common/07_List.md), [progress](../../02_Widgets/03_Common/10_Progress.md) bars, [tables](../../02_Widgets/03_Common/08_Table.md), and [tooltips](../../02_Widgets/03_Common/03_Tooltip.md). Each widget is designed with Ivy's signature approach to simplicity and functionality.
```mermaid
flowchart TB
A[Common Widgets] --> B[Badges, Blades, Buttons, Cards]
A --> C[Dropdown Menus, Expandables, Lists]
A --> D[Progress Bars, Tables, Tooltips]
A --> E[Details Implementations]
```
```csharp
public class CommonWidgetsDemo : ViewBase
{
public override object? Build()
{
var client = UseService<IClientProvider>();
return Layout.Grid().Columns(2).Gap(4)
| new Card(
Layout.Horizontal().Gap(2)
| new Button("Click Me", onClick: _ => client.Toast("Hello!"))
| new Button("Destructive").Destructive()
| new Button("Secondary").Secondary()
).Title("Buttons").Description("Interactive button variants").Height(Size.Units(40))
| new Card(
Layout.Wrap().Gap(2)
| new Badge("Primary")
| new Badge("Success").Icon(Icons.Check)
| new Badge("Outline").Outline()
).Title("Badges").Description("Status and label badges").Height(Size.Units(40))
| new Card(
Layout.Vertical().Gap(2)
| new Progress(50).Goal("Task completion")
| new Progress(75).ColorVariant(Progress.ColorVariants.EmeraldGradient)
| new Progress(90)
).Title("Progress").Description("Task completion indicators").Height(Size.Units(50))
| new Card(
Layout.Vertical().Gap(2)
| new Card("Clickable Card").HandleClick(_ => client.Toast("Clicked!"))
).Title("Cards").Description("Content containers").Height(Size.Units(50))
| new Card(
new[] {
new { Name = "Apple", Price = 1.20 },
new { Name = "Banana", Price = 0.80 },
new { Name = "Cherry", Price = 2.50 }
}.ToTable()
).Title("Table").Description("Structured data display").Height(Size.Units(70))
| new Card(
Layout.Vertical().Gap(2)
| new Expandable("Click to expand", "Hidden content appears here")
| new Expandable("Another section", "More expandable content")
).Title("Expandable").Description("Collapsible sections").Height(Size.Units(70))
| new Card(
new List(new[]
{
new ListItem("First item", icon: Icons.Circle),
new ListItem("Second item", icon: Icons.Circle),
new ListItem("Third item", icon: Icons.Circle)
})
).Title("List").Description("Vertical item lists").Height(Size.Units(70))
| new Card(
new { Name = "John Doe", Email = "john@example.com", Role = "Admin" }
.ToDetails()
).Title("Details").Description("Label-value pairs").Height(Size.Units(70))
| new Card(
Layout.Vertical().Align(Align.Center)
| new DropDownMenu(_ => { },
new Button("Menu"),
MenuItem.Default("Profile"),
MenuItem.Default("Settings"),
MenuItem.Separator(),
MenuItem.Default("Logout"))
).Title("DropDownMenu").Description("Action menus").Height(Size.Units(40))
| new Card(
Layout.Horizontal().Align(Align.Center).Gap(2)
| new Button("Hover", icon: Icons.Info).WithTooltip("This is a tooltip")
| new Button("Help", icon: Icons.CircleQuestionMark).WithTooltip("Get help here")
).Title("Tooltip").Description("Contextual information").Height(Size.Units(40));
}
}
```
### Input Widgets
We also provide our users with various input methods to capture user data. Users can work with simple input types such as [boolean inputs](../../02_Widgets/04_Inputs/04_BoolInput.md), [feedback](../../02_Widgets/04_Inputs/13_FeedbackInput.md) forms, [text inputs](../../02_Widgets/04_Inputs/02_TextInput.md), [number inputs](../../02_Widgets/04_Inputs/03_NumberInput.md), [date ranges](../../02_Widgets/04_Inputs/08_DateRangeInput.md), and [date-time pickers](../../02_Widgets/04_Inputs/07_DateTimeInput.md). Additionally, we offer specialized features including Ivy's [color](../../02_Widgets/04_Inputs/09_ColorInput.md) palette system and our implementation of [code](../../02_Widgets/04_Inputs/11_CodeInput.md) highlighting. We introduce our [file input](../../02_Widgets/04_Inputs/10_FileInput.md) implementations, [read-only](../../02_Widgets/04_Inputs/14_ReadOnlyInput.md) statements, and provide the ability to work with complex structures like [async select](../../02_Widgets/04_Inputs/06_AsyncSelectInput.md) operations in a simple, intuitive way.
```mermaid
graph BT
A[Input Methods] --> B[Boolean, Feedback, Text, Number, Date, DateRange]
A --> C[Color Palette, Code Highlighting, File Inputs, Read-Only]
A --> D[Async Select, Complex Structures]
```
```csharp
public class InputWidgetsDemo : ViewBase
{
private static readonly string[] Categories = { "Electronics", "Clothing", "Books", "Home & Garden", "Sports" };
public override object? Build()
{
var textState = UseState("");
var numberState = UseState(0);
var boolState = UseState(false);
var dateState = UseState(DateTime.Now);
var dateRangeState = UseState<(DateOnly?, DateOnly?)>((null, null));
var colorState = UseState("#00cc92");
var codeState = UseState("var x = 10;");
var fileState = UseState<FileUpload<byte[]>?>();
var fileUpload = UseUpload(MemoryStreamUploadHandler.Create(fileState));
var feedbackState = UseState(4);
var selectState = UseState("");
var asyncSelectState = UseState((string?)null);
var selectedCategory = UseState<string?>(default(string?));
QueryResult<Option<string>[]> QueryCategories(IViewContext context, string query)
{
return context.UseQuery<Option<string>[], (string, string)>(
key: (nameof(QueryCategories), query),
fetcher: ct => Task.FromResult(Categories
.Where(c => c.Contains(query, StringComparison.OrdinalIgnoreCase))
.Select(c => new Option<string>(c))
.ToArray()));
}
QueryResult<Option<string>?> LookupCategory(IViewContext context, string? category)
{
return context.UseQuery<Option<string>?, (string, string?)>(
key: (nameof(LookupCategory), category),
fetcher: ct => Task.FromResult(category != null ? new Option<string>(category) : null));
}
return Layout.Grid().Columns(2).Gap(4).Width(Size.Full())
| new Card(
Layout.Vertical().Gap(2)
| new TextInput(textState).Placeholder("Enter text...")
| new TextInput(textState).Variant(TextInputs.Password).Placeholder("Password")
| new TextInput(textState).Variant(TextInputs.Email).Placeholder("Email")
| new TextInput(textState).Variant(TextInputs.Search).Placeholder("Search...")
).Title("TextInput").Description("Text input variants").Height(Size.Units(80))
| new Card(
Layout.Vertical().Gap(2)
| new NumberInput<double>(numberState).Min(0).Max(100).Variant(NumberInputs.Slider)
| new NumberInput<int>(numberState).Placeholder("Enter number")
| new NumberInput<decimal>(numberState).FormatStyle(NumberFormatStyle.Currency).Currency("USD").Placeholder("$0.00")
| new NumberInput<double>(numberState).FormatStyle(NumberFormatStyle.Percent).Placeholder("0%")
).Title("NumberInput").Description("Number and slider").Height(Size.Units(80))
| new Card(
Layout.Vertical().Gap(2)
| new BoolInput(boolState).Label("Accept terms and conditions")
| boolState.ToSwitchInput().Label("Enable notifications")
).Title("BoolInput").Description("Checkbox input").Height(Size.Units(65))
| new Card(
Layout.Vertical().Gap(2)
| fileState.ToFileInput(fileUpload).Placeholder("Upload file")
).Title("FileInput").Description("File upload").Height(Size.Units(65))
| new Card(
dateRangeState.ToDateRangeInput().Placeholder("Select date range")
).Title("DateRange").Description("Date range picker").Height(Size.Units(40))
| new Card(
new DateTimeInput<DateTime>(dateState).Placeholder("Select date")
).Title("DateTimeInput").Description("Date and time picker").Height(Size.Units(40))
| new Card(
new FeedbackInput<int>(feedbackState).Variant(FeedbackInputs.Stars)
).Title("Feedback").Description("Star rating").Height(Size.Units(40))
| new Card(
colorState.ToColorInput().Variant(ColorInputs.Picker)
).Title("Color").Description("Color picker").Height(Size.Units(40))
| new Card(
codeState.ToCodeInput().Language(Languages.Javascript).Height(Size.Units(15))
).Title("Code").Description("Code editor").Height(Size.Units(50))
| new Card(
selectState.ToSelectInput(new[] { "Option 1", "Option 2", "Option 3" }.ToOptions()).Placeholder("Select option")
).Title("Select").Description("Dropdown select").Height(Size.Units(50))
| new Card(
new ReadOnlyInput<string>("Read-only value")
).Title("ReadOnly").Description("Read-only display").Height(Size.Units(40))
| new Card(
selectedCategory.ToAsyncSelectInput(QueryCategories, LookupCategory, "Search categories...")
).Title("AsyncSelect").Description("Async dropdown").Height(Size.Units(40));
}
}
```
### Primitives
Ivy also provides a special experience when working with [primitive](../../02_Widgets/01_Primitives/_Index.md) widgets. We make complex tasks simpler through our implementation of [boxes](../../02_Widgets/01_Primitives/04_Box.md), [callouts](../../02_Widgets/01_Primitives/12_Callout.md), [error](../../02_Widgets/01_Primitives/13_Error.md) displays, and [text blocks](../../02_Widgets/01_Primitives/01_TextBlock.md). You can easily add [avatars](../../02_Widgets/01_Primitives/08_Avatar.md), [icons](../../02_Widgets/01_Primitives/02_Icon.md), [images](../../02_Widgets/01_Primitives/03_Image.md), [spacers](../../02_Widgets/01_Primitives/06_Spacer.md), and [separators](../../02_Widgets/01_Primitives/07_Separator.md) to enhance your interfaces. We also provide our own implementations of [JSON](../../02_Widgets/01_Primitives/17_Json.md), [XML](../../02_Widgets/01_Primitives/16_Xml.md), [HTML](../../02_Widgets/01_Primitives/15_Html.md), and [code](../../02_Widgets/01_Primitives/10_CodeBlock.md) rendering capabilities.
```mermaid
flowchart LR
A[Primitive Widgets] --> B[Boxes, Callouts, Errors, Text Blocks]
A --> C[Avatars, Icons, Images, Spacers, Separators]
A --> D[JSON, XML, HTML, Code Rendering]
```
```csharp
public class PrimitiveWidgetsDemo : ViewBase
{
public override object? Build()
{
return Layout.Grid().Columns(2).Gap(4).Width(Size.Full())
| new Card(
Layout.Vertical().Gap(2)
| Text.H3("Heading 3")
| Text.P("Paragraph text")
| Text.Label("Label text")
| Text.P("Large text").Large()
| Text.Lead("Lead text")
).Title("Text").Description("Text variants").Height(Size.Units(75))
| new Card(
Layout.Vertical().Align(Align.Center)
| new Image("https://api.images.cat/150/150")
).Title("Image").Description("Image display").Height(Size.Units(75))
| new Card(
Layout.Horizontal().Gap(4)
| new Icon(Icons.Heart, Colors.Red)
| new Icon(Icons.Star, Colors.Yellow)
| new Icon(Icons.Check, Colors.Green)
| new Icon(Icons.Settings, Colors.Blue)
| new Icon(Icons.Bell, Colors.Orange)
| new Icon(Icons.Mail, Colors.Purple)
| new Icon(Icons.User, Colors.Cyan)
).Title("Icon").Description("Vector icons").Height(Size.Units(40))
| new Card(
Layout.Horizontal().Gap(2)
| new Avatar("John Doe")
| new Avatar("JD", "https://api.images.cat/150/150?1")
| new Avatar("AB")
| new Avatar("Mary Smith")
| new Avatar("TC", "https://api.images.cat/150/150?2")
| new Avatar("XY")
).Title("Avatar").Description("User avatars").Height(Size.Units(40))
| new Card(
Layout.Vertical().Gap(2)
| Callout.Info("Info message")
| Callout.Warning("Warning message")
).Title("Callout").Description("Alert messages").Height(Size.Units(70))
| new Card(
Layout.Vertical().Gap(2)
| new Box("Solid border").BorderStyle(BorderStyle.Solid)
| new Box("Full radius").BorderRadius(BorderRadius.Full)
).Title("Box").Description("Content container").Height(Size.Units(70))
| new Card(
Layout.Vertical().Gap(2)
| Text.P("Content above")
| new Separator()
| Text.P("Content below")
).Title("Separator").Description("Visual divider").Height(Size.Units(50))
| new Card(
Layout.Vertical()
| Text.P("Top content")
| new Spacer().Height(Size.Units(4))
| Text.P("Bottom content")
).Title("Spacer").Description("Empty space").Height(Size.Units(50))
| new Card(
Text.Code("var x = 10;\nconsole.log(x);", Languages.Javascript)
).Title("Code").Description("Syntax highlighting").Height(Size.Units(60))
| new Card(
new Markdown("**Bold** and *italic* text\n\n- Item 1\n- Item 2")
).Title("Markdown").Description("Markdown rendering").Height(Size.Units(60))
| new Card(
Text.Json("{ \"name\": \"value\", \"count\": 42 }")
).Title("Json").Description("JSON display").Height(Size.Units(50))
| new Card(
Text.Xml("<root><item>Value</item></root>")
).Title("Xml").Description("XML display").Height(Size.Units(50))
| new Card(
Text.Html("<div><strong>Bold</strong> text and <em>italic</em> text</div>")
).Title("Html").Description("HTML rendering").Height(Size.Units(40))
| new Card(
new Error("An error occurred")
).Title("Error").Description("Error display").Height(Size.Units(40));
}
}
```
### Layouts
Ivy makes working with layouts not just easier, but satisfying. We provide a much more intuitive way to work with layouts and their elements, allowing you to create complex arrangements with minimal effort.
```mermaid
graph LR
A[Layout Widgets] --> B[Basic Layouts]
A --> C[Panel Layouts]
A --> D[Section Layouts]
A --> E[Special Layouts]
B --> B1[Grid]
B --> B2[Horizontal]
B --> B3[Vertical]
C --> C1[Floating Panel]
C --> C2[Resizable Panel Group]
C --> C3[Sidebar]
C --> C4[Tabs]
D --> D1[Header]
D --> D2[Footer]
E --> E1[Wrap]
```
```csharp
public class LayoutWidgetsDemo : ViewBase
{
public override object? Build()
{
var showPanel = UseState(false);
var singleColumnExamples = Layout.Vertical().Gap(4).Width(Size.Full())
| new Card(
Layout.Grid().Columns(2).Width(Size.Full()).Gap(2)
| new Box("1").Width(Size.Full())
| new Box("2").Width(Size.Full())
| new Box("3").Width(Size.Full())
| new Box("4").Width(Size.Full())
).Title("GridLayout").Description("2D grid arrangement").Height(Size.Units(50))
| new Card(
new HeaderLayout(
header: new Card("Fixed Header Area").Title("Header"),
content: Layout.Vertical().Gap(2)
| Text.P("More scrollable content")
)
).Title("Header").Description("Fixed header").Height(Size.Units(60))
| new Card(
new FooterLayout(
footer: Layout.Horizontal().Gap(2)
| new Button("Cancel").Secondary()
| new Button("Save"),
content: Layout.Vertical().Gap(2)
| Text.P("Footer stays at bottom")
)
).Title("Footer").Description("Fixed footer").Height(Size.Units(60));
var twoColumnExamples = Layout.Grid().Columns(2).Gap(4).Width(Size.Full())
| new Card(
Layout.Horizontal().Gap(2)
| new Box("Item 1").Width(Size.Fraction(1/3f))
| new Box("Item 2").Width(Size.Fraction(1/3f))
| new Box("Item 3").Width(Size.Fraction(1/3f))
).Title("Horizontal").Description("Horizontal flow").Height(Size.Units(50))
| new Card(
Layout.Vertical().Gap(2)
| new Box("Item 1").Width(Size.Full())
| new Box("Item 2").Width(Size.Full())
).Title("Vertical").Description("Vertical stack").Height(Size.Units(50))
| new Card(
Layout.Wrap().Gap(2)
| new Badge("Item 1")
| new Badge("Item 2")
| new Badge("Item 3")
| new Badge("Item 4")
| new Badge("Item 5")
| new Badge("Item 6")
| new Badge("Item 7")
).Title("Wrap").Description("Auto-wrapping layout").Height(Size.Units(50))
| new Card(
Layout.Tabs(
new Tab("Tab 1", new Badge("Content 1")),
new Tab("Tab 2", new Badge("Content 2")),
new Tab("Tab 3", new Badge("Content 3"))
)
).Title("TabsLayout").Description("Tabbed interface").Height(Size.Units(50))
| new Card(
Layout.Vertical().Gap(4)
| new Card(
Layout.Horizontal().Gap(2).Align(Align.Center)
| new Button("Show Panel", onClick: _ => showPanel.Set(true))
| new Button("Hide Panel", onClick: _ => showPanel.Set(false))
).Width(Size.Full())
| (showPanel.Value ? new FloatingPanel(
new Button("Floating Action")
.Icon(Icons.Plus)
.Large()
.BorderRadius(BorderRadius.Full)
) : null)
).Title("FloatingPanel").Description("Fixed position overlay").Height(Size.Units(60))
| new Card(
new ResizablePanelGroup(
new ResizablePanel(Size.Fraction(0.4f),
new Card("Left")),
new ResizablePanel(Size.Fraction(0.6f),
new Card("Right"))
)
).Title("ResizablePanelGroup").Description("Resizable panels").Height(Size.Units(60));
return Layout.Vertical().Gap(4)
| twoColumnExamples
| singleColumnExamples;
}
}
```
### Charts
Additionally, Ivy has its own implementation of charts, which makes data visualization much simpler to work with.
```mermaid
flowchart TB
A[Chart Widgets] --> B[Area Chart]
A --> C[Bar Chart]
A --> D[Line Chart]
A --> E[Pie Chart]
```
```csharp
public class ChartWidgetsDemo : ViewBase
{
public override object? Build()
{
var data = new[]
{
new { Month = "Jan", Desktop = 186, Mobile = 100 },
new { Month = "Feb", Desktop = 305, Mobile = 200 },
new { Month = "Mar", Desktop = 237, Mobile = 300 },
new { Month = "Apr", Desktop = 186, Mobile = 100 }
};
return Layout.Grid().Columns(2).Gap(4).Width(Size.Full())
| new Card(
data.ToLineChart()
.Dimension("Month", e => e.Month)
.Measure("Desktop", e => e.Sum(f => f.Desktop))
.Measure("Mobile", e => e.Sum(f => f.Mobile))
).Title("LineChart").Description("Trend visualization").Height(Size.Units(100))
| new Card(
data.ToBarChart()
.Dimension("Month", e => e.Month)
.Measure("Desktop", e => e.Sum(f => f.Desktop))
).Title("BarChart").Description("Bar comparison").Height(Size.Units(100))
| new Card(
data.ToAreaChart()
.Dimension("Month", e => e.Month)
.Measure("Desktop", e => e.Sum(f => f.Desktop))
).Title("AreaChart").Description("Area under curve").Height(Size.Units(120))
| new Card(
data.ToPieChart(
e => e.Month,
e => e.Sum(f => f.Desktop))
).Title("PieChart").Description("Part-to-whole").Height(Size.Units(120));
}
}
```
### Effects
Ivy provides a rich collection of built-in effects and animations to enhance your user interfaces. Working with effects in Ivy is incredibly simple and intuitive. For detailed information about specific effects, refer to the [animation](../../03_Hooks/02_Core/04_UseEffect.md) and [confetti](../../03_Hooks/02_Core/04_UseEffect.md) documentation pages.
```csharp ivy-bg
public class EffectWidgetsDemo : ViewBase
{
public override object? Build()
{
return Layout.Grid().Columns(2).Gap(4).Width(Size.Full())
| new Card(
Layout.Horizontal().Align(Align.Center).Gap(2)
| new Button("Click Confetti").WithConfetti(AnimationTrigger.Click)
| new Button("Hover Confetti").WithConfetti(AnimationTrigger.Hover)
).Title("Confetti").Description("Celebration effects").Height(Size.Units(40))
| new Card(
Layout.Horizontal().Gap(4)
| Icons.Heart.ToIcon().Color(Colors.Red).WithAnimation(AnimationType.Pulse).Trigger(AnimationTrigger.Click)
| Icons.Bell.ToIcon().Color(Colors.Orange).WithAnimation(AnimationType.Shake).Trigger(AnimationTrigger.Click)
| Icons.Star.ToIcon().Color(Colors.Yellow).WithAnimation(AnimationType.Bounce).Trigger(AnimationTrigger.Click)
| Icons.LoaderCircle.ToIcon().Color(Colors.Blue).WithAnimation(AnimationType.Rotate).Trigger(AnimationTrigger.Click)
| Icons.Zap.ToIcon().Color(Colors.Purple).WithAnimation(AnimationType.Pulse).Trigger(AnimationTrigger.Click)
| Icons.TrendingUp.ToIcon().Color(Colors.Green).WithAnimation(AnimationType.Bounce).Trigger(AnimationTrigger.Click)
| Icons.Sparkles.ToIcon().Color(Colors.Pink).WithAnimation(AnimationType.Rotate).Trigger(AnimationTrigger.Click)
| Icons.CircleAlert.ToIcon().Color(Colors.Destructive).WithAnimation(AnimationType.Shake).Trigger(AnimationTrigger.Click)
).Title("Animation").Description("Click icons to animate").Height(Size.Units(40));
}
}
```
### Advanced
In the Advanced section, we introduce our specialized implementations for working with [sheets](../../02_Widgets/07_Advanced/02_Sheet.md) and [chat functionality](../../02_Widgets/07_Advanced/04_Chat.md). These advanced widgets provide sophisticated features for complex user interface requirements.
```csharp
public class AdvancedWidgetsDemo : ViewBase
{
public override object? Build()
{
var messages = UseState(ImmutableArray.Create<ChatMessage>(
new ChatMessage(ChatSender.Assistant, "Hello! I'm a demo chat bot.")
));
void OnSend(Event<Chat, string> @event)
{
var currentMessages = messages.Value;
messages.Set(currentMessages.Add(new ChatMessage(ChatSender.User, @event.Value)));
messages.Set(currentMessages.Add(new ChatMessage(ChatSender.Assistant, $"You said: {@event.Value}")));
}
return Layout.Vertical().Gap(4).Width(Size.Full())
| new Card(
new Button("Open Sheet").WithSheet(
() => Layout.Vertical()
| Text.H3("Sheet Content")
| Text.P("This is content inside a sheet")
| new Button("Close"),
title: "Demo Sheet",
description: "Sheet demonstration"
)
).Title("Sheet").Description("Side panel overlay").Height(Size.Units(40))
| new Card(
new Chat(messages.Value.ToArray(), OnSend)
.Height(Size.Units(30))
).Title("Chat").Description("Conversation interface").Height(Size.Units(70));
}
}
```